mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-09 19:01:08 +00:00
reintroduce slicable to primitives
This commit is contained in:
@@ -15,7 +15,7 @@ untrusted = "0.5"
|
||||
twox-hash = "1.1.0"
|
||||
byteorder = "1.1"
|
||||
blake2-rfc = "0.2.18"
|
||||
polkadot-runtime-codec = { path = "../runtime-codec", version = "0.1" }
|
||||
polkadot-runtime-codec = { path = "../runtime-codec", version = "0.1", default_features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
polkadot-serializer = { path = "../serializer", version = "0.1" }
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
//! Block and header type definitions.
|
||||
|
||||
use bytes::{self, Vec};
|
||||
use codec::Slicable;
|
||||
use hash::H256;
|
||||
use parachain;
|
||||
use transaction::UncheckedTransaction;
|
||||
@@ -34,6 +35,35 @@ pub type TransactionHash = H256;
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
|
||||
pub struct Log(#[serde(with="bytes")] pub Vec<u8>);
|
||||
|
||||
impl Slicable for Log {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
Vec::<u8>::from_slice(value).map(Log)
|
||||
}
|
||||
|
||||
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
self.0.as_slice_then(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::codec::NonTrivialSlicable for Log { }
|
||||
|
||||
/// The digest of a block, useful for light-clients.
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Digest {
|
||||
/// All logs that have happened in the block.
|
||||
pub logs: Vec<Log>,
|
||||
}
|
||||
|
||||
impl Slicable for Digest {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
Vec::<Log>::from_slice(value).map(|logs| Digest { logs })
|
||||
}
|
||||
|
||||
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
self.logs.as_slice_then(f)
|
||||
}
|
||||
}
|
||||
|
||||
/// A Polkadot relay chain block.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize)]
|
||||
pub struct Block {
|
||||
@@ -43,11 +73,26 @@ pub struct Block {
|
||||
pub transactions: Vec<UncheckedTransaction>,
|
||||
}
|
||||
|
||||
/// The digest of a block, useful for light-clients.
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Digest {
|
||||
/// All logs that have happened in the block.
|
||||
pub logs: Vec<Log>,
|
||||
impl Slicable for Block {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
Some(Block {
|
||||
header: try_opt!(Slicable::from_slice(value)),
|
||||
transactions: try_opt!(Slicable::from_slice(value)),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_vec(&self) -> Vec<u8> {
|
||||
let mut v = Vec::new();
|
||||
|
||||
v.extend(self.header.to_vec());
|
||||
v.extend(self.transactions.to_vec());
|
||||
|
||||
v
|
||||
}
|
||||
|
||||
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
f(self.to_vec().as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
/// A relay chain block header.
|
||||
@@ -65,12 +110,38 @@ pub struct Header {
|
||||
pub state_root: H256,
|
||||
/// The root of the trie that represents this block's transactions, indexed by a 32-byte integer.
|
||||
pub transaction_root: H256,
|
||||
/// Parachain activity bitfield
|
||||
pub parachain_activity: parachain::Activity,
|
||||
/// The digest of activity on the block.
|
||||
pub digest: Digest,
|
||||
}
|
||||
|
||||
impl Slicable for Header {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
Some(Header {
|
||||
parent_hash: try_opt!(Slicable::from_slice(value)),
|
||||
number: try_opt!(Slicable::from_slice(value)),
|
||||
state_root: try_opt!(Slicable::from_slice(value)),
|
||||
transaction_root: try_opt!(Slicable::from_slice(value)),
|
||||
digest: try_opt!(Slicable::from_slice(value)),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_vec(&self) -> Vec<u8> {
|
||||
let mut v = Vec::new();
|
||||
|
||||
self.parent_hash.as_slice_then(|s| v.extend(s));
|
||||
self.number.as_slice_then(|s| v.extend(s));
|
||||
self.state_root.as_slice_then(|s| v.extend(s));
|
||||
self.transaction_root.as_slice_then(|s| v.extend(s));
|
||||
self.digest.as_slice_then(|s| v.extend(s));
|
||||
|
||||
v
|
||||
}
|
||||
|
||||
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
f(self.to_vec().as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
/// A relay chain block body.
|
||||
///
|
||||
/// Included candidates should be sorted by parachain ID, and without duplicate
|
||||
@@ -86,25 +157,33 @@ pub struct Body {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use codec::Slicable;
|
||||
use polkadot_serializer as ser;
|
||||
|
||||
#[test]
|
||||
fn test_header_serialization() {
|
||||
assert_eq!(ser::to_string_pretty(&Header {
|
||||
let header = Header {
|
||||
parent_hash: 5.into(),
|
||||
number: 67,
|
||||
state_root: 3.into(),
|
||||
parachain_activity: parachain::Activity(vec![0]),
|
||||
logs: vec![Log(vec![1])],
|
||||
}), r#"{
|
||||
transaction_root: 6.into(),
|
||||
digest: Digest { logs: vec![Log(vec![1])] },
|
||||
};
|
||||
|
||||
assert_eq!(ser::to_string_pretty(&header), r#"{
|
||||
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000005",
|
||||
"number": 67,
|
||||
"stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000003",
|
||||
"parachainActivity": "0x00",
|
||||
"logs": [
|
||||
"0x01"
|
||||
]
|
||||
"transactionRoot": "0x0000000000000000000000000000000000000000000000000000000000000006",
|
||||
"digest": {
|
||||
"logs": [
|
||||
"0x01"
|
||||
]
|
||||
}
|
||||
}"#);
|
||||
|
||||
let v = header.to_vec();
|
||||
assert_eq!(Header::from_slice(&mut &v[..]).unwrap(), header);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -34,6 +34,16 @@ macro_rules! impl_serde {
|
||||
.map(|x| (&*x).into())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::codec::Slicable for $name {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
<[u8; $len] as ::codec::Slicable>::from_slice(value).map($name)
|
||||
}
|
||||
|
||||
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
self.0.as_slice_then(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ extern crate uint as uint_crate;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
extern crate core;
|
||||
extern crate polkadot_runtime_codec as codec;
|
||||
#[cfg(test)]
|
||||
extern crate polkadot_serializer;
|
||||
#[cfg(test)]
|
||||
@@ -50,6 +51,16 @@ extern crate pretty_assertions;
|
||||
#[macro_use]
|
||||
extern crate alloc;
|
||||
|
||||
// TODO: factor out to separate crate.
|
||||
macro_rules! try_opt {
|
||||
($e: expr) => {
|
||||
match $e {
|
||||
Some(x) => x,
|
||||
None => return None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mod bytes;
|
||||
pub mod block;
|
||||
pub mod contract;
|
||||
@@ -95,6 +106,12 @@ pub type Hash = [u8; 32];
|
||||
/// Alias to 520-bit hash when used in the context of a signature.
|
||||
pub type Signature = hash::H512;
|
||||
|
||||
/// A balance in the staking subsystem.
|
||||
pub type Balance = u64;
|
||||
|
||||
/// A timestamp.
|
||||
pub type Timestamp = u64;
|
||||
|
||||
/// A hash function.
|
||||
pub fn hash(data: &[u8]) -> hash::H256 {
|
||||
blake2_256(data).into()
|
||||
|
||||
@@ -30,6 +30,16 @@ impl From<u64> for Id {
|
||||
fn from(x: u64) -> Self { Id(x) }
|
||||
}
|
||||
|
||||
impl ::codec::Slicable for Id {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
u64::from_slice(value).map(Id)
|
||||
}
|
||||
|
||||
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
self.0.as_slice_then(f)
|
||||
}
|
||||
}
|
||||
|
||||
/// Candidate parachain block.
|
||||
///
|
||||
/// https://github.com/w3f/polkadot-spec/blob/master/spec.md#candidate-para-chain-block
|
||||
@@ -101,6 +111,16 @@ pub struct ValidationCode(#[serde(with="bytes")] pub Vec<u8>);
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct Activity(#[serde(with="bytes")] pub Vec<u8>);
|
||||
|
||||
impl ::codec::Slicable for Activity {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
Vec::<u8>::from_slice(value).map(Activity)
|
||||
}
|
||||
|
||||
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
self.0.as_slice_then(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -19,12 +19,12 @@
|
||||
//! This describes a combination of a function ID and data that can be used to call into
|
||||
//! an internal function.
|
||||
|
||||
use bytes;
|
||||
use block::Number as BlockNumber;
|
||||
use codec::Slicable;
|
||||
|
||||
/// Internal functions that can be dispatched to.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[repr(u8)]
|
||||
pub enum InternalFunction {
|
||||
enum InternalFunctionId {
|
||||
/// Set the system's code.
|
||||
SystemSetCode = 0,
|
||||
/// Set the number of sessions per era.
|
||||
@@ -39,17 +39,17 @@ pub enum InternalFunction {
|
||||
SessionSetLength = 5,
|
||||
}
|
||||
|
||||
impl InternalFunction {
|
||||
impl InternalFunctionId {
|
||||
/// Derive `Some` value from a `u8`, or `None` if it's invalid.
|
||||
pub fn from_u8(value: u8) -> Option<InternalFunction> {
|
||||
fn from_u8(value: u8) -> Option<InternalFunctionId> {
|
||||
use self::*;
|
||||
let functions = [
|
||||
InternalFunction::SystemSetCode,
|
||||
InternalFunction::StakingSetSessionsPerEra,
|
||||
InternalFunction::StakingSetBondingDuration,
|
||||
InternalFunction::StakingSetValidatorCount,
|
||||
InternalFunction::GovernanceSetApprovalPpmRequired,
|
||||
InternalFunction::SessionSetLength
|
||||
InternalFunctionId::SystemSetCode,
|
||||
InternalFunctionId::StakingSetSessionsPerEra,
|
||||
InternalFunctionId::StakingSetBondingDuration,
|
||||
InternalFunctionId::StakingSetValidatorCount,
|
||||
InternalFunctionId::GovernanceSetApprovalPpmRequired,
|
||||
InternalFunctionId::SessionSetLength
|
||||
];
|
||||
if (value as usize) < functions.len() {
|
||||
Some(functions[value as usize])
|
||||
@@ -59,31 +59,85 @@ impl InternalFunction {
|
||||
}
|
||||
}
|
||||
|
||||
/// Internal functions that can be dispatched to.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[repr(u8)]
|
||||
pub enum InternalFunction {
|
||||
/// Set the system's code.
|
||||
SystemSetCode(Vec<u8>),
|
||||
/// Set the number of sessions per era.
|
||||
StakingSetSessionsPerEra(BlockNumber),
|
||||
/// Set the minimum bonding duration for staking.
|
||||
StakingSetBondingDuration(BlockNumber),
|
||||
/// Set the validator count for staking.
|
||||
StakingSetValidatorCount(u32),
|
||||
/// Set the per-mille of validator approval required for governance changes.
|
||||
GovernanceSetApprovalPpmRequired(u32),
|
||||
/// Set the session length.
|
||||
SessionSetLength(BlockNumber),
|
||||
}
|
||||
|
||||
/// An internal function.
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Proposal {
|
||||
/// The privileged function to call.
|
||||
pub function: InternalFunction,
|
||||
/// The serialised data to call it with.
|
||||
#[serde(with = "bytes")]
|
||||
pub input_data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
use support::StaticHexInto;
|
||||
|
||||
#[test]
|
||||
fn slicing_should_work() {
|
||||
let p = Proposal {
|
||||
function: InternalFunction::SystemSetCode,
|
||||
input_data: b"Hello world".to_vec(),
|
||||
impl Slicable for Proposal {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
let id = try_opt!(u8::from_slice(value).and_then(InternalFunctionId::from_u8));
|
||||
let function = match id {
|
||||
InternalFunctionId::SystemSetCode =>
|
||||
InternalFunction::SystemSetCode(try_opt!(Slicable::from_slice(value))),
|
||||
InternalFunctionId::StakingSetSessionsPerEra =>
|
||||
InternalFunction::StakingSetSessionsPerEra(try_opt!(Slicable::from_slice(value))),
|
||||
InternalFunctionId::StakingSetBondingDuration =>
|
||||
InternalFunction::StakingSetBondingDuration(try_opt!(Slicable::from_slice(value))),
|
||||
InternalFunctionId::StakingSetValidatorCount =>
|
||||
InternalFunction::StakingSetValidatorCount(try_opt!(Slicable::from_slice(value))),
|
||||
InternalFunctionId::GovernanceSetApprovalPpmRequired =>
|
||||
InternalFunction::GovernanceSetApprovalPpmRequired(try_opt!(Slicable::from_slice(value))),
|
||||
InternalFunctionId::SessionSetLength =>
|
||||
InternalFunction::SessionSetLength(try_opt!(Slicable::from_slice(value))),
|
||||
};
|
||||
let v = p.to_vec();
|
||||
assert_eq!(v, "000b00000048656c6c6f20776f726c64".convert::<Vec<u8>>());
|
||||
|
||||
let o = Proposal::from_slice(&v).unwrap();
|
||||
assert_eq!(p, o);
|
||||
Some(Proposal { function })
|
||||
}
|
||||
|
||||
fn to_vec(&self) -> Vec<u8> {
|
||||
let mut v = Vec::new();
|
||||
match self.function {
|
||||
InternalFunction::SystemSetCode(ref data) => {
|
||||
(InternalFunctionId::SystemSetCode as u8).as_slice_then(|s| v.extend(s));
|
||||
data.as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
InternalFunction::StakingSetSessionsPerEra(ref data) => {
|
||||
(InternalFunctionId::StakingSetSessionsPerEra as u8).as_slice_then(|s| v.extend(s));
|
||||
data.as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
InternalFunction::StakingSetBondingDuration(ref data) => {
|
||||
(InternalFunctionId::StakingSetBondingDuration as u8).as_slice_then(|s| v.extend(s));
|
||||
data.as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
InternalFunction::StakingSetValidatorCount(ref data) => {
|
||||
(InternalFunctionId::StakingSetValidatorCount as u8).as_slice_then(|s| v.extend(s));
|
||||
data.as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
InternalFunction::GovernanceSetApprovalPpmRequired(ref data) => {
|
||||
(InternalFunctionId::GovernanceSetApprovalPpmRequired as u8).as_slice_then(|s| v.extend(s));
|
||||
data.as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
InternalFunction::SessionSetLength(ref data) => {
|
||||
(InternalFunctionId::SessionSetLength as u8).as_slice_then(|s| v.extend(s));
|
||||
data.as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
}
|
||||
|
||||
v
|
||||
}
|
||||
|
||||
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
f(self.to_vec().as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
//! Polkadot runtime functions.
|
||||
//! This describes a function that can be called from an external transaction.
|
||||
|
||||
use codec::Slicable;
|
||||
|
||||
/// Public functions that can be dispatched to.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[repr(u8)]
|
||||
pub enum Function {
|
||||
enum FunctionId {
|
||||
/// Staking subsystem: begin staking.
|
||||
StakingStake = 0,
|
||||
/// Staking subsystem: stop staking.
|
||||
@@ -37,18 +39,99 @@ pub enum Function {
|
||||
GovernanceApprove = 6,
|
||||
}
|
||||
|
||||
impl Function {
|
||||
impl FunctionId {
|
||||
/// Derive `Some` value from a `u8`, or `None` if it's invalid.
|
||||
pub fn from_u8(value: u8) -> Option<Function> {
|
||||
fn from_u8(value: u8) -> Option<FunctionId> {
|
||||
match value {
|
||||
0 => Some(Function::StakingStake),
|
||||
1 => Some(Function::StakingUnstake),
|
||||
2 => Some(Function::StakingTransfer),
|
||||
3 => Some(Function::SessionSetKey),
|
||||
4 => Some(Function::TimestampSet),
|
||||
5 => Some(Function::GovernancePropose),
|
||||
6 => Some(Function::GovernanceApprove),
|
||||
0 => Some(FunctionId::StakingStake),
|
||||
1 => Some(FunctionId::StakingUnstake),
|
||||
2 => Some(FunctionId::StakingTransfer),
|
||||
3 => Some(FunctionId::SessionSetKey),
|
||||
4 => Some(FunctionId::TimestampSet),
|
||||
5 => Some(FunctionId::GovernancePropose),
|
||||
6 => Some(FunctionId::GovernanceApprove),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Functions on the runtime.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[repr(u8)]
|
||||
pub enum Function {
|
||||
/// Staking subsystem: begin staking.
|
||||
StakingStake,
|
||||
/// Staking subsystem: stop staking.
|
||||
StakingUnstake,
|
||||
/// Staking subsystem: transfer stake.
|
||||
StakingTransfer(::AccountId, ::Balance),
|
||||
/// Set temporary session key as a validator.
|
||||
SessionSetKey(::SessionKey),
|
||||
/// Set the timestamp.
|
||||
TimestampSet(::Timestamp),
|
||||
/// Make a proposal for the governance system.
|
||||
GovernancePropose(::proposal::Proposal),
|
||||
/// Approve a proposal for the governance system.
|
||||
GovernanceApprove(::block::Number),
|
||||
}
|
||||
|
||||
impl Slicable for Function {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
let id = try_opt!(u8::from_slice(value).and_then(FunctionId::from_u8));
|
||||
Some(match id {
|
||||
FunctionId::StakingStake => Function::StakingStake,
|
||||
FunctionId::StakingUnstake => Function::StakingUnstake,
|
||||
FunctionId::StakingTransfer => Function::StakingTransfer(
|
||||
try_opt!(Slicable::from_slice(value)),
|
||||
try_opt!(Slicable::from_slice(value)),
|
||||
),
|
||||
FunctionId::SessionSetKey =>
|
||||
Function::SessionSetKey(try_opt!(Slicable::from_slice(value))),
|
||||
FunctionId::TimestampSet =>
|
||||
Function::TimestampSet(try_opt!(Slicable::from_slice(value))),
|
||||
FunctionId::GovernancePropose =>
|
||||
Function::GovernancePropose(try_opt!(Slicable::from_slice(value))),
|
||||
FunctionId::GovernanceApprove =>
|
||||
Function::GovernanceApprove(try_opt!(Slicable::from_slice(value))),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_vec(&self) -> Vec<u8> {
|
||||
let mut v = Vec::new();
|
||||
match *self {
|
||||
Function::StakingStake => {
|
||||
(FunctionId::StakingStake as u8).as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
Function::StakingUnstake => {
|
||||
(FunctionId::StakingUnstake as u8).as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
Function::StakingTransfer(ref to, ref amount) => {
|
||||
(FunctionId::StakingTransfer as u8).as_slice_then(|s| v.extend(s));
|
||||
to.as_slice_then(|s| v.extend(s));
|
||||
amount.as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
Function::SessionSetKey(ref data) => {
|
||||
(FunctionId::SessionSetKey as u8).as_slice_then(|s| v.extend(s));
|
||||
data.as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
Function::TimestampSet(ref data) => {
|
||||
(FunctionId::TimestampSet as u8).as_slice_then(|s| v.extend(s));
|
||||
data.as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
Function::GovernancePropose(ref data) => {
|
||||
(FunctionId::GovernancePropose as u8).as_slice_then(|s| v.extend(s));
|
||||
data.as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
Function::GovernanceApprove(ref data) => {
|
||||
(FunctionId::GovernanceApprove as u8).as_slice_then(|s| v.extend(s));
|
||||
data.as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
}
|
||||
|
||||
v
|
||||
}
|
||||
|
||||
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
f(self.to_vec().as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
//! Transaction type.
|
||||
|
||||
use bytes::{self, Vec};
|
||||
use codec::Slicable;
|
||||
use runtime_function::Function;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
@@ -48,6 +49,38 @@ pub struct UncheckedTransaction {
|
||||
pub signature: ::Signature,
|
||||
}
|
||||
|
||||
impl Slicable for UncheckedTransaction {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
Some(UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: try_opt!(Slicable::from_slice(value)),
|
||||
nonce: try_opt!(Slicable::from_slice(value)),
|
||||
function: try_opt!(Slicable::from_slice(value)),
|
||||
input_data: try_opt!(Slicable::from_slice(value)),
|
||||
},
|
||||
signature: try_opt!(Slicable::from_slice(value)),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_vec(&self) -> Vec<u8> {
|
||||
let mut v = Vec::new();
|
||||
|
||||
self.transaction.signed.as_slice_then(|s| v.extend(s));
|
||||
self.transaction.nonce.as_slice_then(|s| v.extend(s));
|
||||
self.transaction.function.as_slice_then(|s| v.extend(s));
|
||||
self.transaction.input_data.as_slice_then(|s| v.extend(s));
|
||||
self.signature.as_slice_then(|s| v.extend(s));
|
||||
|
||||
v
|
||||
}
|
||||
|
||||
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
f(self.to_vec().as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
impl ::codec::NonTrivialSlicable for UncheckedTransaction {}
|
||||
|
||||
impl PartialEq for UncheckedTransaction {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.signature.iter().eq(other.signature.iter()) && self.transaction == other.transaction
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
mod endiansensitive;
|
||||
mod slicable;
|
||||
mod streamreader;
|
||||
mod joiner;
|
||||
mod keyedvec;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user