mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-04-28 22:37:57 +00:00
Rococo (mocky)Runtime and Client (#841)
* Implement fake rococo runtime. * Generate correct storage key. * cargo fmt --all * Move client-rococo. * Satisfy clippy. * Apply suggestions from code review Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com> * Address review comments. * Clippy again. Co-authored-by: Hernando Castano <HCastano@users.noreply.github.com>
This commit is contained in:
committed by
Bastian Köcher
parent
60c1c24784
commit
51fc83941b
@@ -7,6 +7,7 @@ edition = "2018"
|
||||
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
||||
|
||||
[dependencies]
|
||||
parity-scale-codec = { version = "2.0.0", default-features = false, features = ["derive"] }
|
||||
|
||||
# Bridge Dependencies
|
||||
bp-messages = { path = "../messages", default-features = false }
|
||||
@@ -14,8 +15,14 @@ bp-polkadot-core = { path = "../polkadot-core", default-features = false }
|
||||
bp-runtime = { path = "../runtime", default-features = false }
|
||||
|
||||
# Substrate Based Dependencies
|
||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" , default-features = false }
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
hex = "0.4"
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
@@ -23,6 +30,10 @@ std = [
|
||||
"bp-messages/std",
|
||||
"bp-polkadot-core/std",
|
||||
"bp-runtime/std",
|
||||
"frame-support/std",
|
||||
"parity-scale-codec/std",
|
||||
"sp-api/std",
|
||||
"sp-runtime/std",
|
||||
"sp-std/std",
|
||||
"sp-version/std",
|
||||
]
|
||||
|
||||
@@ -21,10 +21,60 @@
|
||||
#![allow(clippy::unnecessary_mut_passed)]
|
||||
|
||||
use bp_messages::{LaneId, MessageNonce, UnrewardedRelayersState, Weight};
|
||||
use frame_support::{Blake2_128Concat, StorageHasher, Twox128};
|
||||
use sp_std::prelude::*;
|
||||
use sp_version::RuntimeVersion;
|
||||
|
||||
pub use bp_polkadot_core::*;
|
||||
|
||||
pub type UncheckedExtrinsic = bp_polkadot_core::UncheckedExtrinsic<Call>;
|
||||
|
||||
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
spec_name: sp_version::create_runtime_str!("rococo"),
|
||||
impl_name: sp_version::create_runtime_str!("parity-rococo-v1-1"),
|
||||
authoring_version: 0,
|
||||
spec_version: 30,
|
||||
impl_version: 0,
|
||||
apis: sp_version::create_apis_vec![[]],
|
||||
transaction_version: 6,
|
||||
};
|
||||
|
||||
#[derive(parity_scale_codec::Encode, parity_scale_codec::Decode, Debug, PartialEq, Eq, Clone)]
|
||||
pub enum Call {
|
||||
MockModule,
|
||||
}
|
||||
|
||||
impl sp_runtime::traits::Dispatchable for Call {
|
||||
type Origin = ();
|
||||
type Config = ();
|
||||
type Info = ();
|
||||
type PostInfo = ();
|
||||
|
||||
fn dispatch(self, _origin: Self::Origin) -> sp_runtime::DispatchResultWithInfo<Self::PostInfo> {
|
||||
unimplemented!("The Call is not expected to be dispatched.")
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a storage key for account data.
|
||||
///
|
||||
/// This is based on FRAME storage-generation code from Substrate:
|
||||
/// https://github.com/paritytech/substrate/blob/c939ceba381b6313462d47334f775e128ea4e95d/frame/support/src/storage/generator/map.rs#L74
|
||||
/// The equivalent command to invoke in case full `Runtime` is known is this:
|
||||
/// `let key = frame_system::Account::<Runtime>::storage_map_final_key(&account_id);`
|
||||
pub fn account_info_storage_key(id: &AccountId) -> Vec<u8> {
|
||||
let module_prefix_hashed = Twox128::hash(b"System");
|
||||
let storage_prefix_hashed = Twox128::hash(b"Account");
|
||||
let key_hashed = parity_scale_codec::Encode::using_encoded(id, Blake2_128Concat::hash);
|
||||
|
||||
let mut final_key = Vec::with_capacity(module_prefix_hashed.len() + storage_prefix_hashed.len() + key_hashed.len());
|
||||
|
||||
final_key.extend_from_slice(&module_prefix_hashed[..]);
|
||||
final_key.extend_from_slice(&storage_prefix_hashed[..]);
|
||||
final_key.extend_from_slice(&key_hashed);
|
||||
|
||||
final_key
|
||||
}
|
||||
|
||||
/// Rococo Chain
|
||||
pub type Rococo = PolkadotLike;
|
||||
|
||||
@@ -115,3 +165,19 @@ sp_api::decl_runtime_apis! {
|
||||
fn unrewarded_relayers_state(lane: LaneId) -> UnrewardedRelayersState;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn should_generate_storage_key() {
|
||||
let acc = [
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
|
||||
30, 31, 32,
|
||||
]
|
||||
.into();
|
||||
let key = account_info_storage_key(&acc);
|
||||
assert_eq!(hex::encode(key), "26aa394eea5630e07c48ae0c9558cef7b99d880ec681799c0cf30e8886371da92dccd599abfe1920a1cff8a7358231430102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ edition = "2018"
|
||||
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
||||
|
||||
[dependencies]
|
||||
parity-scale-codec = { version = "2.0.0", default-features = false, features = ["derive"] }
|
||||
|
||||
# Bridge Dependencies
|
||||
|
||||
@@ -21,6 +22,7 @@ sp-api = { git = "https://github.com/paritytech/substrate", branch = "master" ,
|
||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
sp-std = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
@@ -29,8 +31,10 @@ std = [
|
||||
"bp-runtime/std",
|
||||
"frame-support/std",
|
||||
"frame-system/std",
|
||||
"parity-scale-codec/std",
|
||||
"sp-api/std",
|
||||
"sp-core/std",
|
||||
"sp-runtime/std",
|
||||
"sp-std/std",
|
||||
"sp-version/std",
|
||||
]
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
use bp_messages::MessageNonce;
|
||||
use bp_runtime::Chain;
|
||||
use frame_support::{
|
||||
dispatch::Dispatchable,
|
||||
parameter_types,
|
||||
weights::{
|
||||
constants::{BlockExecutionWeight, ExtrinsicBaseWeight, WEIGHT_PER_SECOND},
|
||||
@@ -31,7 +32,7 @@ use sp_core::Hasher as HasherT;
|
||||
use sp_runtime::{
|
||||
generic,
|
||||
traits::{BlakeTwo256, IdentifyAccount, Verify},
|
||||
MultiSignature, OpaqueExtrinsic as UncheckedExtrinsic, Perbill,
|
||||
MultiSignature, OpaqueExtrinsic, Perbill,
|
||||
};
|
||||
|
||||
// Re-export's to avoid extra substrate dependencies in chain-specific crates.
|
||||
@@ -141,6 +142,12 @@ pub type BlockNumber = u32;
|
||||
/// Hash type used in Polkadot-like chains.
|
||||
pub type Hash = <BlakeTwo256 as HasherT>::Out;
|
||||
|
||||
/// Account Index (a.k.a. nonce).
|
||||
pub type Index = u32;
|
||||
|
||||
/// Hashing type.
|
||||
pub type Hashing = BlakeTwo256;
|
||||
|
||||
/// The type of an object that can produce hashes on Polkadot-like chains.
|
||||
pub type Hasher = BlakeTwo256;
|
||||
|
||||
@@ -160,7 +167,7 @@ pub type AccountId = <AccountPublic as IdentifyAccount>::AccountId;
|
||||
pub type Nonce = u32;
|
||||
|
||||
/// Block type of Polkadot-like chains.
|
||||
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
pub type Block = generic::Block<Header, OpaqueExtrinsic>;
|
||||
|
||||
/// Polkadot-like block signed with a Justification.
|
||||
pub type SignedBlock = generic::SignedBlock<Block>;
|
||||
@@ -168,6 +175,86 @@ pub type SignedBlock = generic::SignedBlock<Block>;
|
||||
/// The balance of an account on Polkadot-like chain.
|
||||
pub type Balance = u128;
|
||||
|
||||
/// Unchecked Extrinsic type.
|
||||
pub type UncheckedExtrinsic<Call> = generic::UncheckedExtrinsic<AccountId, Call, Signature, SignedExtensions<Call>>;
|
||||
|
||||
/// A type of the data encoded as part of the transaction.
|
||||
pub type SignedExtra = ((), (), (), sp_runtime::generic::Era, Nonce, (), Balance);
|
||||
|
||||
/// Parameters which are part of the payload used to produce transaction signature,
|
||||
/// but don't end up in the transaction itself (i.e. inherent part of the runtime).
|
||||
pub type AdditionalSigned = (u32, u32, Hash, Hash, (), (), ());
|
||||
|
||||
/// A simplified version of signed extensions meant for producing signed transactions
|
||||
/// and signed payload in the client code.
|
||||
#[derive(PartialEq, Eq, Clone, RuntimeDebug)]
|
||||
pub struct SignedExtensions<Call> {
|
||||
encode_payload: SignedExtra,
|
||||
additional_signed: AdditionalSigned,
|
||||
_data: sp_std::marker::PhantomData<Call>,
|
||||
}
|
||||
|
||||
impl<Call> parity_scale_codec::Encode for SignedExtensions<Call> {
|
||||
fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
|
||||
self.encode_payload.using_encoded(f)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Call> parity_scale_codec::Decode for SignedExtensions<Call> {
|
||||
fn decode<I: parity_scale_codec::Input>(_input: &mut I) -> Result<Self, parity_scale_codec::Error> {
|
||||
unimplemented!("SignedExtensions are never meant to be decoded, they are only used to create transaction");
|
||||
}
|
||||
}
|
||||
|
||||
impl<Call> SignedExtensions<Call> {
|
||||
pub fn new(
|
||||
version: sp_version::RuntimeVersion,
|
||||
era: sp_runtime::generic::Era,
|
||||
genesis_hash: Hash,
|
||||
nonce: Nonce,
|
||||
tip: Balance,
|
||||
) -> Self {
|
||||
Self {
|
||||
encode_payload: (
|
||||
(), // spec version
|
||||
(), // tx version
|
||||
(), // genesis
|
||||
era, // era
|
||||
nonce, // nonce (compact encoding)
|
||||
(), // Check weight
|
||||
tip, // transaction payment / tip (compact encoding)
|
||||
),
|
||||
additional_signed: (
|
||||
version.spec_version,
|
||||
version.transaction_version,
|
||||
genesis_hash,
|
||||
genesis_hash,
|
||||
(),
|
||||
(),
|
||||
(),
|
||||
),
|
||||
_data: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<Call> sp_runtime::traits::SignedExtension for SignedExtensions<Call>
|
||||
where
|
||||
Call: parity_scale_codec::Codec + sp_std::fmt::Debug + Sync + Send + Clone + Eq + PartialEq,
|
||||
Call: Dispatchable,
|
||||
{
|
||||
const IDENTIFIER: &'static str = "Not needed.";
|
||||
|
||||
type AccountId = AccountId;
|
||||
type Call = Call;
|
||||
type AdditionalSigned = AdditionalSigned;
|
||||
type Pre = ();
|
||||
|
||||
fn additional_signed(&self) -> Result<Self::AdditionalSigned, frame_support::unsigned::TransactionValidityError> {
|
||||
Ok(self.additional_signed)
|
||||
}
|
||||
}
|
||||
|
||||
/// Polkadot-like chain.
|
||||
#[derive(RuntimeDebug)]
|
||||
pub struct PolkadotLike;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
[package]
|
||||
name = "relay-rococo-client"
|
||||
version = "0.1.0"
|
||||
authors = ["Parity Technologies <admin@parity.io>"]
|
||||
edition = "2018"
|
||||
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
|
||||
|
||||
[dependencies]
|
||||
codec = { package = "parity-scale-codec", version = "2.0.0" }
|
||||
headers-relay = { path = "../headers" }
|
||||
relay-substrate-client = { path = "../client-substrate" }
|
||||
relay-utils = { path = "../utils" }
|
||||
|
||||
# Bridge dependencies
|
||||
bp-rococo = { path = "../../primitives/chain-rococo" }
|
||||
|
||||
# Substrate Dependencies
|
||||
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-core = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-keyring = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
sp-runtime = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
@@ -0,0 +1,116 @@
|
||||
// Parity Bridges Common 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.
|
||||
|
||||
// Parity Bridges Common 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 Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Types used to connect to the Rococo-Substrate chain.
|
||||
|
||||
use codec::Encode;
|
||||
use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, TransactionSignScheme};
|
||||
use sp_core::{storage::StorageKey, Pair};
|
||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
||||
use std::time::Duration;
|
||||
|
||||
/// Rococo header id.
|
||||
pub type HeaderId = relay_utils::HeaderId<bp_rococo::Hash, bp_rococo::BlockNumber>;
|
||||
|
||||
/// Rococo chain definition
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Rococo;
|
||||
|
||||
impl ChainBase for Rococo {
|
||||
type BlockNumber = bp_rococo::BlockNumber;
|
||||
type Hash = bp_rococo::Hash;
|
||||
type Hasher = bp_rococo::Hashing;
|
||||
type Header = bp_rococo::Header;
|
||||
}
|
||||
|
||||
impl Chain for Rococo {
|
||||
const NAME: &'static str = "Rococo";
|
||||
const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6);
|
||||
|
||||
type AccountId = bp_rococo::AccountId;
|
||||
type Index = bp_rococo::Index;
|
||||
type SignedBlock = bp_rococo::SignedBlock;
|
||||
type Call = bp_rococo::Call;
|
||||
}
|
||||
|
||||
impl ChainWithBalances for Rococo {
|
||||
type NativeBalance = bp_rococo::Balance;
|
||||
|
||||
fn account_info_storage_key(account_id: &Self::AccountId) -> StorageKey {
|
||||
StorageKey(bp_rococo::account_info_storage_key(account_id))
|
||||
}
|
||||
}
|
||||
|
||||
impl TransactionSignScheme for Rococo {
|
||||
type Chain = Rococo;
|
||||
type AccountKeyPair = sp_core::sr25519::Pair;
|
||||
type SignedTransaction = bp_rococo::UncheckedExtrinsic;
|
||||
|
||||
fn sign_transaction(
|
||||
genesis_hash: <Self::Chain as ChainBase>::Hash,
|
||||
signer: &Self::AccountKeyPair,
|
||||
signer_nonce: <Self::Chain as Chain>::Index,
|
||||
call: <Self::Chain as Chain>::Call,
|
||||
) -> Self::SignedTransaction {
|
||||
let raw_payload = SignedPayload::new(
|
||||
call,
|
||||
bp_rococo::SignedExtensions::new(
|
||||
bp_rococo::VERSION,
|
||||
sp_runtime::generic::Era::Immortal,
|
||||
genesis_hash,
|
||||
signer_nonce,
|
||||
0,
|
||||
),
|
||||
)
|
||||
.expect("SignedExtension never fails.");
|
||||
|
||||
let signature = raw_payload.using_encoded(|payload| signer.sign(payload));
|
||||
let signer: sp_runtime::MultiSigner = signer.public().into();
|
||||
let (call, extra, _) = raw_payload.deconstruct();
|
||||
|
||||
bp_rococo::UncheckedExtrinsic::new_signed(call, signer.into_account(), signature.into(), extra)
|
||||
}
|
||||
}
|
||||
|
||||
/// Rococo signing params.
|
||||
#[derive(Clone)]
|
||||
pub struct SigningParams {
|
||||
/// Substrate transactions signer.
|
||||
pub signer: sp_core::sr25519::Pair,
|
||||
}
|
||||
|
||||
impl SigningParams {
|
||||
/// Create signing params from SURI and password.
|
||||
pub fn from_suri(suri: &str, password: Option<&str>) -> Result<Self, sp_core::crypto::SecretStringError> {
|
||||
Ok(SigningParams {
|
||||
signer: sp_core::sr25519::Pair::from_string(suri, password)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for SigningParams {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
write!(f, "{}", self.signer.public())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for SigningParams {
|
||||
fn default() -> Self {
|
||||
SigningParams {
|
||||
signer: sp_keyring::AccountKeyring::Alice.pair(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Rococo header type used in headers sync.
|
||||
pub type SyncHeader = relay_substrate_client::SyncHeader<bp_rococo::Header>;
|
||||
Reference in New Issue
Block a user