diff --git a/polkadot/Cargo.lock b/polkadot/Cargo.lock index ddbf81ae78..228fa47636 100644 --- a/polkadot/Cargo.lock +++ b/polkadot/Cargo.lock @@ -704,17 +704,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "bp-kusama" -version = "0.1.0" -dependencies = [ - "bp-messages", - "bp-polkadot-core", - "bp-runtime", - "sp-api", - "sp-std", -] - [[package]] name = "bp-messages" version = "0.1.0" @@ -726,17 +715,6 @@ dependencies = [ "sp-std", ] -[[package]] -name = "bp-polkadot" -version = "0.1.0" -dependencies = [ - "bp-messages", - "bp-polkadot-core", - "bp-runtime", - "sp-api", - "sp-std", -] - [[package]] name = "bp-polkadot-core" version = "0.1.0" @@ -800,7 +778,7 @@ dependencies = [ ] [[package]] -name = "bp-westend" +name = "bp-wococo" version = "0.1.0" dependencies = [ "bp-header-chain", @@ -4561,6 +4539,28 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-bridge-grandpa" +version = "0.1.0" +dependencies = [ + "bp-header-chain", + "bp-runtime", + "bp-test-utils", + "finality-grandpa", + "frame-benchmarking", + "frame-support", + "frame-system", + "log", + "num-traits", + "parity-scale-codec", + "serde", + "sp-finality-grandpa", + "sp-io", + "sp-runtime", + "sp-std", + "sp-trie", +] + [[package]] name = "pallet-collective" version = "3.0.0" @@ -7417,6 +7417,8 @@ name = "rococo-runtime" version = "0.9.1" dependencies = [ "beefy-primitives", + "bp-rococo", + "bp-wococo", "frame-executive", "frame-support", "frame-system", @@ -7428,6 +7430,7 @@ dependencies = [ "pallet-babe", "pallet-balances", "pallet-beefy", + "pallet-bridge-grandpa", "pallet-collective", "pallet-grandpa", "pallet-im-online", diff --git a/polkadot/Cargo.toml b/polkadot/Cargo.toml index 88584c77fb..6143ebf99d 100644 --- a/polkadot/Cargo.toml +++ b/polkadot/Cargo.toml @@ -26,11 +26,6 @@ tempfile = "3.2.0" [workspace] members = [ - "bridges/primitives/chain-kusama", - "bridges/primitives/chain-polkadot", - "bridges/primitives/chain-rococo", - "bridges/primitives/chain-westend", - "bridges/primitives/runtime", "cli", "core-primitives", "erasure-coding", diff --git a/polkadot/node/service/src/chain_spec.rs b/polkadot/node/service/src/chain_spec.rs index 6d6900f12b..278724746b 100644 --- a/polkadot/node/service/src/chain_spec.rs +++ b/polkadot/node/service/src/chain_spec.rs @@ -923,6 +923,14 @@ fn rococo_staging_testnet_config_genesis(wasm_binary: &[u8]) -> rococo_runtime:: ..Default::default() }, }, + pallet_bridge_grandpa: rococo_runtime::BridgeRococoGrandpaConfig { + owner: Some(endowed_accounts[0].clone()), + ..Default::default() + }, + pallet_bridge_grandpa_Instance1: rococo_runtime::BridgeWococoGrandpaConfig { + owner: Some(endowed_accounts[0].clone()), + ..Default::default() + }, } } @@ -1431,7 +1439,7 @@ pub fn rococo_testnet_genesis( pallet_authority_discovery: rococo_runtime::AuthorityDiscoveryConfig { keys: vec![], }, - pallet_sudo: rococo_runtime::SudoConfig { key: root_key }, + pallet_sudo: rococo_runtime::SudoConfig { key: root_key.clone() }, parachains_configuration: rococo_runtime::ParachainsConfigurationConfig { config: polkadot_runtime_parachains::configuration::HostConfiguration { validation_upgrade_frequency: 600u32, @@ -1479,6 +1487,14 @@ pub fn rococo_testnet_genesis( paras: vec![], _phdata: Default::default(), }, + pallet_bridge_grandpa: rococo_runtime::BridgeRococoGrandpaConfig { + owner: Some(root_key.clone()), + ..Default::default() + }, + pallet_bridge_grandpa_Instance1: rococo_runtime::BridgeWococoGrandpaConfig { + owner: Some(root_key.clone()), + ..Default::default() + }, } } diff --git a/polkadot/runtime/rococo/Cargo.toml b/polkadot/runtime/rococo/Cargo.toml index a9dd8078f6..06d31a80d9 100644 --- a/polkadot/runtime/rococo/Cargo.toml +++ b/polkadot/runtime/rococo/Cargo.toml @@ -68,6 +68,11 @@ xcm-executor = { package = "xcm-executor", path = "../../xcm/xcm-executor", defa xcm-builder = { package = "xcm-builder", path = "../../xcm/xcm-builder", default-features = false } pallet-xcm = { path = "../../xcm/pallet-xcm", default-features = false } +# Bridge Dependencies +bp-rococo = { path = "../../bridges/primitives/chain-rococo", default-features = false } +bp-wococo = { path = "../../bridges/primitives/chain-wococo", default-features = false } +pallet-bridge-grandpa = { path = "../../bridges/modules/grandpa", default-features = false } + [build-dependencies] substrate-wasm-builder = "3.0.0" @@ -77,6 +82,8 @@ no_std = [] std = [ "authority-discovery-primitives/std", "babe-primitives/std", + "bp-rococo/std", + "bp-wococo/std", "parity-scale-codec/std", "frame-executive/std", "pallet-authority-discovery/std", @@ -84,6 +91,7 @@ std = [ "pallet-babe/std", "beefy-primitives/std", "pallet-balances/std", + "pallet-bridge-grandpa/std", "pallet-collective/std", "pallet-beefy/std", "pallet-grandpa/std", diff --git a/polkadot/runtime/rococo/src/lib.rs b/polkadot/runtime/rococo/src/lib.rs index 6de4302b98..e2bd4a15c5 100644 --- a/polkadot/runtime/rococo/src/lib.rs +++ b/polkadot/runtime/rococo/src/lib.rs @@ -236,6 +236,12 @@ construct_runtime! { Beefy: pallet_beefy::{Pallet, Config, Storage}, MmrLeaf: mmr_common::{Pallet, Storage}, + // It might seem strange that we add both sides of the bridge to the same runtime. We do this because this + // runtime as shared by both the Rococo and Wococo chains. When running as Rococo we only use + // `BridgeWococoGrandpa`, and vice versa. + BridgeRococoGrandpa: pallet_bridge_grandpa::{Pallet, Call, Storage, Config} = 40, + BridgeWococoGrandpa: pallet_bridge_grandpa::::{Pallet, Call, Storage, Config} = 41, + // Validator Manager pallet. ValidatorManager: validator_manager::{Pallet, Call, Storage, Event}, @@ -794,6 +800,38 @@ impl mmr_common::Config for Runtime { type ParachainHeads = Paras; } +parameter_types! { + // This is a pretty unscientific cap. + // + // Note that once this is hit the pallet will essentially throttle incoming requests down to one + // call per block. + pub const MaxRequests: u32 = 4 * HOURS as u32; + + // Number of headers to keep. + // + // Assuming the worst case of every header being finalized, we will keep headers at least for a + // week. + pub const HeadersToKeep: u32 = 7 * DAYS as u32; +} + +pub type RococoGrandpaInstance = (); +impl pallet_bridge_grandpa::Config for Runtime { + type BridgedChain = bp_rococo::Rococo; + type MaxRequests = MaxRequests; + type HeadersToKeep = HeadersToKeep; + + type WeightInfo = pallet_bridge_grandpa::weights::RialtoWeight; +} + +pub type WococoGrandpaInstance = pallet_bridge_grandpa::Instance1; +impl pallet_bridge_grandpa::Config for Runtime { + type BridgedChain = bp_wococo::Wococo; + type MaxRequests = MaxRequests; + type HeadersToKeep = HeadersToKeep; + + type WeightInfo = pallet_bridge_grandpa::weights::RialtoWeight; +} + impl Randomness for ParentHashRandomness { fn random(subject: &[u8]) -> (Hash, BlockNumber) { ( @@ -1222,6 +1260,28 @@ sp_api::impl_runtime_apis! { } } + impl bp_rococo::RococoFinalityApi for Runtime { + fn best_finalized() -> (bp_rococo::BlockNumber, bp_rococo::Hash) { + let header = BridgeRococoGrandpa::best_finalized(); + (header.number, header.hash()) + } + + fn is_known_header(hash: bp_rococo::Hash) -> bool { + BridgeRococoGrandpa::is_known_header(hash) + } + } + + impl bp_wococo::WococoFinalityApi for Runtime { + fn best_finalized() -> (bp_wococo::BlockNumber, bp_wococo::Hash) { + let header = BridgeWococoGrandpa::best_finalized(); + (header.number, header.hash()) + } + + fn is_known_header(hash: bp_wococo::Hash) -> bool { + BridgeWococoGrandpa::is_known_header(hash) + } + } + impl frame_system_rpc_runtime_api::AccountNonceApi for Runtime { fn account_nonce(account: AccountId) -> Nonce { System::account_nonce(account)