Allow sub accounts to be derived from an TypeId. (#3039)

* Allow sub accounts to be derived from an TypeId.

* Deduplicate

* Fix

* Rephrase.
This commit is contained in:
Gavin Wood
2019-07-09 18:01:08 +02:00
committed by GitHub
parent d7b6720663
commit 2c5a3b84db
+24 -7
View File
@@ -872,27 +872,44 @@ impl<'a> codec::Input for TrailingZeroInput<'a> {
/// This type can be converted into and possibly from an AccountId (which itself is generic).
pub trait AccountIdConversion<AccountId>: Sized {
/// Convert into an account ID. This is infallible.
fn into_account(&self) -> AccountId;
fn into_account(&self) -> AccountId { self.into_sub_account(&()) }
/// Try to convert an account ID into this type. Might not succeed.
fn try_from_account(a: &AccountId) -> Option<Self>;
fn try_from_account(a: &AccountId) -> Option<Self> {
Self::try_from_sub_account::<()>(a).map(|x| x.0)
}
/// Convert this value amalgamated with the a secondary "sub" value into an account ID. This is
/// infallible.
///
/// NOTE: The account IDs from this and from `into_account` are *not* guaranteed to be distinct
/// for any given value of `self`, nor are different invocations to this with different types
/// `T`. For example, the following will all encode to the same account ID value:
/// - `self.into_sub_account(0u32)`
/// - `self.into_sub_account(vec![0u8; 0])`
/// - `self.into_account()`
fn into_sub_account<S: Encode>(&self, sub: S) -> AccountId;
/// Try to convert an account ID into this type. Might not succeed.
fn try_from_sub_account<S: Decode>(x: &AccountId) -> Option<(Self, S)>;
}
/// Provide a simply 4 byte identifier for a type.
/// Provide a simple 4 byte identifier for a type.
pub trait TypeId {
/// Simple 4 byte identifier.
const TYPE_ID: [u8; 4];
}
/// Format is TYPE_ID ++ encode(parachain ID) ++ 00.... where 00... is indefinite trailing zeroes to fill AccountId.
/// Format is TYPE_ID ++ encode(parachain ID) ++ 00.... where 00... is indefinite trailing zeroes to
/// fill AccountId.
impl<T: Encode + Decode + Default, Id: Encode + Decode + TypeId> AccountIdConversion<T> for Id {
fn into_account(&self) -> T {
(Id::TYPE_ID, self).using_encoded(|b|
fn into_sub_account<S: Encode>(&self, sub: S) -> T {
(Id::TYPE_ID, self, sub).using_encoded(|b|
T::decode(&mut TrailingZeroInput(b))
).unwrap_or_default()
}
fn try_from_account(x: &T) -> Option<Self> {
fn try_from_sub_account<S: Decode>(x: &T) -> Option<(Self, S)> {
x.using_encoded(|d| {
if &d[0..4] != Id::TYPE_ID { return None }
let mut cursor = &d[4..];