Skip to content
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,660 changes: 1,737 additions & 1,923 deletions Cargo.lock

Large diffs are not rendered by default.

449 changes: 226 additions & 223 deletions Cargo.toml

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion bin/millau/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ license = "GPL-3.0-or-later WITH Classpath-exception-2.0"

[dependencies]
clap = { version = "3.1", features = ["derive"] }
jsonrpc-core = "18.0"
jsonrpsee = { version = "0.15.1", features = ["server"] }
serde_json = "1.0.79"

# Bridge dependencies
Expand Down
96 changes: 45 additions & 51 deletions bin/millau/node/src/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,7 @@

//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.

// =====================================================================================
// =====================================================================================
// =====================================================================================
// UPDATE GUIDE:
// 1) replace everything with node-template/src/service.rs contents (found in main Substrate repo);
// 2) from old code keep `rpc_extensions_builder` - we use our own custom RPCs;
// 3) from old code keep the Beefy gadget;
// 4) fix compilation errors;
// 5) test :)
// =====================================================================================
// =====================================================================================
// =====================================================================================

use jsonrpsee::RpcModule;
use millau_runtime::{self, opaque::Block, RuntimeApi};
use sc_client_api::{BlockBackend, ExecutorProvider};
use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams};
Expand Down Expand Up @@ -83,6 +71,8 @@ pub fn new_partial(
FullSelectChain,
>,
sc_finality_grandpa::LinkHalf<Block, FullClient, FullSelectChain>,
beefy_gadget::BeefyVoterLinks<Block>,
beefy_gadget::BeefyRPCLinks<Block>,
Option<Telemetry>,
),
>,
Expand Down Expand Up @@ -140,11 +130,18 @@ pub fn new_partial(
telemetry.as_ref().map(|x| x.handle()),
)?;

let (beefy_block_import, beefy_voter_links, beefy_rpc_links) =
beefy_gadget::beefy_block_import_and_links(
grandpa_block_import.clone(),
backend.clone(),
client.clone(),
);

let slot_duration = sc_consensus_aura::slot_duration(&*client)?;

let import_queue =
sc_consensus_aura::import_queue::<AuraPair, _, _, _, _, _, _>(ImportQueueParams {
block_import: grandpa_block_import.clone(),
block_import: beefy_block_import,
justification_import: Some(Box::new(grandpa_block_import.clone())),
client: client.clone(),
create_inherent_data_providers: move |_, ()| async move {
Expand Down Expand Up @@ -175,7 +172,7 @@ pub fn new_partial(
keystore_container,
select_chain,
transaction_pool,
other: (grandpa_block_import, grandpa_link, telemetry),
other: (grandpa_block_import, grandpa_link, beefy_voter_links, beefy_rpc_links, telemetry),
})
}

Expand All @@ -196,7 +193,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
mut keystore_container,
select_chain,
transaction_pool,
other: (block_import, grandpa_link, mut telemetry),
other: (block_import, grandpa_link, beefy_voter_links, beefy_rpc_links, mut telemetry),
} = new_partial(&config)?;

if let Some(url) = &config.keystore_remote {
Expand Down Expand Up @@ -264,18 +261,16 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
let enable_grandpa = !config.disable_grandpa;
let prometheus_registry = config.prometheus_registry().cloned();
let shared_voter_state = SharedVoterState::empty();
let (beefy_commitment_link, beefy_commitment_stream) =
beefy_gadget::notification::BeefySignedCommitmentStream::<Block>::channel();
let (beefy_best_block_link, beefy_best_block_stream) =
beefy_gadget::notification::BeefyBestBlockStream::<Block>::channel();

let rpc_extensions_builder = {
use sc_finality_grandpa::FinalityProofProvider as GrandpaFinalityProofProvider;

use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApi};
use sc_finality_grandpa_rpc::{GrandpaApi, GrandpaRpcHandler};
use beefy_gadget_rpc::{Beefy, BeefyApiServer};
use pallet_mmr_rpc::{Mmr, MmrApiServer};
use pallet_transaction_payment_rpc::{TransactionPayment, TransactionPaymentApiServer};
use sc_finality_grandpa_rpc::{Grandpa, GrandpaApiServer};
use sc_rpc::DenyUnsafe;
use substrate_frame_rpc_system::{FullSystem, SystemApi};
use substrate_frame_rpc_system::{System, SystemApiServer};

let backend = backend.clone();
let client = client.clone();
Expand All @@ -291,33 +286,33 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
);

