From a329e323e069bf863753625d042d3d809f69e12a Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 23 Oct 2020 11:28:54 +0200 Subject: [PATCH 1/8] More extensible multiaddress format --- frame/indices/src/address.rs | 159 ------------------------- frame/indices/src/lib.rs | 15 ++- primitives/runtime/src/lib.rs | 4 + primitives/runtime/src/multiaddress.rs | 69 +++++++++++ 4 files changed, 80 insertions(+), 167 deletions(-) delete mode 100644 frame/indices/src/address.rs create mode 100644 primitives/runtime/src/multiaddress.rs diff --git a/frame/indices/src/address.rs b/frame/indices/src/address.rs deleted file mode 100644 index 0fd8933381328..0000000000000 --- a/frame/indices/src/address.rs +++ /dev/null @@ -1,159 +0,0 @@ -// This file is part of Substrate. - -// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. -// SPDX-License-Identifier: Apache-2.0 - -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//! Address type that is union of index and id for an account. - -#[cfg(feature = "std")] -use std::fmt; -use sp_std::convert::TryInto; -use crate::Member; -use codec::{Encode, Decode, Input, Output, Error}; - -/// An indices-aware address, which can be either a direct `AccountId` or -/// an index. -#[derive(PartialEq, Eq, Clone, sp_runtime::RuntimeDebug)] -#[cfg_attr(feature = "std", derive(Hash))] -pub enum Address where - AccountId: Member, - AccountIndex: Member, -{ - /// It's an account ID (pubkey). - Id(AccountId), - /// It's an account index. - Index(AccountIndex), -} - -#[cfg(feature = "std")] -impl fmt::Display for Address where - AccountId: Member, - AccountIndex: Member, -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:?}", self) - } -} - -impl From for Address where - AccountId: Member, - AccountIndex: Member, -{ - fn from(a: AccountId) -> Self { - Address::Id(a) - } -} - -fn need_more_than(a: T, b: T) -> Result { - if a < b { Ok(b) } else { Err("Invalid range".into()) } -} - -impl Decode for Address where - AccountId: Member + Decode, - AccountIndex: Member + Decode + PartialOrd + Ord + From + Copy, -{ - fn decode(input: &mut I) -> Result { - Ok(match input.read_byte()? { - x @ 0x00..=0xef => Address::Index(AccountIndex::from(x as u32)), - 0xfc => Address::Index(AccountIndex::from( - need_more_than(0xef, u16::decode(input)?)? as u32 - )), - 0xfd => Address::Index(AccountIndex::from( - need_more_than(0xffff, u32::decode(input)?)? - )), - 0xfe => Address::Index( - need_more_than(0xffffffffu32.into(), Decode::decode(input)?)? - ), - 0xff => Address::Id(Decode::decode(input)?), - _ => return Err("Invalid address variant".into()), - }) - } -} - -impl Encode for Address where - AccountId: Member + Encode, - AccountIndex: Member + Encode + PartialOrd + Ord + Copy + From + TryInto, -{ - fn encode_to(&self, dest: &mut T) { - match *self { - Address::Id(ref i) => { - dest.push_byte(255); - dest.push(i); - } - Address::Index(i) => { - let maybe_u32: Result = i.try_into(); - if let Ok(x) = maybe_u32 { - if x > 0xffff { - dest.push_byte(253); - dest.push(&x); - } - else if x >= 0xf0 { - dest.push_byte(252); - dest.push(&(x as u16)); - } - else { - dest.push_byte(x as u8); - } - - } else { - dest.push_byte(254); - dest.push(&i); - } - }, - } - } -} - -impl codec::EncodeLike for Address where - AccountId: Member + Encode, - AccountIndex: Member + Encode + PartialOrd + Ord + Copy + From + TryInto, -{} - -impl Default for Address where - AccountId: Member + Default, - AccountIndex: Member, -{ - fn default() -> Self { - Address::Id(Default::default()) - } -} - -#[cfg(test)] -mod tests { - use codec::{Encode, Decode}; - - type Address = super::Address<[u8; 8], u32>; - fn index(i: u32) -> Address { super::Address::Index(i) } - fn id(i: [u8; 8]) -> Address { super::Address::Id(i) } - - fn compare(a: Option
, d: &[u8]) { - if let Some(ref a) = a { - assert_eq!(d, &a.encode()[..]); - } - assert_eq!(Address::decode(&mut &d[..]).ok(), a); - } - - #[test] - fn it_should_work() { - compare(Some(index(2)), &[2][..]); - compare(None, &[240][..]); - compare(None, &[252, 239, 0][..]); - compare(Some(index(240)), &[252, 240, 0][..]); - compare(Some(index(304)), &[252, 48, 1][..]); - compare(None, &[253, 255, 255, 0, 0][..]); - compare(Some(index(0x10000)), &[253, 0, 0, 1, 0][..]); - compare(Some(id([42, 69, 42, 69, 42, 69, 42, 69])), &[255, 42, 69, 42, 69, 42, 69, 42, 69][..]); - } -} diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index edbaed17e536f..d931280e11776 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -22,6 +22,7 @@ use sp_std::prelude::*; use codec::Codec; +use sp_runtime::MultiAddress; use sp_runtime::traits::{ StaticLookup, Member, LookupError, Zero, Saturating, AtLeast32Bit }; @@ -30,15 +31,12 @@ use frame_support::dispatch::DispatchResult; use frame_support::traits::{Currency, ReservableCurrency, Get, BalanceStatus::Reserved}; use frame_support::weights::Weight; use frame_system::{ensure_signed, ensure_root}; -use self::address::Address as RawAddress; mod mock; -pub mod address; mod tests; mod benchmarking; mod default_weights; -pub type Address = RawAddress<::AccountId, ::AccountIndex>; type BalanceOf = <::Currency as Currency<::AccountId>>::Balance; pub trait WeightInfo { @@ -295,17 +293,18 @@ impl Module { /// Lookup an address to get an Id, if there's one there. pub fn lookup_address( - a: address::Address + a: MultiAddress ) -> Option { match a { - address::Address::Id(i) => Some(i), - address::Address::Index(i) => Self::lookup_index(i), + MultiAddress::Id(i) => Some(i), + MultiAddress::Index(i) => Self::lookup_index(i), + _ => None, } } } impl StaticLookup for Module { - type Source = address::Address; + type Source = MultiAddress; type Target = T::AccountId; fn lookup(a: Self::Source) -> Result { @@ -313,6 +312,6 @@ impl StaticLookup for Module { } fn unlookup(a: Self::Target) -> Self::Source { - address::Address::Id(a) + MultiAddress::Id(a) } } diff --git a/primitives/runtime/src/lib.rs b/primitives/runtime/src/lib.rs index 47081e9115c3a..7355edb3264b4 100644 --- a/primitives/runtime/src/lib.rs +++ b/primitives/runtime/src/lib.rs @@ -56,9 +56,13 @@ pub mod traits; pub mod transaction_validity; pub mod random_number_generator; mod runtime_string; +mod multiaddress; pub use crate::runtime_string::*; +// Re-export Multiaddress +pub use multiaddress::MultiAddress; + /// Re-export these since they're only "kind of" generic. pub use generic::{DigestItem, Digest}; diff --git a/primitives/runtime/src/multiaddress.rs b/primitives/runtime/src/multiaddress.rs new file mode 100644 index 0000000000000..e084f6abd59ea --- /dev/null +++ b/primitives/runtime/src/multiaddress.rs @@ -0,0 +1,69 @@ +// This file is part of Substrate. + +// Copyright (C) 2017-2020 Parity Technologies (UK) Ltd. +// SPDX-License-Identifier: Apache-2.0 + +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! MultiAddress type is a wrapper for multiple downstream account formats. + +use crate::traits::Member; +use codec::{Encode, Decode}; +use sp_std::vec::Vec; + +/// A multi-format address wrapper for on-chain accounts. +#[derive(Encode, Decode, PartialEq, Eq, Clone, crate::RuntimeDebug)] +#[cfg_attr(feature = "std", derive(Hash))] +pub enum MultiAddress where + AccountId: Member, + AccountIndex: Member, +{ + /// It's an account ID (pubkey). + Id(AccountId), + /// It's an account index. + Index(#[codec(compact)] AccountIndex), + /// It's some arbitrary raw bytes. + Raw(Vec), + /// It's a 32 byte representation. + Account32([u8; 32]), + /// Its a 20 byte representation. + Account20([u8; 20]), +} + +#[cfg(feature = "std")] +impl std::fmt::Display for MultiAddress where + AccountId: Member, + AccountIndex: Member, +{ + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!(f, "{:?}", self) + } +} + +impl From for MultiAddress where + AccountId: Member, + AccountIndex: Member, +{ + fn from(a: AccountId) -> Self { + MultiAddress::Id(a) + } +} + +impl Default for MultiAddress where + AccountId: Member + Default, + AccountIndex: Member, +{ + fn default() -> Self { + MultiAddress::Id(Default::default()) + } +} From b81b08dd34237d20d8574f1bf2bf50bf8bef7c68 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 23 Oct 2020 11:37:43 +0200 Subject: [PATCH 2/8] update name --- primitives/runtime/src/multiaddress.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/primitives/runtime/src/multiaddress.rs b/primitives/runtime/src/multiaddress.rs index e084f6abd59ea..c6747486069b3 100644 --- a/primitives/runtime/src/multiaddress.rs +++ b/primitives/runtime/src/multiaddress.rs @@ -35,9 +35,9 @@ pub enum MultiAddress where /// It's some arbitrary raw bytes. Raw(Vec), /// It's a 32 byte representation. - Account32([u8; 32]), + Address32([u8; 32]), /// Its a 20 byte representation. - Account20([u8; 20]), + Address20([u8; 20]), } #[cfg(feature = "std")] From 7009e911920f68df6a65209e54b1bded3616f8ba Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 23 Oct 2020 11:42:18 +0200 Subject: [PATCH 3/8] Don't depend on indices to define multiaddress type --- bin/node/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index dfa7a4680abe8..8e20e832fa814 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -936,7 +936,7 @@ construct_runtime!( ); /// The address format for describing accounts. -pub type Address = ::Source; +pub type Address = sp_runtime::MultiAddress; /// Block header type as expected by this runtime. pub type Header = generic::Header; /// Block type as expected by this runtime. From 36fdb7bca134982475bf7037c9bd67187ec25f6a Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 23 Oct 2020 14:12:14 +0200 Subject: [PATCH 4/8] Use MultiAddress in Node Template too! --- bin/node-template/runtime/src/lib.rs | 6 +++--- primitives/runtime/src/traits.rs | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index e96de63731745..c5cb3e3c69755 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -13,7 +13,7 @@ use sp_runtime::{ transaction_validity::{TransactionValidity, TransactionSource}, }; use sp_runtime::traits::{ - BlakeTwo256, Block as BlockT, IdentityLookup, Verify, IdentifyAccount, NumberFor, Saturating, + BlakeTwo256, Block as BlockT, AccountIdLookup, Verify, IdentifyAccount, NumberFor, Saturating, }; use sp_api::impl_runtime_apis; use sp_consensus_aura::sr25519::AuthorityId as AuraId; @@ -141,7 +141,7 @@ impl frame_system::Trait for Runtime { /// The aggregated dispatch type that is available for extrinsics. type Call = Call; /// The lookup mechanism to get account ID from whatever is passed in dispatchers. - type Lookup = IdentityLookup; + type Lookup = AccountIdLookup; /// The index type for storing how many extrinsics an account has signed. type Index = Index; /// The index type for blocks. @@ -287,7 +287,7 @@ construct_runtime!( ); /// The address format for describing accounts. -pub type Address = AccountId; +pub type Address = sp_runtime::MultiAddress; /// Block header type as expected by this runtime. pub type Header = generic::Header; /// Block type as expected by this runtime. diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 4d2b1f062f716..43d7060da08ad 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -209,6 +209,22 @@ impl Lookup for IdentityLookup { fn lookup(&self, x: T) -> Result { Ok(x) } } +/// A lookup implementation returning the `AccountId` from a `MultiAddress`. +pub struct AccountIdLookup(PhantomData); +impl StaticLookup for AccountIdLookup { + type Source = crate::MultiAddress; + type Target = AccountId; + fn lookup(x: Self::Source) -> Result { + match x { + crate::MultiAddress::Id(i) => Ok(i), + _ => Err(LookupError), + } + } + fn unlookup(x: Self::Target) -> Self::Source { + crate::MultiAddress::Id(x) + } +} + /// Extensible conversion trait. Generic over both source and destination types. pub trait Convert { /// Make conversion. From 3fc64d127363a1c45a0d5466238806ec07849f75 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Fri, 23 Oct 2020 14:31:20 +0200 Subject: [PATCH 5/8] reduce traits, fix build --- bin/node/executor/tests/basic.rs | 2 +- bin/node/testing/src/bench.rs | 6 +++--- bin/node/testing/src/keyring.rs | 2 +- primitives/runtime/src/multiaddress.rs | 23 +++++++---------------- primitives/runtime/src/traits.rs | 2 +- 5 files changed, 13 insertions(+), 22 deletions(-) diff --git a/bin/node/executor/tests/basic.rs b/bin/node/executor/tests/basic.rs index 723e3a7e4ba62..a48efaea2d695 100644 --- a/bin/node/executor/tests/basic.rs +++ b/bin/node/executor/tests/basic.rs @@ -621,7 +621,7 @@ fn deploying_wasm_contract_should_work() { signed: Some((charlie(), signed_extra(2, 0))), function: Call::Contracts( pallet_contracts::Call::call::( - pallet_indices::address::Address::Id(addr.clone()), + sp_runtime::MultiAddress::Id(addr.clone()), 10, 500_000_000, vec![0x00, 0x01, 0x02, 0x03] diff --git a/bin/node/testing/src/bench.rs b/bin/node/testing/src/bench.rs index 153a52375c2a9..32e4bab9773a5 100644 --- a/bin/node/testing/src/bench.rs +++ b/bin/node/testing/src/bench.rs @@ -317,7 +317,7 @@ impl<'a> Iterator for BlockContentIterator<'a> { BlockType::RandomTransfersKeepAlive => { Call::Balances( BalancesCall::transfer_keep_alive( - pallet_indices::address::Address::Id(receiver), + sp_runtime::MultiAddress::Id(receiver), node_runtime::ExistentialDeposit::get() + 1, ) ) @@ -325,7 +325,7 @@ impl<'a> Iterator for BlockContentIterator<'a> { BlockType::RandomTransfersReaping => { Call::Balances( BalancesCall::transfer( - pallet_indices::address::Address::Id(receiver), + sp_runtime::MultiAddress::Id(receiver), // Transfer so that ending balance would be 1 less than existential deposit // so that we kill the sender account. 100*DOLLARS - (node_runtime::ExistentialDeposit::get() - 1), @@ -591,7 +591,7 @@ impl BenchKeyring { } }).into(); UncheckedExtrinsic { - signature: Some((pallet_indices::address::Address::Id(signed), signature, extra)), + signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)), function: payload.0, } } diff --git a/bin/node/testing/src/keyring.rs b/bin/node/testing/src/keyring.rs index 3413748563633..f0b8ff707294e 100644 --- a/bin/node/testing/src/keyring.rs +++ b/bin/node/testing/src/keyring.rs @@ -94,7 +94,7 @@ pub fn sign(xt: CheckedExtrinsic, spec_version: u32, tx_version: u32, genesis_ha } }).into(); UncheckedExtrinsic { - signature: Some((pallet_indices::address::Address::Id(signed), signature, extra)), + signature: Some((sp_runtime::MultiAddress::Id(signed), signature, extra)), function: payload.0, } } diff --git a/primitives/runtime/src/multiaddress.rs b/primitives/runtime/src/multiaddress.rs index c6747486069b3..ba4e862956a3f 100644 --- a/primitives/runtime/src/multiaddress.rs +++ b/primitives/runtime/src/multiaddress.rs @@ -17,17 +17,13 @@ //! MultiAddress type is a wrapper for multiple downstream account formats. -use crate::traits::Member; use codec::{Encode, Decode}; use sp_std::vec::Vec; /// A multi-format address wrapper for on-chain accounts. #[derive(Encode, Decode, PartialEq, Eq, Clone, crate::RuntimeDebug)] #[cfg_attr(feature = "std", derive(Hash))] -pub enum MultiAddress where - AccountId: Member, - AccountIndex: Member, -{ +pub enum MultiAddress { /// It's an account ID (pubkey). Id(AccountId), /// It's an account index. @@ -41,28 +37,23 @@ pub enum MultiAddress where } #[cfg(feature = "std")] -impl std::fmt::Display for MultiAddress where - AccountId: Member, - AccountIndex: Member, +impl std::fmt::Display for MultiAddress +where + AccountId: std::fmt::Debug, + AccountIndex: std::fmt::Debug, { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!(f, "{:?}", self) } } -impl From for MultiAddress where - AccountId: Member, - AccountIndex: Member, -{ +impl From for MultiAddress { fn from(a: AccountId) -> Self { MultiAddress::Id(a) } } -impl Default for MultiAddress where - AccountId: Member + Default, - AccountIndex: Member, -{ +impl Default for MultiAddress { fn default() -> Self { MultiAddress::Id(Default::default()) } diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 43d7060da08ad..23f027dde86f3 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -211,7 +211,7 @@ impl Lookup for IdentityLookup { /// A lookup implementation returning the `AccountId` from a `MultiAddress`. pub struct AccountIdLookup(PhantomData); -impl StaticLookup for AccountIdLookup { +impl StaticLookup for AccountIdLookup { type Source = crate::MultiAddress; type Target = AccountId; fn lookup(x: Self::Source) -> Result { From 535a512903fc44d4d3681281548d8b9c20154e34 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sat, 24 Oct 2020 10:28:24 +0200 Subject: [PATCH 6/8] support multiple `StaticLookup` --- primitives/runtime/src/traits.rs | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 23f027dde86f3..083ad0db17fe6 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -225,6 +225,23 @@ impl StaticLookup for AccountIdLoo } } +/// Perform a StaticLookup where there are multiple lookup sources of the same type. +impl StaticLookup for (A, B) +where + A: StaticLookup, + B: StaticLookup, +{ + type Source = A::Source; + type Target = A::Target; + + fn lookup(x: Self::Source) -> Result { + A::lookup(x.clone()).or_else(|_| B::lookup(x)) + } + fn unlookup(x: Self::Target) -> Self::Source { + A::unlookup(x) + } +} + /// Extensible conversion trait. Generic over both source and destination types. pub trait Convert { /// Make conversion. From 98bfef676454e19bd0cc918e38a609b4b19dea04 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Mon, 26 Oct 2020 15:07:27 +0100 Subject: [PATCH 7/8] bump tx version --- bin/node/runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/node/runtime/src/lib.rs b/bin/node/runtime/src/lib.rs index 8e20e832fa814..1b1634b24043e 100644 --- a/bin/node/runtime/src/lib.rs +++ b/bin/node/runtime/src/lib.rs @@ -115,7 +115,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { spec_version: 260, impl_version: 0, apis: RUNTIME_API_VERSIONS, - transaction_version: 1, + transaction_version: 2, }; /// Native version. From 0e5ffa3088e639615907d26593b9503326367dc4 Mon Sep 17 00:00:00 2001 From: Shawn Tabrizi Date: Sat, 31 Oct 2020 12:50:10 +0100 Subject: [PATCH 8/8] feedback --- bin/node-template/runtime/src/lib.rs | 2 +- frame/indices/src/lib.rs | 1 - primitives/runtime/src/multiaddress.rs | 8 +++++++- primitives/runtime/src/traits.rs | 11 ++++++++--- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/bin/node-template/runtime/src/lib.rs b/bin/node-template/runtime/src/lib.rs index b0f12da310f93..1e8a58d033bc6 100644 --- a/bin/node-template/runtime/src/lib.rs +++ b/bin/node-template/runtime/src/lib.rs @@ -142,7 +142,7 @@ impl frame_system::Trait for Runtime { /// The aggregated dispatch type that is available for extrinsics. type Call = Call; /// The lookup mechanism to get account ID from whatever is passed in dispatchers. - type Lookup = AccountIdLookup; + type Lookup = AccountIdLookup; /// The index type for storing how many extrinsics an account has signed. type Index = Index; /// The index type for blocks. diff --git a/frame/indices/src/lib.rs b/frame/indices/src/lib.rs index 54f93239cd0fa..d65c630977849 100644 --- a/frame/indices/src/lib.rs +++ b/frame/indices/src/lib.rs @@ -21,7 +21,6 @@ #![cfg_attr(not(feature = "std"), no_std)] mod mock; -pub mod address; mod tests; mod benchmarking; pub mod weights; diff --git a/primitives/runtime/src/multiaddress.rs b/primitives/runtime/src/multiaddress.rs index ba4e862956a3f..bb352f7eb5f8e 100644 --- a/primitives/runtime/src/multiaddress.rs +++ b/primitives/runtime/src/multiaddress.rs @@ -43,7 +43,13 @@ where AccountIndex: std::fmt::Debug, { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - write!(f, "{:?}", self) + use sp_core::hexdisplay::HexDisplay; + match self { + MultiAddress::Raw(inner) => write!(f, "MultiAddress::Raw({})", HexDisplay::from(inner)), + MultiAddress::Address32(inner) => write!(f, "MultiAddress::Address32({})", HexDisplay::from(inner)), + MultiAddress::Address20(inner) => write!(f, "MultiAddress::Address20({})", HexDisplay::from(inner)), + _ => write!(f, "{:?}", self), + } } } diff --git a/primitives/runtime/src/traits.rs b/primitives/runtime/src/traits.rs index 083ad0db17fe6..4ce9ac0afa9a3 100644 --- a/primitives/runtime/src/traits.rs +++ b/primitives/runtime/src/traits.rs @@ -210,9 +210,14 @@ impl Lookup for IdentityLookup { } /// A lookup implementation returning the `AccountId` from a `MultiAddress`. -pub struct AccountIdLookup(PhantomData); -impl StaticLookup for AccountIdLookup { - type Source = crate::MultiAddress; +pub struct AccountIdLookup(PhantomData<(AccountId, AccountIndex)>); +impl StaticLookup for AccountIdLookup +where + AccountId: Codec + Clone + PartialEq + Debug, + AccountIndex: Codec + Clone + PartialEq + Debug, + crate::MultiAddress: Codec, +{ + type Source = crate::MultiAddress; type Target = AccountId; fn lookup(x: Self::Source) -> Result { match x {