mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-27 23:18:01 +00:00
Introduce UncheckedTransaction & test.
This commit is contained in:
@@ -26,4 +26,6 @@ macro_rules! impl_non_endians {
|
||||
}
|
||||
|
||||
impl_endians!(u16, u32, u64, usize, i16, i32, i64, isize);
|
||||
impl_non_endians!(u8, i8, [u8; 20], [u8; 32]);
|
||||
impl_non_endians!(u8, i8, [u8; 1], [u8; 2], [u8; 3], [u8; 4], [u8; 5], [u8; 6], [u8; 7], [u8; 8],
|
||||
[u8; 10], [u8; 12], [u8; 14], [u8; 16], [u8; 20], [u8; 24], [u8; 28], [u8; 32], [u8; 40],
|
||||
[u8; 48], [u8; 56], [u8; 64], [u8; 80], [u8; 96], [u8; 112], [u8; 128]);
|
||||
|
||||
@@ -11,11 +11,12 @@ pub use codec::{endiansensitive, streamreader, joiner, slicable, keyedvec};
|
||||
pub use support::{primitives, function, environment, storage};
|
||||
#[cfg(test)]
|
||||
pub use support::testing;
|
||||
#[allow(unused_imports)] // TODO: remove in due course
|
||||
|
||||
|
||||
#[allow(unused_imports)] // TODO: remove in due course
|
||||
use runtime_support::Vec;
|
||||
use slicable::Slicable;
|
||||
use primitives::{Block, Transaction};
|
||||
use primitives::{Block, UncheckedTransaction};
|
||||
|
||||
// TODO: add externals for:
|
||||
// - keccak256 (or some better hashing scheme)
|
||||
@@ -27,7 +28,7 @@ pub fn execute_block(input: Vec<u8>) -> Vec<u8> {
|
||||
}
|
||||
|
||||
pub fn execute_transaction(input: Vec<u8>) -> Vec<u8> {
|
||||
runtime::system::execute_transaction(&Transaction::from_slice(&input).unwrap())
|
||||
runtime::system::execute_transaction(&UncheckedTransaction::from_slice(&input).unwrap())
|
||||
}
|
||||
|
||||
impl_stubs!(execute_block, execute_transaction);
|
||||
|
||||
@@ -2,14 +2,13 @@ use runtime_support::Vec;
|
||||
use keyedvec::KeyedVec;
|
||||
use storage::Storage;
|
||||
use primitives::{AccountID, SessionKey, BlockNumber};
|
||||
use storage::storage_into;
|
||||
|
||||
pub fn set_authority(index: u32, authority: AccountID) {
|
||||
authority.store(&index.to_keyed_vec(b"con\0aut\0"));
|
||||
}
|
||||
|
||||
fn authority(index: u32) -> AccountID {
|
||||
storage_into(&index.to_keyed_vec(b"con\0aut\0"))
|
||||
Storage::into(&index.to_keyed_vec(b"con\0aut\0"))
|
||||
}
|
||||
|
||||
pub fn set_authority_count(count: u32) {
|
||||
@@ -18,7 +17,7 @@ pub fn set_authority_count(count: u32) {
|
||||
}
|
||||
|
||||
fn authority_count() -> u32 {
|
||||
storage_into(b"con\0aut\0len")
|
||||
Storage::into(b"con\0aut\0len")
|
||||
}
|
||||
|
||||
/// Get the current set of authorities. These are the session keys.
|
||||
@@ -49,7 +48,7 @@ pub fn set_validators(_new: &[AccountID]) {
|
||||
|
||||
/// The number of blocks in each session.
|
||||
pub fn session_length() -> BlockNumber {
|
||||
storage_into(b"con\0bps")
|
||||
Storage::into(b"con\0bps")
|
||||
}
|
||||
|
||||
/// Sets the session key of `_transactor` to `_session`. This doesn't take effect until the next
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use keyedvec::KeyedVec;
|
||||
use storage::{Storage, storage_into};
|
||||
use storage::Storage;
|
||||
use primitives::{BlockNumber, Balance, AccountID};
|
||||
use runtime::consensus;
|
||||
|
||||
@@ -10,7 +10,7 @@ pub fn era_length() -> BlockNumber {
|
||||
|
||||
/// The length of a staking era in sessions.
|
||||
pub fn sessions_per_era() -> BlockNumber {
|
||||
storage_into(b"sta\0spe")
|
||||
Storage::into(b"sta\0spe")
|
||||
}
|
||||
|
||||
/// The era has changed - enact new staking set.
|
||||
@@ -22,16 +22,16 @@ pub fn next_era() {
|
||||
|
||||
/// The balance of a given account.
|
||||
pub fn balance(who: &AccountID) -> Balance {
|
||||
storage_into(&who.to_keyed_vec(b"sta\0bal\0"))
|
||||
Storage::into(&who.to_keyed_vec(b"sta\0bal\0"))
|
||||
}
|
||||
|
||||
/// Transfer some unlocked staking balance to another staker.
|
||||
pub fn transfer_stake(transactor: &AccountID, dest: &AccountID, value: Balance) {
|
||||
let from_key = transactor.to_keyed_vec(b"sta\0bal\0");
|
||||
let from_balance: Balance = storage_into(&from_key);
|
||||
let from_balance: Balance = Storage::into(&from_key);
|
||||
assert!(from_balance >= value);
|
||||
let to_key = dest.to_keyed_vec(b"sta\0bal\0");
|
||||
let to_balance: Balance = storage_into(&to_key);
|
||||
let to_balance: Balance = Storage::into(&to_key);
|
||||
assert!(to_balance + value > to_balance); // no overflow
|
||||
(from_balance - value).store(&from_key);
|
||||
(to_balance + value).store(&to_key);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use primitives::{Block, BlockNumber, Hash, Transaction};
|
||||
use primitives::{Block, BlockNumber, Hash, UncheckedTransaction};
|
||||
use runtime_support::{Vec, swap};
|
||||
use environment::with_env;
|
||||
use runtime_support;
|
||||
@@ -53,7 +53,7 @@ fn final_checks(_block: &Block) {
|
||||
}
|
||||
|
||||
/// Execute a given transaction.
|
||||
pub fn execute_transaction(_tx: &Transaction) -> Vec<u8> {
|
||||
pub fn execute_transaction(_tx: &UncheckedTransaction) -> Vec<u8> {
|
||||
// TODO: decode data and ensure valid
|
||||
// TODO: ensure signature valid and recover id (use authentication::authenticate)
|
||||
// TODO: check nonce
|
||||
@@ -61,7 +61,7 @@ pub fn execute_transaction(_tx: &Transaction) -> Vec<u8> {
|
||||
// TODO: ensure target_function valid
|
||||
// TODO: decode parameters
|
||||
|
||||
_tx.function.dispatch(&_tx.signed, &_tx.input_data);
|
||||
_tx.transaction.function.dispatch(&_tx.transaction.signed, &_tx.transaction.input_data);
|
||||
|
||||
// TODO: encode any return
|
||||
Vec::new()
|
||||
@@ -78,7 +78,7 @@ mod tests {
|
||||
use function::Function;
|
||||
use std::collections::HashMap;
|
||||
use runtime_support::{NoError, with_externalities, Externalities};
|
||||
use primitives::{AccountID, Transaction};
|
||||
use primitives::{AccountID, UncheckedTransaction, Transaction};
|
||||
use runtime::{system, staking};
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@@ -114,11 +114,14 @@ mod tests {
|
||||
{ let mut r = b"sta\0bal\0".to_vec(); r.extend_from_slice(&one); r } => vec![111u8, 0, 0, 0, 0, 0, 0, 0]
|
||||
], };
|
||||
|
||||
let tx = Transaction {
|
||||
signed: one.clone(),
|
||||
function: Function::StakingTransferStake,
|
||||
input_data: vec![].join(&two).join(&69u64),
|
||||
nonce: 0,
|
||||
let tx = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 0,
|
||||
function: Function::StakingTransferStake,
|
||||
input_data: vec![].join(&two).join(&69u64),
|
||||
},
|
||||
signature: [1u8; 64],
|
||||
};
|
||||
|
||||
with_externalities(&mut t, || {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use primitives::Timestamp;
|
||||
use storage::Storage;
|
||||
|
||||
pub fn timestamp() -> Timestamp {
|
||||
unimplemented!()
|
||||
Storage::into(b"tim\0val")
|
||||
}
|
||||
|
||||
pub fn set_timestamp(_now: Timestamp) {
|
||||
unimplemented!()
|
||||
pub fn set_timestamp(now: Timestamp) {
|
||||
now.store(b"tim\0val")
|
||||
}
|
||||
|
||||
@@ -5,10 +5,13 @@ use slicable::{Slicable, NonTrivialSlicable};
|
||||
use function::Function;
|
||||
use runtime_support::size_of;
|
||||
|
||||
/// The hash of an ECDSA pub key which is used to identify an external transactor.
|
||||
#[cfg(test)]
|
||||
use std::fmt;
|
||||
|
||||
/// The Ed25519 pubkey that identifies an account.
|
||||
pub type AccountID = [u8; 32];
|
||||
/// The ECDSA pub key of an authority. This is what the external environment/consensus algorithm
|
||||
/// refers to as a "authority".
|
||||
/// The Ed25519 pub key of an session that belongs to an authority. This is used as what the
|
||||
/// external environment/consensus algorithm calls an "authority".
|
||||
pub type SessionKey = AccountID;
|
||||
pub type Balance = u64;
|
||||
pub type ChainID = u64;
|
||||
@@ -36,15 +39,9 @@ pub struct Header {
|
||||
#[cfg_attr(test, derive(PartialEq, Debug))]
|
||||
pub struct Transaction {
|
||||
pub signed: AccountID,
|
||||
pub nonce: TxOrder,
|
||||
pub function: Function,
|
||||
pub input_data: Vec<u8>,
|
||||
pub nonce: TxOrder,
|
||||
}
|
||||
|
||||
#[cfg_attr(test, derive(PartialEq, Debug))]
|
||||
pub struct Block {
|
||||
pub header: Header,
|
||||
pub transactions: Vec<Transaction>,
|
||||
}
|
||||
|
||||
impl Slicable for Transaction {
|
||||
@@ -52,8 +49,8 @@ impl Slicable for Transaction {
|
||||
let mut reader = StreamReader::new(value);
|
||||
Some(Transaction {
|
||||
signed: reader.read()?,
|
||||
function: Function::from_u8(reader.read()?)?,
|
||||
nonce: reader.read()?,
|
||||
function: Function::from_u8(reader.read()?)?,
|
||||
input_data: reader.read()?,
|
||||
})
|
||||
}
|
||||
@@ -65,13 +62,13 @@ impl Slicable for Transaction {
|
||||
fn to_vec(&self) -> Vec<u8> {
|
||||
Vec::new()
|
||||
.join(&self.signed)
|
||||
.join(&(self.function as u8))
|
||||
.join(&self.nonce)
|
||||
.join(&(self.function as u8))
|
||||
.join(&self.input_data)
|
||||
}
|
||||
|
||||
fn size_of(data: &[u8]) -> Option<usize> {
|
||||
let first_part = size_of::<AccountID>() + size_of::<u8>() + size_of::<TxOrder>();
|
||||
let first_part = size_of::<AccountID>() + size_of::<TxOrder>() + size_of::<u8>();
|
||||
let second_part = <Vec<u8>>::size_of(&data[first_part..])?;
|
||||
Some(first_part + second_part)
|
||||
}
|
||||
@@ -79,6 +76,59 @@ impl Slicable for Transaction {
|
||||
|
||||
impl NonTrivialSlicable for Transaction {}
|
||||
|
||||
pub struct UncheckedTransaction {
|
||||
pub transaction: Transaction,
|
||||
pub signature: [u8; 64],
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl PartialEq for UncheckedTransaction {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.signature.iter().eq(other.signature.iter()) && self.transaction == other.transaction
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl fmt::Debug for UncheckedTransaction {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "UncheckedTransaction({:?})", self.transaction)
|
||||
}
|
||||
}
|
||||
|
||||
impl Slicable for UncheckedTransaction {
|
||||
fn from_slice(value: &[u8]) -> Option<Self> {
|
||||
let mut reader = StreamReader::new(value);
|
||||
Some(UncheckedTransaction {
|
||||
signature: reader.read()?,
|
||||
transaction: reader.read()?,
|
||||
})
|
||||
}
|
||||
|
||||
fn set_as_slice<F: FnOnce(&mut[u8]) -> bool>(_fill_slice: F) -> Option<Self> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn to_vec(&self) -> Vec<u8> {
|
||||
Vec::new()
|
||||
.join(&self.signature)
|
||||
.join(&self.transaction)
|
||||
}
|
||||
|
||||
fn size_of(data: &[u8]) -> Option<usize> {
|
||||
let first_part = size_of::<[u8; 64]>();
|
||||
let second_part = <Transaction>::size_of(&data[first_part..])?;
|
||||
Some(first_part + second_part)
|
||||
}
|
||||
}
|
||||
|
||||
impl NonTrivialSlicable for UncheckedTransaction {}
|
||||
|
||||
#[cfg_attr(test, derive(PartialEq, Debug))]
|
||||
pub struct Block {
|
||||
pub header: Header,
|
||||
pub transactions: Vec<UncheckedTransaction>,
|
||||
}
|
||||
|
||||
impl<T: Slicable> NonTrivialSlicable for Vec<T> where Vec<T>: Slicable {}
|
||||
|
||||
impl<T: NonTrivialSlicable> Slicable for Vec<T> {
|
||||
@@ -181,15 +231,15 @@ mod tests {
|
||||
let two: AccountID = [2u8; 32];
|
||||
let tx = Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 69,
|
||||
function: Function::StakingTransferStake,
|
||||
input_data: Vec::new().join(&two).join(&69u64),
|
||||
nonce: 69,
|
||||
};
|
||||
let serialised = tx.to_vec();
|
||||
assert_eq!(serialised, vec![
|
||||
1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
2,
|
||||
40, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
69, 0, 0, 0, 0, 0, 0, 0
|
||||
@@ -202,14 +252,14 @@ mod tests {
|
||||
let two: AccountID = [2u8; 32];
|
||||
let tx = Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 69,
|
||||
function: Function::StakingTransferStake,
|
||||
input_data: Vec::new().join(&two).join(&69u64),
|
||||
nonce: 69,
|
||||
};
|
||||
let data = [
|
||||
1u8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
2,
|
||||
40, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
69, 0, 0, 0, 0, 0, 0, 0
|
||||
@@ -269,17 +319,23 @@ mod tests {
|
||||
fn serialise_block_works() {
|
||||
let one: AccountID = [1u8; 32];
|
||||
let two: AccountID = [2u8; 32];
|
||||
let tx1 = Transaction {
|
||||
signed: one.clone(),
|
||||
function: Function::StakingTransferStake,
|
||||
input_data: Vec::new().join(&two).join(&69u64),
|
||||
nonce: 69,
|
||||
let tx1 = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 69,
|
||||
function: Function::StakingTransferStake,
|
||||
input_data: Vec::new().join(&two).join(&69u64),
|
||||
},
|
||||
signature: [1u8; 64],
|
||||
};
|
||||
let tx2 = Transaction {
|
||||
signed: two.clone(),
|
||||
function: Function::StakingStake,
|
||||
input_data: Vec::new(),
|
||||
nonce: 42,
|
||||
let tx2 = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: two.clone(),
|
||||
nonce: 42,
|
||||
function: Function::StakingStake,
|
||||
input_data: Vec::new(),
|
||||
},
|
||||
signature: [2u8; 64],
|
||||
};
|
||||
let h = Header {
|
||||
parent_hash: [4u8; 32],
|
||||
@@ -305,18 +361,20 @@ mod tests {
|
||||
11, 0, 0, 0,
|
||||
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103,
|
||||
// transactions
|
||||
130, 0, 0, 0,
|
||||
2, 1, 0, 0,
|
||||
// tx1
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
2,
|
||||
40, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
// tx2
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
0,
|
||||
42, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0
|
||||
]);
|
||||
}
|
||||
@@ -325,17 +383,23 @@ mod tests {
|
||||
fn deserialise_block_works() {
|
||||
let one: AccountID = [1u8; 32];
|
||||
let two: AccountID = [2u8; 32];
|
||||
let tx1 = Transaction {
|
||||
signed: one.clone(),
|
||||
function: Function::StakingTransferStake,
|
||||
input_data: Vec::new().join(&two).join(&69u64),
|
||||
nonce: 69,
|
||||
let tx1 = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 69,
|
||||
function: Function::StakingTransferStake,
|
||||
input_data: Vec::new().join(&two).join(&69u64),
|
||||
},
|
||||
signature: [1u8; 64],
|
||||
};
|
||||
let tx2 = Transaction {
|
||||
signed: two.clone(),
|
||||
function: Function::StakingStake,
|
||||
input_data: Vec::new(),
|
||||
nonce: 42,
|
||||
let tx2 = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: two.clone(),
|
||||
nonce: 42,
|
||||
function: Function::StakingStake,
|
||||
input_data: Vec::new(),
|
||||
},
|
||||
signature: [2u8; 64],
|
||||
};
|
||||
let h = Header {
|
||||
parent_hash: [4u8; 32],
|
||||
@@ -360,18 +424,20 @@ mod tests {
|
||||
11, 0, 0, 0,
|
||||
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103,
|
||||
// transactions
|
||||
130, 0, 0, 0,
|
||||
2, 1, 0, 0,
|
||||
// tx1
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
2,
|
||||
40, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
// tx2
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
0,
|
||||
42, 0, 0, 0, 0, 0, 0, 0,
|
||||
0,
|
||||
0, 0, 0, 0
|
||||
];
|
||||
let deserialised = Block::from_slice(&data).unwrap();
|
||||
|
||||
@@ -3,12 +3,12 @@ use endiansensitive::EndianSensitive;
|
||||
use runtime_support;
|
||||
|
||||
pub trait Storage {
|
||||
fn storage_into(key: &[u8]) -> Self;
|
||||
fn into(key: &[u8]) -> Self;
|
||||
fn store(&self, key: &[u8]);
|
||||
}
|
||||
|
||||
impl<T: Default + Sized + EndianSensitive> Storage for T {
|
||||
fn storage_into(key: &[u8]) -> Self {
|
||||
fn into(key: &[u8]) -> Self {
|
||||
Slicable::set_as_slice(|out| runtime_support::read_storage(key, out) == out.len())
|
||||
.unwrap_or_else(Default::default)
|
||||
}
|
||||
@@ -19,5 +19,5 @@ impl<T: Default + Sized + EndianSensitive> Storage for T {
|
||||
}
|
||||
|
||||
pub fn storage_into<T: Storage>(key: &[u8]) -> T {
|
||||
T::storage_into(key)
|
||||
T::into(key)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user