Skip to content

Commit 8c8d6d4

Browse files
authored
Integrate BEEFY with Rialto & Millau runtimes (paritytech#1227)
* Add Beefy pallet to Rialto runtime * Add Beefy gadget to Rialto node * Add MMR pallet to Rialto runtime * Add Beefy pallet to Millau runtime * Add Beefy gadget to Millau node * Add MMR pallet to Millau runtime * Add pallet_beefy_mmr to Millau runtime * Add pallet_beefy_mmr to Rialto runtime * Implement MMR and BEEFY APIs in Rialto * fix unit tests - should_encode_bridge_send_message_call() tests for new runtime encoding resulted from newly added pallets. - runtime size_of::<Call>() slightly increased from newly added pallets. * fix grumbles * tighten clippy allowances * fix more grumbles * Add MMR RPC to Rialto and Millau nodes Also implement MmrApi in Millau runtime. * rialto: use upstream polkadot_client::RuntimeApiCollection
1 parent e0d38b7 commit 8c8d6d4

File tree

11 files changed

+322
-86
lines changed

11 files changed

+322
-86
lines changed

bin/millau/node/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,13 @@ pallet-bridge-messages = { path = "../../../modules/messages" }
2323

2424
# Substrate Dependencies
2525

26+
beefy-gadget = { git = "https://github.com/paritytech/substrate", branch = "master" }
27+
beefy-gadget-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
28+
beefy-primitives = { git = "https://github.com/paritytech/substrate", branch = "master" }
2629
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master" }
2730
frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "master" }
2831
node-inspect = { git = "https://github.com/paritytech/substrate", branch = "master" }
32+
pallet-mmr-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
2933
pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
3034
sc-basic-authorship = { git = "https://github.com/paritytech/substrate", branch = "master" }
3135
sc-cli = { git = "https://github.com/paritytech/substrate", branch = "master", features = ["wasmtime"] }

bin/millau/node/src/chain_spec.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,12 @@
1414
// You should have received a copy of the GNU General Public License
1515
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
1616

17+
use beefy_primitives::crypto::AuthorityId as BeefyId;
1718
use bp_millau::derive_account_from_rialto_id;
1819
use millau_runtime::{
19-
AccountId, AuraConfig, BalancesConfig, BridgeRialtoMessagesConfig, BridgeWestendGrandpaConfig,
20-
GenesisConfig, GrandpaConfig, SessionConfig, SessionKeys, Signature, SudoConfig, SystemConfig,
21-
WASM_BINARY,
20+
AccountId, AuraConfig, BalancesConfig, BeefyConfig, BridgeRialtoMessagesConfig,
21+
BridgeWestendGrandpaConfig, GenesisConfig, GrandpaConfig, SessionConfig, SessionKeys,
22+
Signature, SudoConfig, SystemConfig, WASM_BINARY,
2223
};
2324
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
2425
use sp_core::{sr25519, Pair, Public};
@@ -57,10 +58,11 @@ where
5758
}
5859

5960
/// Helper function to generate an authority key for Aura
60-
pub fn get_authority_keys_from_seed(s: &str) -> (AccountId, AuraId, GrandpaId) {
61+
pub fn get_authority_keys_from_seed(s: &str) -> (AccountId, AuraId, BeefyId, GrandpaId) {
6162
(
6263
get_account_id_from_seed::<sr25519::Public>(s),
6364
get_from_seed::<AuraId>(s),
65+
get_from_seed::<BeefyId>(s),
6466
get_from_seed::<GrandpaId>(s),
6567
)
6668
}
@@ -173,12 +175,12 @@ impl Alternative {
173175
}
174176
}
175177

176-
fn session_keys(aura: AuraId, grandpa: GrandpaId) -> SessionKeys {
177-
SessionKeys { aura, grandpa }
178+
fn session_keys(aura: AuraId, beefy: BeefyId, grandpa: GrandpaId) -> SessionKeys {
179+
SessionKeys { aura, beefy, grandpa }
178180
}
179181

180182
fn testnet_genesis(
181-
initial_authorities: Vec<(AccountId, AuraId, GrandpaId)>,
183+
initial_authorities: Vec<(AccountId, AuraId, BeefyId, GrandpaId)>,
182184
root_key: AccountId,
183185
endowed_accounts: Vec<AccountId>,
184186
_enable_println: bool,
@@ -191,12 +193,15 @@ fn testnet_genesis(
191193
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 50)).collect(),
192194
},
193195
aura: AuraConfig { authorities: Vec::new() },
196+
beefy: BeefyConfig { authorities: Vec::new() },
194197
grandpa: GrandpaConfig { authorities: Vec::new() },
195198
sudo: SudoConfig { key: root_key },
196199
session: SessionConfig {
197200
keys: initial_authorities
198201
.iter()
199-
.map(|x| (x.0.clone(), x.0.clone(), session_keys(x.1.clone(), x.2.clone())))
202+
.map(|x| {
203+
(x.0.clone(), x.0.clone(), session_keys(x.1.clone(), x.2.clone(), x.3.clone()))
204+
})
200205
.collect::<Vec<_>>(),
201206
},
202207
bridge_westend_grandpa: BridgeWestendGrandpaConfig {

bin/millau/node/src/service.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@
2121
// =====================================================================================
2222
// UPDATE GUIDE:
2323
// 1) replace everything with node-template/src/service.rs contents (found in main Substrate repo);
24-
// 2) the only thing to keep from old code, is `rpc_extensions_builder` - we use our own custom
25-
// RPCs; 3) fix compilation errors;
26-
// 4) test :)
24+
// 2) from old code keep `rpc_extensions_builder` - we use our own custom RPCs;
25+
// 3) from old code keep the Beefy gadget;
26+
// 4) fix compilation errors;
27+
// 5) test :)
2728
// =====================================================================================
2829
// =====================================================================================
2930
// =====================================================================================
@@ -209,6 +210,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
209210
}
210211

