Skip to content

Commit

Permalink
Sync Westend to Millau (paritytech#824)
Browse files Browse the repository at this point in the history
* make finality verifier pallet instantiable

* add second instance of finality verifier pallet to the Millau runtime

* add Westend -> Millau headers relay

* use wss to connect to public westend nodes

* initialize with best_finalized_block

* typo

* Revert "initialize with best_finalized_block"

This reverts commit 954ed2832372d67618abc1a06d47e66faa93f674.

* pass VoterSet by ref

* new bridge initialization code

* loop upper bound

* Polkadot -> Westend

* fixed tests compilation

* default-features

* assert
  • Loading branch information
svyatonik authored and serban300 committed Apr 8, 2024
1 parent 9d725a1 commit 139b706
Show file tree
Hide file tree
Showing 18 changed files with 476 additions and 138 deletions.
2 changes: 2 additions & 0 deletions bridges/bin/millau/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ bp-message-lane = { path = "../../../primitives/message-lane", default-features
bp-millau = { path = "../../../primitives/chains/millau", default-features = false }
bp-rialto = { path = "../../../primitives/chains/rialto", default-features = false }
bp-runtime = { path = "../../../primitives/runtime", default-features = false }
bp-westend = { path = "../../../primitives/chains/westend", default-features = false }
bridge-runtime-common = { path = "../../runtime-common", default-features = false }
pallet-bridge-call-dispatch = { path = "../../../modules/call-dispatch", default-features = false }
pallet-finality-verifier = { path = "../../../modules/finality-verifier", default-features = false }
Expand Down Expand Up @@ -66,6 +67,7 @@ std = [
"bp-millau/std",
"bp-rialto/std",
"bp-runtime/std",
"bp-westend/std",
"bridge-runtime-common/std",
"codec/std",
"frame-executive/std",
Expand Down
26 changes: 23 additions & 3 deletions bridges/bin/millau/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub use frame_support::{
pub use frame_system::Call as SystemCall;
pub use pallet_balances::Call as BalancesCall;
pub use pallet_finality_verifier::Call as FinalityBridgeRialtoCall;
pub use pallet_finality_verifier::Call as FinalityBridgeWestendCall;
pub use pallet_message_lane::Call as MessageLaneCall;
pub use pallet_substrate_bridge::Call as BridgeRialtoCall;
pub use pallet_sudo::Call as SudoCall;
Expand Down Expand Up @@ -312,11 +313,18 @@ parameter_types! {
pub const MaxRequests: u32 = 50;
}

pub type RialtoFinalityVerifierInstance = ();
impl pallet_finality_verifier::Config for Runtime {
type BridgedChain = bp_rialto::Rialto;
type MaxRequests = MaxRequests;
}

pub type WestendFinalityVerifierInstance = pallet_finality_verifier::Instance1;
impl pallet_finality_verifier::Config<WestendFinalityVerifierInstance> for Runtime {
type BridgedChain = bp_westend::Westend;
type MaxRequests = MaxRequests;
}

impl pallet_shift_session_manager::Config for Runtime {}

parameter_types! {
Expand Down Expand Up @@ -371,7 +379,8 @@ construct_runtime!(
BridgeRialto: pallet_substrate_bridge::{Module, Call, Storage, Config<T>},
BridgeRialtoMessageLane: pallet_message_lane::{Module, Call, Storage, Event<T>},
BridgeCallDispatch: pallet_bridge_call_dispatch::{Module, Event<T>},
BridgeFinalityVerifier: pallet_finality_verifier::{Module, Call},
BridgeRialtoFinalityVerifier: pallet_finality_verifier::{Module, Call},
BridgeWestendFinalityVerifier: pallet_finality_verifier::<Instance1>::{Module, Call},
System: frame_system::{Module, Call, Config, Storage, Event<T>},
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},
Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},
Expand Down Expand Up @@ -572,12 +581,23 @@ impl_runtime_apis! {

impl bp_rialto::RialtoFinalityApi<Block> for Runtime {
fn best_finalized() -> (bp_rialto::BlockNumber, bp_rialto::Hash) {
let header = BridgeFinalityVerifier::best_finalized();
let header = BridgeRialtoFinalityVerifier::best_finalized();
(header.number, header.hash())
}

fn is_known_header(hash: bp_rialto::Hash) -> bool {
BridgeFinalityVerifier::is_known_header(hash)
BridgeRialtoFinalityVerifier::is_known_header(hash)
}
}

impl bp_westend::WestendFinalityApi<Block> for Runtime {
fn best_finalized() -> (bp_westend::BlockNumber, bp_westend::Hash) {
let header = BridgeWestendFinalityVerifier::best_finalized();
(header.number, header.hash())
}

fn is_known_header(hash: bp_westend::Hash) -> bool {
BridgeWestendFinalityVerifier::is_known_header(hash)
}
}

Expand Down
2 changes: 1 addition & 1 deletion bridges/modules/finality-verifier/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ pub mod pallet {
let set_id = authority_set.set_id;

Ok(
verify_justification::<BridgedHeader<T, I>>((hash, number), set_id, voter_set, &justification).map_err(
verify_justification::<BridgedHeader<T, I>>((hash, number), set_id, &voter_set, &justification).map_err(
|e| {
log::error!("Received invalid justification for {:?}: {:?}", hash, e);
<Error<T, I>>::InvalidJustification
Expand Down
2 changes: 1 addition & 1 deletion bridges/modules/substrate/src/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ where
verify_justification::<H>(
(hash, *header.number()),
current_authority_set.set_id,
voter_set,
&voter_set,
&proof.0,
)
.map_err(|_| FinalizationError::InvalidJustification)?;
Expand Down
2 changes: 1 addition & 1 deletion bridges/primitives/chains/westend/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
// Runtime-generated DecodeLimit::decode_all_with_depth_limit
#![allow(clippy::unnecessary_mut_passed)]

use bp_message_lane::{LaneId, Weight, MessageNonce, UnrewardedRelayersState};
use bp_message_lane::{LaneId, MessageNonce, UnrewardedRelayersState, Weight};
use sp_std::prelude::*;

pub use bp_polkadot_core::*;
Expand Down
4 changes: 2 additions & 2 deletions bridges/primitives/header-chain/src/justification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ pub fn decode_justification_target<Header: HeaderT>(
pub fn verify_justification<Header: HeaderT>(
finalized_target: (Header::Hash, Header::Number),
authorities_set_id: SetId,
authorities_set: VoterSet<AuthorityId>,
authorities_set: &VoterSet<AuthorityId>,
raw_justification: &[u8],
) -> Result<(), Error>
where
Expand All @@ -76,7 +76,7 @@ where
// signatures are valid. We'll check the validity of the signatures later since they're more
// resource intensive to verify.
let ancestry_chain = AncestryChain::new(&justification.votes_ancestries);
match finality_grandpa::validate_commit(&justification.commit, &authorities_set, &ancestry_chain) {
match finality_grandpa::validate_commit(&justification.commit, authorities_set, &ancestry_chain) {
Ok(ref result) if result.ghost().is_some() => {}
_ => return Err(Error::InvalidJustificationCommit),
}
Expand Down
12 changes: 6 additions & 6 deletions bridges/primitives/header-chain/tests/justification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn make_justification_for_header_1() -> GrandpaJustification<TestHeader> {
#[test]
fn justification_with_invalid_encoding_rejected() {
assert_eq!(
verify_justification::<TestHeader>(header_id::<TestHeader>(1), TEST_GRANDPA_SET_ID, voter_set(), &[],),
verify_justification::<TestHeader>(header_id::<TestHeader>(1), TEST_GRANDPA_SET_ID, &voter_set(), &[],),
Err(Error::JustificationDecode),
);
}
Expand All @@ -45,7 +45,7 @@ fn justification_with_invalid_target_rejected() {
verify_justification::<TestHeader>(
header_id::<TestHeader>(2),
TEST_GRANDPA_SET_ID,
voter_set(),
&voter_set(),
&make_justification_for_header_1().encode(),
),
Err(Error::InvalidJustificationTarget),
Expand All @@ -61,7 +61,7 @@ fn justification_with_invalid_commit_rejected() {
verify_justification::<TestHeader>(
header_id::<TestHeader>(1),
TEST_GRANDPA_SET_ID,
voter_set(),
&voter_set(),
&justification.encode(),
),
Err(Error::InvalidJustificationCommit),
Expand All @@ -77,7 +77,7 @@ fn justification_with_invalid_authority_signature_rejected() {
verify_justification::<TestHeader>(
header_id::<TestHeader>(1),
TEST_GRANDPA_SET_ID,
voter_set(),
&voter_set(),
&justification.encode(),
),
Err(Error::InvalidAuthoritySignature),
Expand All @@ -93,7 +93,7 @@ fn justification_with_invalid_precommit_ancestry() {
verify_justification::<TestHeader>(
header_id::<TestHeader>(1),
TEST_GRANDPA_SET_ID,
voter_set(),
&voter_set(),
&justification.encode(),
),
Err(Error::InvalidPrecommitAncestries),
Expand All @@ -106,7 +106,7 @@ fn valid_justification_accepted() {
verify_justification::<TestHeader>(
header_id::<TestHeader>(1),
TEST_GRANDPA_SET_ID,
voter_set(),
&voter_set(),
&make_justification_for_header_1().encode(),
),
Ok(()),
Expand Down
7 changes: 6 additions & 1 deletion bridges/relays/clients/substrate/src/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,12 @@ impl<C: Chain> Client<C> {

/// Build client to use in connection.
async fn build_client(params: ConnectionParams) -> Result<RpcClient> {
let uri = format!("ws://{}:{}", params.host, params.port);
let uri = format!(
"{}://{}:{}",
if params.secure { "wss" } else { "ws" },
params.host,
params.port,
);
let mut config = RpcConfig::with_url(&uri);
config.max_subscription_capacity = MAX_SUBSCRIPTION_CAPACITY;
let client = RpcClient::new(config).await?;
Expand Down
3 changes: 3 additions & 0 deletions bridges/relays/clients/substrate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,16 @@ pub struct ConnectionParams {
pub host: String,
/// Websocket server TCP port.
pub port: u16,
/// Use secure websocket connection.
pub secure: bool,
}

impl Default for ConnectionParams {
fn default() -> Self {
ConnectionParams {
host: "localhost".into(),
port: 9944,
secure: false,
}
}
}
25 changes: 25 additions & 0 deletions bridges/relays/clients/westend/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "relay-westend-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 = "../../generic/headers" }
relay-substrate-client = { path = "../substrate" }
relay-utils = { path = "../../generic/utils" }

# Bridge dependencies

bp-westend = { path = "../../../primitives/chains/westend" }

# 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" }
47 changes: 47 additions & 0 deletions bridges/relays/clients/westend/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2019-2020 Parity Technologies (UK) Ltd.
// This file is part of Parity Bridges Common.

// 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 Westend chain.

use relay_substrate_client::{Chain, ChainBase};
use std::time::Duration;

/// Westend header id.
pub type HeaderId = relay_utils::HeaderId<bp_westend::Hash, bp_westend::BlockNumber>;

/// Westend chain definition
#[derive(Debug, Clone, Copy)]
pub struct Westend;

impl ChainBase for Westend {
type BlockNumber = bp_westend::BlockNumber;
type Hash = bp_westend::Hash;
type Hasher = bp_westend::Hasher;
type Header = bp_westend::Header;
}

impl Chain for Westend {
const NAME: &'static str = "Westend";
const AVERAGE_BLOCK_INTERVAL: Duration = Duration::from_secs(6);

type AccountId = bp_westend::AccountId;
type Index = bp_westend::Nonce;
type SignedBlock = bp_westend::SignedBlock;
type Call = ();
}

/// Westend header type used in headers sync.
pub type SyncHeader = relay_substrate_client::SyncHeader<bp_westend::Header>;
3 changes: 3 additions & 0 deletions bridges/relays/substrate/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ bp-millau = { path = "../../primitives/chains/millau" }
bp-polkadot = { path = "../../primitives/chains/polkadot" }
bp-runtime = { path = "../../primitives/runtime" }
bp-rialto = { path = "../../primitives/chains/rialto" }
bp-westend = { path = "../../primitives/chains/westend" }
bridge-runtime-common = { path = "../../bin/runtime-common" }
finality-grandpa = { version = "0.14.0" }
finality-relay = { path = "../generic/finality" }
headers-relay = { path = "../generic/headers" }
messages-relay = { path = "../generic/messages" }
Expand All @@ -39,6 +41,7 @@ relay-millau-client = { path = "../clients/millau" }
relay-polkadot-client = { path = "../clients/polkadot" }
relay-rialto-client = { path = "../clients/rialto" }
relay-substrate-client = { path = "../clients/substrate" }
relay-westend-client = { path = "../clients/westend" }
relay-utils = { path = "../generic/utils" }
rialto-runtime = { path = "../../bin/rialto/runtime" }

Expand Down
17 changes: 3 additions & 14 deletions bridges/relays/substrate/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,9 @@ macro_rules! declare_chain_options {
#[doc = "Connect to " $chain " node websocket server at given port."]
#[structopt(long)]
pub [<$chain_prefix _port>]: u16,
#[doc = "Use secure websocket connection."]
#[structopt(long)]
pub [<$chain_prefix _secure>]: bool,
}

#[doc = $chain " signing params."]
Expand All @@ -408,20 +411,6 @@ macro_rules! declare_chain_options {
#[structopt(long)]
pub [<$chain_prefix _signer_password>]: Option<String>,
}

#[doc = $chain " headers bridge initialization params."]
#[derive(StructOpt)]
pub struct [<$chain BridgeInitializationParams>] {
#[doc = "Hex-encoded " $chain " header to initialize bridge with. If not specified, genesis header is used."]
#[structopt(long)]
pub [<$chain_prefix _initial_header>]: Option<sp_core::Bytes>,
#[doc = "Hex-encoded " $chain " GRANDPA authorities set to initialize bridge with. If not specified, set from genesis block is used."]
#[structopt(long)]
pub [<$chain_prefix _initial_authorities>]: Option<sp_core::Bytes>,
#[doc = "Id of the " $chain " GRANDPA authorities set to initialize bridge with. If not specified, zero is used."]
#[structopt(long)]
pub [<$chain_prefix _initial_authorities_set_id>]: Option<sp_finality_grandpa::SetId>,
}
}
};
}
Loading

0 comments on commit 139b706

Please sign in to comment.