Box::new(move |_, subscription_executor: sc_rpc::SubscriptionTaskExecutor| {
let mut io = jsonrpc_core::IoHandler::default();
io.extend_with(SystemApi::to_delegate(FullSystem::new(
client.clone(),
pool.clone(),
DenyUnsafe::No,
)));
io.extend_with(TransactionPaymentApi::to_delegate(TransactionPayment::new(
client.clone(),
)));
io.extend_with(GrandpaApi::to_delegate(GrandpaRpcHandler::new(
shared_authority_set.clone(),
shared_voter_state.clone(),
justification_stream.clone(),
subscription_executor.clone(),
finality_proof_provider.clone(),
)));
io.extend_with(beefy_gadget_rpc::BeefyApi::to_delegate(
beefy_gadget_rpc::BeefyRpcHandler::<Block>::new(
beefy_commitment_stream.clone(),
beefy_best_block_stream.clone(),
let mut io = RpcModule::new(());
let map_err = |e| sc_service::Error::Other(format!("{}", e));
io.merge(System::new(client.clone(), pool.clone(), DenyUnsafe::No).into_rpc())
.map_err(map_err)?;
io.merge(TransactionPayment::new(client.clone()).into_rpc()).map_err(map_err)?;
io.merge(
Grandpa::new(
subscription_executor.clone(),
shared_authority_set.clone(),
shared_voter_state.clone(),
justification_stream.clone(),
finality_proof_provider.clone(),
)
.into_rpc(),
)
.map_err(map_err)?;
io.merge(
Beefy::<Block>::new(
beefy_rpc_links.from_voter_justif_stream.clone(),
beefy_rpc_links.from_voter_best_beefy_stream.clone(),
subscription_executor,
)
.map_err(|e| sc_service::Error::Other(format!("{}", e)))?,
));
io.extend_with(pallet_mmr_rpc::MmrApi::to_delegate(pallet_mmr_rpc::Mmr::new(
client.clone(),
)));
.map_err(|e| sc_service::Error::Other(format!("{}", e)))?
.into_rpc(),
)
.map_err(map_err)?;
io.merge(Mmr::new(client.clone()).into_rpc()).map_err(map_err)?;
Ok(io)
})
};
Expand All @@ -328,7 +323,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
keystore: keystore_container.sync_keystore(),
task_manager: &mut task_manager,
transaction_pool: transaction_pool.clone(),
rpc_extensions_builder,
rpc_builder: rpc_extensions_builder.clone(),
backend: backend.clone(),
system_rpc_tx,
config,
Expand Down Expand Up @@ -397,11 +392,10 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
runtime: client,
key_store: keystore.clone(),
network: network.clone(),
signed_commitment_sender: beefy_commitment_link,
beefy_best_block_sender: beefy_best_block_link,
min_block_delta: 2,
prometheus_registry: prometheus_registry.clone(),
protocol_name: beefy_protocol_name,
links: beefy_voter_links,
};

