mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-12 10:01:17 +00:00
Split out substrate-primitives from polkadot-primitives.
Bottom half minus tests builds.
This commit is contained in:
@@ -18,11 +18,9 @@
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use bytes;
|
||||
use bytes::Vec;
|
||||
use rstd::vec::Vec;
|
||||
use codec::Slicable;
|
||||
use hash::H256;
|
||||
use parachain;
|
||||
use relay::transaction::UncheckedTransaction;
|
||||
|
||||
/// Used to refer to a block number.
|
||||
pub type Number = u64;
|
||||
@@ -33,9 +31,26 @@ pub type HeaderHash = H256;
|
||||
/// Hash used to refer to a transaction hash.
|
||||
pub type TransactionHash = H256;
|
||||
|
||||
/// Simple generic transaction type.
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct Transaction(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
impl Slicable for Transaction {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
Vec::<u8>::from_slice(value).map(Transaction)
|
||||
}
|
||||
|
||||
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
self.0.as_slice_then(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl ::codec::NonTrivialSlicable for Transaction { }
|
||||
|
||||
/// Execution log (event)
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct Log(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
impl Slicable for Log {
|
||||
@@ -51,8 +66,8 @@ impl Slicable for Log {
|
||||
impl ::codec::NonTrivialSlicable for Log { }
|
||||
|
||||
/// The digest of a block, useful for light-clients.
|
||||
#[derive(Debug, Clone, Default, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
#[derive(Clone, Default, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct Digest {
|
||||
/// All logs that have happened in the block.
|
||||
pub logs: Vec<Log>,
|
||||
@@ -68,14 +83,14 @@ impl Slicable for Digest {
|
||||
}
|
||||
}
|
||||
|
||||
/// A Polkadot relay chain block.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
/// A Substrate relay chain block.
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct Block {
|
||||
/// The block header.
|
||||
pub header: Header,
|
||||
/// All relay-chain transactions.
|
||||
pub transactions: Vec<UncheckedTransaction>,
|
||||
pub transactions: Vec<Transaction>,
|
||||
}
|
||||
|
||||
impl Slicable for Block {
|
||||
@@ -103,8 +118,8 @@ impl Slicable for Block {
|
||||
/// A relay chain block header.
|
||||
///
|
||||
/// https://github.com/w3f/polkadot-spec/blob/master/spec.md#header
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
||||
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
|
||||
pub struct Header {
|
||||
@@ -161,19 +176,6 @@ impl Slicable for Header {
|
||||
}
|
||||
}
|
||||
|
||||
/// A relay chain block body.
|
||||
///
|
||||
/// Included candidates should be sorted by parachain ID, and without duplicate
|
||||
/// IDs.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
||||
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
|
||||
pub struct Body {
|
||||
/// Parachain proposal blocks.
|
||||
pub candidates: Vec<parachain::Candidate>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
@@ -205,28 +207,4 @@ mod tests {
|
||||
let v = header.to_vec();
|
||||
assert_eq!(Header::from_slice(&mut &v[..]).unwrap(), header);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_body_serialization() {
|
||||
assert_eq!(ser::to_string_pretty(&Body {
|
||||
candidates: vec![
|
||||
parachain::Candidate {
|
||||
parachain_index: 10.into(),
|
||||
collator_signature: Default::default(),
|
||||
unprocessed_ingress: Default::default(),
|
||||
block: ::parachain::BlockData(vec![1, 3, 5, 8]),
|
||||
}
|
||||
],
|
||||
}), r#"{
|
||||
"candidates": [
|
||||
{
|
||||
"parachainIndex": 10,
|
||||
"collatorSignature": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"unprocessedIngress": [],
|
||||
"block": "0x01030508"
|
||||
}
|
||||
]
|
||||
}"#);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -14,6 +14,8 @@
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Simply type for representing Vec<u8> with regards to serde.
|
||||
|
||||
use core::fmt;
|
||||
|
||||
use serde::{de, Serializer, Deserializer};
|
||||
@@ -60,7 +62,8 @@ pub fn serialize_uint<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
|
||||
}
|
||||
|
||||
/// Expected length of bytes vector.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[derive(PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Debug))]
|
||||
pub enum ExpectedLen {
|
||||
/// Any length in bytes.
|
||||
#[cfg_attr(not(feature = "std"), allow(unused))]
|
||||
|
||||
@@ -16,18 +16,22 @@
|
||||
|
||||
//! A fixed hash type.
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use bytes;
|
||||
|
||||
macro_rules! impl_serde {
|
||||
macro_rules! impl_rest {
|
||||
($name: ident, $len: expr) => {
|
||||
#[cfg(feature = "std")]
|
||||
impl Serialize for $name {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
||||
bytes::serialize(&self.0, serializer)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<'de> Deserialize<'de> for $name {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
|
||||
bytes::deserialize_check_len(deserializer, bytes::ExpectedLen::Exact($len))
|
||||
@@ -48,11 +52,11 @@ macro_rules! impl_serde {
|
||||
}
|
||||
|
||||
construct_hash!(H160, 20);
|
||||
impl_serde!(H160, 20);
|
||||
construct_hash!(H256, 32);
|
||||
impl_serde!(H256, 32);
|
||||
construct_hash!(H512, 64);
|
||||
impl_serde!(H512, 64);
|
||||
impl_rest!(H160, 20);
|
||||
impl_rest!(H256, 32);
|
||||
impl_rest!(H512, 64);
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
@@ -22,38 +22,37 @@
|
||||
#![cfg_attr(not(feature = "std"), feature(alloc))]
|
||||
|
||||
extern crate rustc_hex;
|
||||
|
||||
extern crate serde;
|
||||
extern crate byteorder;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
extern crate twox_hash;
|
||||
#[cfg(feature = "std")]
|
||||
extern crate blake2_rfc;
|
||||
|
||||
#[macro_use]
|
||||
extern crate crunchy;
|
||||
#[macro_use]
|
||||
extern crate fixed_hash;
|
||||
#[macro_use]
|
||||
extern crate uint as uint_crate;
|
||||
extern crate substrate_codec as codec;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
extern crate serde;
|
||||
#[cfg(feature = "std")]
|
||||
extern crate twox_hash;
|
||||
#[cfg(feature = "std")]
|
||||
extern crate blake2_rfc;
|
||||
#[cfg(feature = "std")]
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
#[macro_use]
|
||||
extern crate uint as uint_crate;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
extern crate core;
|
||||
extern crate substrate_codec as codec;
|
||||
|
||||
#[macro_use]
|
||||
extern crate substrate_runtime_std as rstd;
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate substrate_serializer;
|
||||
|
||||
#[cfg(test)]
|
||||
#[macro_use]
|
||||
extern crate pretty_assertions;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
#[macro_use]
|
||||
extern crate alloc;
|
||||
|
||||
// TODO: factor out to separate crate.
|
||||
macro_rules! try_opt {
|
||||
($e: expr) => {
|
||||
@@ -64,23 +63,27 @@ macro_rules! try_opt {
|
||||
}
|
||||
}
|
||||
|
||||
mod bytes;
|
||||
pub mod contract;
|
||||
pub mod hash;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod bytes;
|
||||
#[cfg(feature = "std")]
|
||||
pub mod hashing;
|
||||
#[cfg(feature = "std")]
|
||||
pub use hashing::{blake2_256, twox_128, twox_256};
|
||||
#[cfg(feature = "std")]
|
||||
pub mod hexdisplay;
|
||||
pub mod parachain;
|
||||
pub mod relay;
|
||||
|
||||
pub mod storage;
|
||||
pub mod hash;
|
||||
pub mod uint;
|
||||
pub mod validator;
|
||||
pub mod block;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub mod hashing;
|
||||
|
||||
pub use self::hash::{H160, H256};
|
||||
pub use self::uint::{U256, U512};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub use hashing::{blake2_256, twox_128, twox_256};
|
||||
pub use block::{Block, Header};
|
||||
|
||||
/// An identifier for an authority in the consensus algorithm. The same as ed25519::Public.
|
||||
pub type AuthorityId = [u8; 32];
|
||||
|
||||
@@ -1,172 +0,0 @@
|
||||
// Copyright 2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Parachain data types.
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use bytes;
|
||||
use bytes::Vec;
|
||||
|
||||
/// Unique identifier of a parachain.
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct Id(u64);
|
||||
|
||||
impl From<Id> for u64 {
|
||||
fn from(x: Id) -> Self { x.0 }
|
||||
}
|
||||
|
||||
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
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
||||
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
|
||||
pub struct Candidate {
|
||||
/// The ID of the parachain this is a proposal for.
|
||||
pub parachain_index: Id,
|
||||
/// Collator's signature
|
||||
pub collator_signature: ::relay::Signature,
|
||||
/// Unprocessed ingress queue.
|
||||
///
|
||||
/// Ordered by parachain ID and block number.
|
||||
pub unprocessed_ingress: ConsolidatedIngress,
|
||||
/// Block data
|
||||
pub block: BlockData,
|
||||
}
|
||||
|
||||
/// Candidate receipt type.
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Debug, Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
||||
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
|
||||
pub struct CandidateReceipt {
|
||||
/// The ID of the parachain this is a candidate for.
|
||||
pub parachain_index: Id,
|
||||
/// The collator's relay-chain account ID
|
||||
pub collator: ::relay::AccountId,
|
||||
/// The head-data
|
||||
pub head_data: HeadData,
|
||||
/// Balance uploads to the relay chain.
|
||||
pub balance_uploads: Vec<(::relay::AccountId, ::uint::U256)>,
|
||||
/// Egress queue roots.
|
||||
pub egress_queue_roots: Vec<(Id, ::hash::H256)>,
|
||||
/// Fees paid from the chain to the relay chain validators
|
||||
pub fees: ::uint::U256,
|
||||
}
|
||||
|
||||
/// Parachain ingress queue message.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct Message(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
/// Consolidated ingress queue data.
|
||||
///
|
||||
/// This is just an ordered vector of other parachains' egress queues,
|
||||
/// obtained according to the routing rules.
|
||||
#[derive(Debug, Default, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct ConsolidatedIngress(pub Vec<(Id, Vec<Message>)>);
|
||||
|
||||
/// Parachain block data.
|
||||
///
|
||||
/// contains everything required to validate para-block, may contain block and witness data
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct BlockData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
/// Parachain header raw bytes wrapper type.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct Header(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
/// Parachain head data included in the chain.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct HeadData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
/// Parachain validation code.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct ValidationCode(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
/// Activitiy bit field
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Default)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct Activity(#[cfg_attr(feature = "std", 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::*;
|
||||
use substrate_serializer as ser;
|
||||
|
||||
#[test]
|
||||
fn test_candidate() {
|
||||
assert_eq!(ser::to_string_pretty(&Candidate {
|
||||
parachain_index: 5.into(),
|
||||
collator_signature: 10.into(),
|
||||
unprocessed_ingress: ConsolidatedIngress(vec![
|
||||
(Id(1), vec![Message(vec![2])]),
|
||||
(Id(2), vec![Message(vec![2]), Message(vec![3])]),
|
||||
]),
|
||||
block: BlockData(vec![1, 2, 3]),
|
||||
}), r#"{
|
||||
"parachainIndex": 5,
|
||||
"collatorSignature": "0x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a",
|
||||
"unprocessedIngress": [
|
||||
[
|
||||
1,
|
||||
[
|
||||
"0x02"
|
||||
]
|
||||
],
|
||||
[
|
||||
2,
|
||||
[
|
||||
"0x02",
|
||||
"0x03"
|
||||
]
|
||||
]
|
||||
],
|
||||
"block": "0x010203"
|
||||
}"#);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
//! Relay chain primitives.
|
||||
|
||||
pub mod block;
|
||||
pub mod transaction;
|
||||
|
||||
pub use self::block::*;
|
||||
pub use self::transaction::*;
|
||||
|
||||
pub use self::block::Number as BlockNumber;
|
||||
|
||||
/// Virtual account ID that represents the idea of a dispatch/statement being signed by everybody
|
||||
/// (who matters). Essentially this means that a majority of validators have decided it is
|
||||
/// "correct".
|
||||
pub const EVERYBODY: AccountId = [255u8; 32];
|
||||
|
||||
/// Alias to Ed25519 pubkey that identifies an account on the relay chain.
|
||||
pub type AccountId = [u8; 32];
|
||||
|
||||
/// The Ed25519 pub key of an session that belongs to an authority of the relay chain. This is
|
||||
/// used as what the external environment/consensus algorithm calls an "authority".
|
||||
pub type SessionKey = AccountId;
|
||||
|
||||
/// Indentifier for a chain.
|
||||
pub type ChainID = u64;
|
||||
|
||||
/// Index of a transaction in the relay chain.
|
||||
pub type TxOrder = u64;
|
||||
|
||||
/// A hash of some data used by the relay chain.
|
||||
pub type Hash = ::hash::H256;
|
||||
|
||||
/// Alias to 520-bit hash when used in the context of a signature on the relay chain.
|
||||
pub type Signature = ::hash::H512;
|
||||
@@ -1,389 +0,0 @@
|
||||
// Copyright 2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Transaction type.
|
||||
|
||||
use bytes::Vec;
|
||||
use codec::Slicable;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use std::fmt;
|
||||
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::fmt;
|
||||
|
||||
use relay::block::Number as BlockNumber;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
#[repr(u8)]
|
||||
enum InternalFunctionId {
|
||||
/// Set the system's code.
|
||||
SystemSetCode = 0x00,
|
||||
|
||||
/// Set the session length.
|
||||
SessionSetLength = 0x10,
|
||||
/// Force a new session.
|
||||
SessionForceNewSession = 0x11,
|
||||
|
||||
/// Set the number of sessions per era.
|
||||
StakingSetSessionsPerEra = 0x20,
|
||||
/// Set the minimum bonding duration for staking.
|
||||
StakingSetBondingDuration = 0x21,
|
||||
/// Set the validator count for staking.
|
||||
StakingSetValidatorCount = 0x22,
|
||||
/// Force a new staking era.
|
||||
StakingForceNewEra = 0x23,
|
||||
|
||||
/// Set the per-mille of validator approval required for governance changes.
|
||||
GovernanceSetApprovalPpmRequired = 0x30,
|
||||
|
||||
}
|
||||
|
||||
impl InternalFunctionId {
|
||||
/// Derive `Some` value from a `u8`, or `None` if it's invalid.
|
||||
fn from_u8(value: u8) -> Option<InternalFunctionId> {
|
||||
let functions = [
|
||||
InternalFunctionId::SystemSetCode,
|
||||
InternalFunctionId::SessionSetLength,
|
||||
InternalFunctionId::SessionForceNewSession,
|
||||
InternalFunctionId::StakingSetSessionsPerEra,
|
||||
InternalFunctionId::StakingSetBondingDuration,
|
||||
InternalFunctionId::StakingSetValidatorCount,
|
||||
InternalFunctionId::StakingForceNewEra,
|
||||
InternalFunctionId::GovernanceSetApprovalPpmRequired,
|
||||
];
|
||||
functions.iter().map(|&f| f).find(|&f| value == f as u8)
|
||||
}
|
||||
}
|
||||
|
||||
/// Internal functions that can be dispatched to.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub enum InternalFunction {
|
||||
/// Set the system's code.
|
||||
SystemSetCode(Vec<u8>),
|
||||
/// Set the session length.
|
||||
SessionSetLength(BlockNumber),
|
||||
/// Force a new session.
|
||||
SessionForceNewSession,
|
||||
/// 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),
|
||||
/// Force a new staking era.
|
||||
StakingForceNewEra,
|
||||
/// Set the per-mille of validator approval required for governance changes.
|
||||
GovernanceSetApprovalPpmRequired(u32),
|
||||
|
||||
}
|
||||
|
||||
/// An internal function.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct Proposal {
|
||||
/// The privileged function to call.
|
||||
pub function: InternalFunction,
|
||||
}
|
||||
|
||||
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::SessionSetLength =>
|
||||
InternalFunction::SessionSetLength(try_opt!(Slicable::from_slice(value))),
|
||||
InternalFunctionId::SessionForceNewSession => InternalFunction::SessionForceNewSession,
|
||||
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::StakingForceNewEra => InternalFunction::StakingForceNewEra,
|
||||
InternalFunctionId::GovernanceSetApprovalPpmRequired =>
|
||||
InternalFunction::GovernanceSetApprovalPpmRequired(try_opt!(Slicable::from_slice(value))),
|
||||
};
|
||||
|
||||
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::SessionSetLength(ref data) => {
|
||||
(InternalFunctionId::SessionSetLength as u8).as_slice_then(|s| v.extend(s));
|
||||
data.as_slice_then(|s| v.extend(s));
|
||||
}
|
||||
InternalFunction::SessionForceNewSession => {
|
||||
(InternalFunctionId::SessionForceNewSession as u8).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::StakingForceNewEra => {
|
||||
(InternalFunctionId::StakingForceNewEra as u8).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));
|
||||
}
|
||||
}
|
||||
|
||||
v
|
||||
}
|
||||
|
||||
fn as_slice_then<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
f(self.to_vec().as_slice())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Public functions that can be dispatched to.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
#[repr(u8)]
|
||||
enum FunctionId {
|
||||
/// Set the timestamp.
|
||||
TimestampSet = 0x00,
|
||||
/// Set temporary session key as a validator.
|
||||
SessionSetKey = 0x10,
|
||||
/// Staking subsystem: begin staking.
|
||||
StakingStake = 0x20,
|
||||
/// Staking subsystem: stop staking.
|
||||
StakingUnstake = 0x21,
|
||||
/// Staking subsystem: transfer stake.
|
||||
StakingTransfer = 0x22,
|
||||
/// Make a proposal for the governance system.
|
||||
GovernancePropose = 0x30,
|
||||
/// Approve a proposal for the governance system.
|
||||
GovernanceApprove = 0x31,
|
||||
}
|
||||
|
||||
impl FunctionId {
|
||||
/// Derive `Some` value from a `u8`, or `None` if it's invalid.
|
||||
fn from_u8(value: u8) -> Option<FunctionId> {
|
||||
use self::*;
|
||||
let functions = [FunctionId::StakingStake, FunctionId::StakingUnstake,
|
||||
FunctionId::StakingTransfer, FunctionId::SessionSetKey, FunctionId::TimestampSet,
|
||||
FunctionId::GovernancePropose, FunctionId::GovernanceApprove];
|
||||
functions.iter().map(|&f| f).find(|&f| value == f as u8)
|
||||
}
|
||||
}
|
||||
|
||||
/// Functions on the runtime.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub enum Function {
|
||||
/// Set the timestamp.
|
||||
TimestampSet(u64),
|
||||
/// Set temporary session key as a validator.
|
||||
SessionSetKey(::relay::SessionKey),
|
||||
/// Staking subsystem: begin staking.
|
||||
StakingStake,
|
||||
/// Staking subsystem: stop staking.
|
||||
StakingUnstake,
|
||||
/// Staking subsystem: transfer stake.
|
||||
StakingTransfer(::relay::AccountId, u64),
|
||||
/// Make a proposal for the governance system.
|
||||
GovernancePropose(Proposal),
|
||||
/// Approve a proposal for the governance system.
|
||||
GovernanceApprove(BlockNumber),
|
||||
}
|
||||
|
||||
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::TimestampSet =>
|
||||
Function::TimestampSet(try_opt!(Slicable::from_slice(value))),
|
||||
FunctionId::SessionSetKey =>
|
||||
Function::SessionSetKey(try_opt!(Slicable::from_slice(value))),
|
||||
FunctionId::StakingStake => Function::StakingStake,
|
||||
FunctionId::StakingUnstake => Function::StakingUnstake,
|
||||
FunctionId::StakingTransfer => {
|
||||
let to = try_opt!(Slicable::from_slice(value));
|
||||
let amount = try_opt!(Slicable::from_slice(value));
|
||||
|
||||
Function::StakingTransfer(to, amount)
|
||||
}
|
||||
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::TimestampSet(ref data) => {
|
||||
(FunctionId::TimestampSet as u8).as_slice_then(|s| v.extend(s));
|
||||
data.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::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::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())
|
||||
}
|
||||
}
|
||||
|
||||
/// A vetted and verified transaction from the external world.
|
||||
#[derive(Debug, PartialEq, Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct Transaction {
|
||||
/// Who signed it (note this is not a signature).
|
||||
pub signed: super::AccountId,
|
||||
/// The number of transactions have come before from the same signer.
|
||||
pub nonce: super::TxOrder,
|
||||
/// The function that should be called.
|
||||
pub function: Function,
|
||||
}
|
||||
|
||||
impl Slicable for Transaction {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
Some(Transaction {
|
||||
signed: try_opt!(Slicable::from_slice(value)),
|
||||
nonce: try_opt!(Slicable::from_slice(value)),
|
||||
function: try_opt!(Slicable::from_slice(value)),
|
||||
})
|
||||
}
|
||||
|
||||
fn to_vec(&self) -> Vec<u8> {
|
||||
let mut v = Vec::new();
|
||||
|
||||
self.signed.as_slice_then(|s| v.extend(s));
|
||||
self.nonce.as_slice_then(|s| v.extend(s));
|
||||
self.function.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 transactions right from the external world. Unchecked.
|
||||
#[derive(Eq, Clone)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct UncheckedTransaction {
|
||||
/// The actual transaction information.
|
||||
pub transaction: Transaction,
|
||||
/// The signature; should be an Ed25519 signature applied to the serialised `transaction` field.
|
||||
pub signature: super::Signature,
|
||||
}
|
||||
|
||||
impl Slicable for UncheckedTransaction {
|
||||
fn from_slice(value: &mut &[u8]) -> Option<Self> {
|
||||
Some(UncheckedTransaction {
|
||||
transaction: try_opt!(Transaction::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.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
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for UncheckedTransaction {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "UncheckedTransaction({:?})", self.transaction)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ::codec::Slicable;
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn serialize_unchecked() {
|
||||
let tx = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: [1; 32],
|
||||
nonce: 999u64,
|
||||
function: Function::TimestampSet(135135),
|
||||
},
|
||||
signature: ::hash::H512([0; 64]),
|
||||
};
|
||||
|
||||
let v = Slicable::to_vec(&tx);
|
||||
assert_eq!(UncheckedTransaction::from_slice(&mut &v[..]).unwrap(), tx);
|
||||
}
|
||||
}
|
||||
@@ -18,14 +18,14 @@
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use bytes;
|
||||
use bytes::Vec;
|
||||
use rstd::vec::Vec;
|
||||
|
||||
/// Contract storage key.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
#[derive(PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct StorageKey(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
/// Contract storage entry data.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
#[derive(PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize, Debug))]
|
||||
pub struct StorageData(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
@@ -15,215 +15,3 @@
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Tests.
|
||||
|
||||
use codec::Slicable;
|
||||
use relay::{AccountId, Block, Header, Digest, Log, UncheckedTransaction, Transaction, Function};
|
||||
|
||||
#[test]
|
||||
fn serialise_transaction_works() {
|
||||
let one: AccountId = [1u8; 32];
|
||||
let two: AccountId = [2u8; 32];
|
||||
let tx = Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 69,
|
||||
function: Function::StakingTransfer(two, 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,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
34,
|
||||
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
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialise_transaction_works() {
|
||||
let one: AccountId = [1u8; 32];
|
||||
let two: AccountId = [2u8; 32];
|
||||
let tx = Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 69,
|
||||
function: Function::StakingTransfer(two, 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,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
34,
|
||||
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
|
||||
];
|
||||
let deserialised = Transaction::from_slice(&mut &data[..]).unwrap();
|
||||
assert_eq!(deserialised, tx);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialise_header_works() {
|
||||
let h = Header {
|
||||
parent_hash: [4u8; 32].into(),
|
||||
number: 42,
|
||||
state_root: [5u8; 32].into(),
|
||||
transaction_root: [6u8; 32].into(),
|
||||
digest: Digest { logs: vec![ Log(b"one log".to_vec()), Log(b"another log".to_vec()) ], },
|
||||
};
|
||||
let serialised = h.to_vec();
|
||||
assert_eq!(serialised, vec![
|
||||
4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
42, 0, 0, 0, 0, 0, 0, 0,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
2, 0, 0, 0,
|
||||
7, 0, 0, 0,
|
||||
111, 110, 101, 32, 108, 111, 103,
|
||||
11, 0, 0, 0,
|
||||
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialise_header_works() {
|
||||
let h = Header {
|
||||
parent_hash: [4u8; 32].into(),
|
||||
number: 42,
|
||||
state_root: [5u8; 32].into(),
|
||||
transaction_root: [6u8; 32].into(),
|
||||
digest: Digest { logs: vec![ Log(b"one log".to_vec()), Log(b"another log".to_vec()) ], },
|
||||
};
|
||||
let data = [
|
||||
4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
42, 0, 0, 0, 0, 0, 0, 0,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
2, 0, 0, 0,
|
||||
7, 0, 0, 0,
|
||||
111, 110, 101, 32, 108, 111, 103,
|
||||
11, 0, 0, 0,
|
||||
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103
|
||||
];
|
||||
let deserialised = Header::from_slice(&mut &data[..]).unwrap();
|
||||
assert_eq!(deserialised, h);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn serialise_block_works() {
|
||||
let one: AccountId = [1u8; 32];
|
||||
let two: AccountId = [2u8; 32];
|
||||
let tx1 = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 69,
|
||||
function: Function::StakingTransfer(two, 69),
|
||||
},
|
||||
signature: [1u8; 64].into(),
|
||||
};
|
||||
let tx2 = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: two.clone(),
|
||||
nonce: 42,
|
||||
function: Function::StakingStake,
|
||||
},
|
||||
signature: [2u8; 64].into(),
|
||||
};
|
||||
let h = Header {
|
||||
parent_hash: [4u8; 32].into(),
|
||||
number: 42,
|
||||
state_root: [5u8; 32].into(),
|
||||
transaction_root: [6u8; 32].into(),
|
||||
digest: Digest { logs: vec![ Log(b"one log".to_vec()), Log(b"another log".to_vec()) ], },
|
||||
};
|
||||
let b = Block {
|
||||
header: h,
|
||||
transactions: vec![tx1, tx2],
|
||||
};
|
||||
let serialised = b.to_vec();
|
||||
assert_eq!(serialised, vec![
|
||||
// header
|
||||
4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
42, 0, 0, 0, 0, 0, 0, 0,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
2, 0, 0, 0,
|
||||
7, 0, 0, 0,
|
||||
111, 110, 101, 32, 108, 111, 103,
|
||||
11, 0, 0, 0,
|
||||
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103,
|
||||
// transactions
|
||||
2, 0, 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,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
34,
|
||||
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,
|
||||
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,
|
||||
// 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,
|
||||
42, 0, 0, 0, 0, 0, 0, 0,
|
||||
32,
|
||||
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,
|
||||
]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialise_block_works() {
|
||||
let one: AccountId = [1u8; 32];
|
||||
let two: AccountId = [2u8; 32];
|
||||
let tx1 = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: one.clone(),
|
||||
nonce: 69,
|
||||
function: Function::StakingTransfer(two, 69),
|
||||
},
|
||||
signature: [1u8; 64].into(),
|
||||
};
|
||||
let tx2 = UncheckedTransaction {
|
||||
transaction: Transaction {
|
||||
signed: two.clone(),
|
||||
nonce: 42,
|
||||
function: Function::StakingStake,
|
||||
},
|
||||
signature: [2u8; 64].into(),
|
||||
};
|
||||
let h = Header {
|
||||
parent_hash: [4u8; 32].into(),
|
||||
number: 42,
|
||||
state_root: [5u8; 32].into(),
|
||||
transaction_root: [6u8; 32].into(),
|
||||
digest: Digest { logs: vec![ Log(b"one log".to_vec()), Log(b"another log".to_vec()) ], },
|
||||
};
|
||||
let b = Block {
|
||||
header: h,
|
||||
transactions: vec![tx1, tx2],
|
||||
};
|
||||
let data = [
|
||||
// header
|
||||
4u8, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
42, 0, 0, 0, 0, 0, 0, 0,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
|
||||
2, 0, 0, 0,
|
||||
7, 0, 0, 0,
|
||||
111, 110, 101, 32, 108, 111, 103,
|
||||
11, 0, 0, 0,
|
||||
97, 110, 111, 116, 104, 101, 114, 32, 108, 111, 103,
|
||||
// transactions
|
||||
2, 0, 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,
|
||||
69, 0, 0, 0, 0, 0, 0, 0,
|
||||
34,
|
||||
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,
|
||||
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,
|
||||
// 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,
|
||||
42, 0, 0, 0, 0, 0, 0, 0,
|
||||
32,
|
||||
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,
|
||||
];
|
||||
let deserialised = Block::from_slice(&mut &data[..]).unwrap();
|
||||
assert_eq!(deserialised, b);
|
||||
}
|
||||
|
||||
@@ -16,12 +16,15 @@
|
||||
|
||||
//! An unsigned fixed-size integer.
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use serde::{Serialize, Serializer, Deserialize, Deserializer};
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use bytes;
|
||||
|
||||
macro_rules! impl_serde {
|
||||
($name: ident, $len: expr) => {
|
||||
#[cfg(feature = "std")]
|
||||
impl Serialize for $name {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
|
||||
let mut bytes = [0u8; $len * 8];
|
||||
@@ -30,6 +33,7 @@ macro_rules! impl_serde {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
impl<'de> Deserialize<'de> for $name {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
|
||||
bytes::deserialize_check_len(deserializer, bytes::ExpectedLen::Between(0, $len * 8))
|
||||
@@ -40,8 +44,8 @@ macro_rules! impl_serde {
|
||||
}
|
||||
|
||||
construct_uint!(U256, 4);
|
||||
impl_serde!(U256, 4);
|
||||
construct_uint!(U512, 8);
|
||||
impl_serde!(U256, 4);
|
||||
impl_serde!(U512, 8);
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
// Copyright 2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Polkadot.
|
||||
|
||||
// Polkadot is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Polkadot is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Polkadot. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Validator primitives.
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
use bytes;
|
||||
use bytes::Vec;
|
||||
use parachain;
|
||||
|
||||
/// Parachain outgoing message.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct EgressPost(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
/// Balance upload.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct BalanceUpload(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
/// Balance download.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
pub struct BalanceDownload(#[cfg_attr(feature = "std", serde(with="bytes"))] pub Vec<u8>);
|
||||
|
||||
/// The result of parachain validation.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "std", derive(Serialize, Deserialize))]
|
||||
#[cfg_attr(feature = "std", serde(rename_all = "camelCase"))]
|
||||
#[cfg_attr(feature = "std", serde(deny_unknown_fields))]
|
||||
pub struct ValidationResult {
|
||||
/// New head data that should be included in the relay chain state.
|
||||
pub head_data: parachain::HeadData,
|
||||
/// Outgoing messages (a vec for each parachain).
|
||||
pub egress_queues: Vec<Vec<EgressPost>>,
|
||||
/// Balance uploads
|
||||
pub balance_uploads: Vec<BalanceUpload>,
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use substrate_serializer as ser;
|
||||
|
||||
#[test]
|
||||
fn test_validation_result() {
|
||||
assert_eq!(ser::to_string_pretty(&ValidationResult {
|
||||
head_data: parachain::HeadData(vec![1]),
|
||||
egress_queues: vec![vec![EgressPost(vec![1])]],
|
||||
balance_uploads: vec![BalanceUpload(vec![2])],
|
||||
}), r#"{
|
||||
"headData": "0x01",
|
||||
"egressQueues": [
|
||||
[
|
||||
"0x01"
|
||||
]
|
||||
],
|
||||
"balanceUploads": [
|
||||
"0x02"
|
||||
]
|
||||
}"#);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user