211212
config.network.extra_sets.push(sc_finality_grandpa::grandpa_peers_set_config());
213+
config.network.extra_sets.push(beefy_gadget::beefy_peers_set_config());
212214
let warp_sync = Arc::new(sc_finality_grandpa::warp_proof::NetworkProvider::new(
213215
backend.clone(),
214216
grandpa_link.shared_authority_set().clone(),
@@ -242,6 +244,8 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
242244
let enable_grandpa = !config.disable_grandpa;
243245
let prometheus_registry = config.prometheus_registry().cloned();
244246
let shared_voter_state = SharedVoterState::empty();
247+
let (signed_commitment_sender, signed_commitment_stream) =
248+
beefy_gadget::notification::BeefySignedCommitmentStream::channel();
245249

246250
let rpc_extensions_builder = {
247251
use sc_finality_grandpa::FinalityProofProvider as GrandpaFinalityProofProvider;
@@ -264,7 +268,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
264268
Some(shared_authority_set.clone()),
265269
);
266270

267-
Box::new(move |_, subscription_executor| {
271+
Box::new(move |_, subscription_executor: sc_rpc::SubscriptionTaskExecutor| {
268272
let mut io = jsonrpc_core::IoHandler::default();
269273
io.extend_with(SystemApi::to_delegate(FullSystem::new(
270274
client.clone(),
@@ -278,9 +282,18 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
278282
shared_authority_set.clone(),
279283
shared_voter_state.clone(),
280284
justification_stream.clone(),
281-
subscription_executor,
285+
subscription_executor.clone(),
282286
finality_proof_provider.clone(),
283287
)));
288+
io.extend_with(beefy_gadget_rpc::BeefyApi::to_delegate(
289+
beefy_gadget_rpc::BeefyRpcHandler::new(
290+
signed_commitment_stream.clone(),
291+
subscription_executor,
292+
),
293+
));
294+
io.extend_with(pallet_mmr_rpc::MmrApi::to_delegate(pallet_mmr_rpc::Mmr::new(
295+
client.clone(),
296+
)));
284297
Ok(io)
285298
})
286299
};
@@ -292,7 +305,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
292305
task_manager: &mut task_manager,
293306
transaction_pool: transaction_pool.clone(),
294307
rpc_extensions_builder,
295-
backend,
308+
backend: backend.clone(),
296309
system_rpc_tx,
297310
config,
298311
telemetry: telemetry.as_mut(),
@@ -355,6 +368,23 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
355368
let keystore =
356369
if role.is_authority() { Some(keystore_container.sync_keystore()) } else { None };
357370

371+
let beefy_params = beefy_gadget::BeefyParams {
372+
client,
373+
backend,
374+
key_store: keystore.clone(),
375+
network: network.clone(),
376+
signed_commitment_sender,
377+
min_block_delta: 4,
378+
prometheus_registry: prometheus_registry.clone(),
379+
};
380+
381+
// Start the BEEFY bridge gadget.
382+
task_manager.spawn_essential_handle().spawn_blocking(
383+
"beefy-gadget",
384+
None,
385+
beefy_gadget::start_beefy_gadget::<_, _, _, _>(beefy_params),
386+
);
387+
358388
let grandpa_config = sc_finality_grandpa::Config {
359389
// FIXME #1578 make this available through chainspec
360390
gossip_duration: Duration::from_millis(333),

bin/millau/runtime/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,19 @@ pallet-shift-session-manager = { path = "../../../modules/shift-session-manager"
3030

3131
# Substrate Dependencies
3232

33+
beefy-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
3334
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false, optional = true }
3435
frame-executive = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
3536
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
3637
frame-system = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
3738
frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
3839
pallet-aura = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
3940
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
41+
pallet-beefy = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
42+
pallet-beefy-mmr = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
4043
pallet-grandpa = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
44+
pallet-mmr = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
45+
pallet-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
4146
pallet-randomness-collective-flip = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
4247
pallet-session = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
4348
pallet-sudo = { git = "https://github.com/paritytech/substrate", branch = "master", default-features = false }
@@ -64,6 +69,7 @@ substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", bran
6469
[features]
6570
default = ["std"]
6671
std = [
72+
"beefy-primitives/std",
6773
"bp-header-chain/std",
6874
"bp-messages/std",
6975
"bp-millau/std",
@@ -78,11 +84,14 @@ std = [
7884
"frame-system/std",
7985
"pallet-aura/std",
8086
"pallet-balances/std",
87+
"pallet-beefy/std",
88+
"pallet-beefy-mmr/std",
8189
"pallet-bridge-dispatch/std",
8290
"pallet-bridge-grandpa/std",
8391
"pallet-bridge-messages/std",
8492
"pallet-bridge-token-swap/std",
8593
"pallet-grandpa/std",
94+
"pallet-mmr/std",
8695
"pallet-randomness-collective-flip/std",
8796
"pallet-session/std",
8897
"pallet-shift-session-manager/std",

bin/millau/runtime/src/lib.rs

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,19 +34,23 @@ pub mod rialto_messages;
3434

3535
use crate::rialto_messages::{ToRialtoMessagePayload, WithRialtoMessageBridge};
3636

37+
use beefy_primitives::{crypto::AuthorityId as BeefyId, mmr::MmrLeafVersion, ValidatorSet};
3738
use bridge_runtime_common::messages::{
3839
source::estimate_message_dispatch_and_delivery_fee, MessageBridge,
3940
};
4041
use pallet_grandpa::{
4142
fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList,
4243
};
44+
use pallet_mmr_primitives::{
45+
DataOrHash, EncodableOpaqueLeaf, Error as MmrError, LeafDataProvider, Proof as MmrProof,
46+
};
4347
use pallet_transaction_payment::{FeeDetails, Multiplier, RuntimeDispatchInfo};
4448
use sp_api::impl_runtime_apis;
4549
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
4650
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
4751
use sp_runtime::{
4852
create_runtime_str, generic, impl_opaque_keys,
49-
traits::{Block as BlockT, IdentityLookup, NumberFor, OpaqueKeys},
53+
traits::{Block as BlockT, IdentityLookup, Keccak256, NumberFor, OpaqueKeys},
5054
transaction_validity::{TransactionSource, TransactionValidity},
5155
ApplyExtrinsicResult, FixedPointNumber, MultiSignature, MultiSigner, Perquintill,
5256
};
@@ -120,6 +124,7 @@ pub mod opaque {
120124
impl_opaque_keys! {
121125
pub struct SessionKeys {
122126
pub aura: Aura,
127+
pub beefy: Beefy,
123128
pub grandpa: Grandpa,
124129
}
125130
}
@@ -212,6 +217,11 @@ impl pallet_aura::Config for Runtime {
212217
type MaxAuthorities = MaxAuthorities;
213218
type DisabledValidators = ();
214219
}
220+
221+
impl pallet_beefy::Config for Runtime {
222+
type BeefyId = BeefyId;
223+
}
224+
215225
impl pallet_bridge_dispatch::Config for Runtime {
216226
type Event = Event;
217227
type BridgeMessageId = (bp_messages::LaneId, bp_messages::MessageNonce);
@@ -240,6 +250,40 @@ impl pallet_grandpa::Config for Runtime {
240250
type MaxAuthorities = MaxAuthorities;
241251
}
242252

253+
type MmrHash = <Keccak256 as sp_runtime::traits::Hash>::Output;
254+
255+
impl pallet_mmr::Config for Runtime {
256+
const INDEXING_PREFIX: &'static [u8] = b"mmr";
257+
type Hashing = Keccak256;
258+
type Hash = MmrHash;
259+
type OnNewRoot = pallet_beefy_mmr::DepositBeefyDigest<Runtime>;
260+
type WeightInfo = ();
261+
type LeafData = pallet_beefy_mmr::Pallet<Runtime>;
262+
}
263+
264+
parameter_types! {
265+
/// Version of the produced MMR leaf.
266+
///
267+
/// The version consists of two parts;
268+
/// - `major` (3 bits)
269+
/// - `minor` (5 bits)
270+
///
271+
/// `major` should be updated only if decoding the previous MMR Leaf format from the payload
272+
/// is not possible (i.e. backward incompatible change).
273+
/// `minor` should be updated if fields are added to the previous MMR Leaf, which given SCALE
274+
/// encoding does not prevent old leafs from being decoded.
275+
///
276+
/// Hence we expect `major` to be changed really rarely (think never).
277+
/// See [`MmrLeafVersion`] type documentation for more details.
278+
pub LeafVersion: MmrLeafVersion = MmrLeafVersion::new(0, 0);
279+
}
280+
281+
impl pallet_beefy_mmr::Config for Runtime {
282+
type LeafVersion = LeafVersion;
283+
type BeefyAuthorityToMerkleLeaf = pallet_beefy_mmr::BeefyEcdsaToEthereum;
284+
type ParachainHeads = ();
285+
}
286+
243287
parameter_types! {
244288
pub const MinimumPeriod: u64 = bp_millau::SLOT_DURATION / 2;
245289
}
@@ -459,6 +503,11 @@ construct_runtime!(
459503
ShiftSessionManager: pallet_shift_session_manager::{Pallet},
460504
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Pallet, Storage},
461505

506+
// BEEFY Bridges support.
507+
Beefy: pallet_beefy::{Pallet, Storage, Config<T>},
508+
Mmr: pallet_mmr::{Pallet, Storage},
509+
MmrLeaf: pallet_beefy_mmr::{Pallet, Storage},
510+
462511
// Rialto bridge modules.
463512
BridgeRialtoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage},
464513
BridgeDispatch: pallet_bridge_dispatch::{Pallet, Event<T>},
@@ -603,6 +652,45 @@ impl_runtime_apis! {
603652
}
604653
}
605654

655+
impl beefy_primitives::BeefyApi<Block> for Runtime {
656+
fn validator_set() -> ValidatorSet<BeefyId> {
657+
Beefy::validator_set()
658+
}
659+
}
660+
661+
impl pallet_mmr_primitives::MmrApi<Block, MmrHash> for Runtime {
662+
fn generate_proof(leaf_index: u64)
663+
-> Result<(EncodableOpaqueLeaf, MmrProof<MmrHash>), MmrError>
664+
{
665+
Mmr::generate_proof(leaf_index)
666+
.map(|(leaf, proof)| (EncodableOpaqueLeaf::from_leaf(&leaf), proof))
667+
}
668+
669+
fn verify_proof(leaf: EncodableOpaqueLeaf, proof: MmrProof<MmrHash>)
670+
-> Result<(), MmrError>
671+
{
672+
pub type Leaf = <
673+
<Runtime as pallet_mmr::Config>::LeafData as LeafDataProvider
674+
>::LeafData;
675+
676+
let leaf: Leaf = leaf
677+
.into_opaque_leaf()
678+
.try_decode()
679+
.ok_or(MmrError::Verify)?;
680+
Mmr::verify_leaf(leaf, proof)
681+
}
682+
683+
fn verify_proof_stateless(
684+
root: MmrHash,
685+
leaf: EncodableOpaqueLeaf,
686+
proof: MmrProof<MmrHash>
687+
) -> Result<(), MmrError> {
688+
type MmrHashing = <Runtime as pallet_mmr::Config>::Hashing;
689+
let node = DataOrHash::Data(leaf.into_opaque_leaf());
690+
pallet_mmr::verify_leaf_proof::<MmrHashing, _>(root, node, proof)
691+
}
692+
}
693+
606694
impl fg_primitives::GrandpaApi<Block> for Runtime {
607695
fn current_set_id() -> fg_primitives::SetId {
608696
Grandpa::current_set_id()

bin/rialto/node/Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,15 @@ rialto-runtime = { path = "../runtime" }
2828

2929
# Substrate Dependencies
3030

31+
beefy-gadget = { git = "https://github.com/paritytech/substrate", branch = "master" }
32+
beefy-gadget-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
33+
beefy-primitives = { git = "https://github.com/paritytech/substrate", branch = "master" }
3134
frame-benchmarking = { git = "https://github.com/paritytech/substrate", branch = "master" }
3235
frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "master" }
3336
frame-system-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
3437
node-inspect = { git = "https://github.com/paritytech/substrate", branch = "master" }
38+
pallet-mmr-primitives = { git = "https://github.com/paritytech/substrate", branch = "master" }
39+
pallet-mmr-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
3540
pallet-transaction-payment-rpc = { git = "https://github.com/paritytech/substrate", branch = "master" }
3641
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
3742
sc-authority-discovery = { git = "https://github.com/paritytech/substrate", branch = "master" }
@@ -70,6 +75,10 @@ sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "mast
7075
substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "master" }
7176
substrate-prometheus-endpoint = { git = "https://github.com/paritytech/substrate", branch = "master" }
7277

78+
# Polkadot Dependencies
79+
80+
polkadot-client = { git = "https://github.com/paritytech/polkadot", branch = "master" }
81+
7382
# Polkadot (parachain) Dependencies
7483

7584
polkadot-approval-distribution = { git = "https://github.com/paritytech/polkadot", branch = "master" }

0 commit comments

Comments
 (0)