// Start the BEEFY bridge gadget.
Expand Down
54 changes: 47 additions & 7 deletions bin/millau/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ use codec::Decode;
use pallet_grandpa::{
fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList,
};
use pallet_mmr::primitives as mmr;
use pallet_transaction_payment::{FeeDetails, Multiplier, RuntimeDispatchInfo};
use sp_api::impl_runtime_apis;
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
Expand Down Expand Up @@ -238,6 +239,8 @@ impl pallet_aura::Config for Runtime {

impl pallet_beefy::Config for Runtime {
type BeefyId = BeefyId;
type MaxAuthorities = MaxAuthorities;
type OnNewValidatorSet = MmrLeaf;
}

impl pallet_grandpa::Config for Runtime {
Expand All @@ -257,6 +260,7 @@ impl pallet_grandpa::Config for Runtime {
}

type MmrHash = <Keccak256 as sp_runtime::traits::Hash>::Output;
type MmrHashing = <Runtime as pallet_mmr::Config>::Hashing;

impl pallet_mmr::Config for Runtime {
const INDEXING_PREFIX: &'static [u8] = b"mmr";
Expand Down Expand Up @@ -355,6 +359,7 @@ impl pallet_transaction_payment::Config for Runtime {
AdjustmentVariable,
MinimumMultiplier,
>;
type Event = Event;
}

impl pallet_sudo::Config for Runtime {
Expand Down Expand Up @@ -562,7 +567,7 @@ construct_runtime!(

Timestamp: pallet_timestamp::{Pallet, Call, Storage, Inherent},
Balances: pallet_balances::{Pallet, Call, Storage, Config<T>, Event<T>},
TransactionPayment: pallet_transaction_payment::{Pallet, Storage},
TransactionPayment: pallet_transaction_payment::{Pallet, Storage, Event<T>},

// Consensus support.
Session: pallet_session::{Pallet, Call, Storage, Event, Config<T>},
Expand Down Expand Up @@ -748,37 +753,72 @@ impl_runtime_apis! {
fn generate_proof(leaf_index: u64)
-> Result<(EncodableOpaqueLeaf, MmrProof<MmrHash>), MmrError>
{
Mmr::generate_proof(leaf_index)
.map(|(leaf, proof)| (EncodableOpaqueLeaf::from_leaf(&leaf), proof))
Mmr::generate_batch_proof(vec![leaf_index])
.and_then(|(leaves, proof)| Ok((
mmr::EncodableOpaqueLeaf::from_leaf(&leaves[0]),
mmr::BatchProof::into_single_leaf_proof(proof)?
)))
}

fn verify_proof(leaf: EncodableOpaqueLeaf, proof: MmrProof<MmrHash>)
-> Result<(), MmrError>
{
pub type Leaf = <
type Leaf = <
<Runtime as pallet_mmr::Config>::LeafData as LeafDataProvider
>::LeafData;

let leaf: Leaf = leaf
.into_opaque_leaf()
.try_decode()
.ok_or(MmrError::Verify)?;
Mmr::verify_leaf(leaf, proof)
Mmr::verify_leaves(vec![leaf], mmr::Proof::into_batch_proof(proof))
}

fn verify_proof_stateless(
root: MmrHash,
leaf: EncodableOpaqueLeaf,
proof: MmrProof<MmrHash>
) -> Result<(), MmrError> {
type MmrHashing = <Runtime as pallet_mmr::Config>::Hashing;
let node = DataOrHash::Data(leaf.into_opaque_leaf());
pallet_mmr::verify_leaf_proof::<MmrHashing, _>(root, node, proof)
pallet_mmr::verify_leaves_proof::<MmrHashing, _>(
root,
vec![node],
pallet_mmr::primitives::Proof::into_batch_proof(proof),
)
}

fn mmr_root() -> Result<MmrHash, MmrError> {
Ok(Mmr::mmr_root())
}

fn generate_batch_proof(leaf_indices: Vec<pallet_mmr::primitives::LeafIndex>)
-> Result<(Vec<mmr::EncodableOpaqueLeaf>, mmr::BatchProof<MmrHash>), mmr::Error>
{
Mmr::generate_batch_proof(leaf_indices)
.map(|(leaves, proof)| (leaves.into_iter().map(|leaf| mmr::EncodableOpaqueLeaf::from_leaf(&leaf)).collect(), proof))
}

fn verify_batch_proof(leaves: Vec<mmr::EncodableOpaqueLeaf>, proof: mmr::BatchProof<MmrHash>)
-> Result<(), mmr::Error>
{
type Leaf = <
<Runtime as pallet_mmr::Config>::LeafData as LeafDataProvider
>::LeafData;
let leaves = leaves.into_iter().map(|leaf|
leaf.into_opaque_leaf()
.try_decode()
.ok_or(mmr::Error::Verify)).collect::<Result<Vec<Leaf>, mmr::Error>>()?;
Mmr::verify_leaves(leaves, proof)
}

fn verify_batch_proof_stateless(
root: MmrHash,
leaves: Vec<mmr::EncodableOpaqueLeaf>,
proof: mmr::BatchProof<MmrHash>
) -> Result<(), mmr::Error> {
let nodes = leaves.into_iter().map(|leaf|mmr::DataOrHash::Data(leaf.into_opaque_leaf())).collect();
pallet_mmr::verify_leaves_proof::<MmrHashing, _>(root, nodes, proof)
}
}

impl fg_primitives::GrandpaApi<Block> for Runtime {
Expand Down
3 changes: 2 additions & 1 deletion bin/millau/runtime/src/xcm_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,7 @@ impl xcm_executor::Config for XcmConfig {
type FeeManager = ();
type MessageExporter = ();
type UniversalAliases = Nothing;
type CallDispatcher = Call;
}

/// Type to convert an `Origin` type value into a `MultiLocation` value which represents an interior
Expand Down Expand Up @@ -270,7 +271,7 @@ mod tests {
fn xcm_messages_are_sent_using_bridge_router() {
new_test_ext().execute_with(|| {
let xcm: Xcm<()> = vec![Instruction::Trap(42)].into();
let expected_fee = MultiAssets::from((Here, 4_345_002_552_u64));
let expected_fee = MultiAssets::from((Here, 4_259_858_152_u64));
let expected_hash =
([0u8, 0u8, 0u8, 0u8], 1u64).using_encoded(sp_io::hashing::blake2_256);

Expand Down
2 changes: 1 addition & 1 deletion bin/rialto-parachain/node/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ bp-rialto-parachain = { path = "../../../primitives/chain-rialto-parachain" }
pallet-bridge-messages = { path = "../../../modules/messages" }

# RPC related Dependencies
jsonrpc-core = '18.0'
jsonrpsee = { version = "0.15.1", features = ["server"] }

# Local Dependencies
rialto-parachain-runtime = { path = '../runtime' }
Expand Down
4 changes: 2 additions & 2 deletions bin/rialto-parachain/node/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ pub enum Subcommand {
#[derive(Debug, Parser)]
pub struct ExportGenesisStateCommand {
/// Output file name or stdout if unspecified.
#[clap(parse(from_os_str))]
#[clap(action)]
pub output: Option<PathBuf>,

/// Id of the parachain this state is for.
Expand All @@ -81,7 +81,7 @@ pub struct ExportGenesisStateCommand {
#[derive(Debug, Parser)]
pub struct ExportGenesisWasmCommand {
/// Output file name or stdout if unspecified.
#[clap(parse(from_os_str))]
#[clap(action)]
pub output: Option<PathBuf>,

/// Write output in binary. Default is to write in hex.
Expand Down
Loading