mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 10:31:03 +00:00
Squashed 'bridges/' changes from b2099c5..23dda62 (#3369)
23dda62 Rococo <> Wococo messages relay (#1030) bcde21d Update the wasm builder to substrate master (#1029) a8318ce Make target signer optional when sending message. (#1018) f8602e1 Fix insufficient balance when send message. (#1020) d95c0a7 greedy relayer don't need message dispatch to be prepaid if dispatch is supposed to be paid at the target chain (#1016) ad5876f Update types. (#1027) 116cbbc CI: fix starting the pipeline (#1022) 7e0fadd Add temporary `canary` job (#1019) 6787091 Update types to contain dispatch_fee_payment (#1017) 03f79ad Allow Root to assume SourceAccount. (#1011) 372d019 Return dispatch_fee_payment from message details RPC (#1014) 604eb1c Relay basic single-bit message dispatch results back to the source chain (#935) bf52fff Use plain source_queue view when selecting nonces for delivery (#1010) fc5cf7d pay dispatch fee at target chain (#911) 1e35477 Bump Substrate to `286d7ce` (#1006) 7ad07b3 Add --only-mandatory-headers mode (#1004) 5351dc9 Messages relayer operating mode (#995) 9bc29a7 Rococo <> Wococo relayer balance guard (#998) bc17341 rename messages_dispatch_weight -> message_details (#996) 95be244 Bump Rococo and Wococo spec versions (#999) c35567b Move ChainWithBalances::NativeBalance -> Chain::Balance (#990) 1bfece1 Fix some nits (#988) 334ea0f Increase pause before starting relays again (#989) 7fb8248 Fix clippy in test code (#993) d60ae50 fix clippy issues (#991) 75ca813 Make sure GRANDPA shares state with RPC. (#987) da2a38a Bump Substrate (#986) 5a9862f Update submit finality proof weight formula (#981) 69df513 Flag for rejecting all outbound messages (#982) 14d0506 Add script to setup bench machine. (#984) e74e8ab Move CI from GitHub Actions to GitLab (#814) c5ca5dd Custom justification verification (#979) 643f10d Always run on-demand headers relay in complex relay (#975) a35b0ef Add JSON type definitions for Rococo<>Wococo bridge (#977) 0eb83f2 Update cargo.deny (#980) e1d1f4c Bump Rococo/Wococo spec_version (#976) deac90d increase pause before starting relays (#974) 68d6d79 Revert to use InspectCmd, bump substrate `6bef4f4` (#966) 66e1508 Avoid hashing headers twice in verify_justification (#973) a31844f Bump `environmental` dependency (#972) 2a4c29a in auto-relays keep trying to connect to nodes until connection is established (#971) 0e767b3 removed stray file (#969) b9545dc Serve multiple lanes with single complex relay instance (#964) 73419f4 Correct type error (#968) bac256f Start finality relay spec-version guards for Rococo <> Wococo finality relays (#965) bfd7037 pass source and target chain ids to account_ownership_proof (#963) 8436073 Upstream changes from Polkadot repo (#961) e58d851 Increase account endowment amount (#960) git-subtree-dir: bridges git-subtree-split: 23dda6248236b27f20d76cbedc30e189cc6f736c
This commit is contained in:
committed by
GitHub
parent
022e8bc11c
commit
feefc34567
@@ -51,7 +51,7 @@ sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "mast
|
||||
substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[build-dependencies]
|
||||
substrate-build-script-utils = "3.0.0"
|
||||
substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[features]
|
||||
|
||||
@@ -72,7 +72,7 @@ impl Alternative {
|
||||
"tokenDecimals": 9,
|
||||
"tokenSymbol": "MLAU",
|
||||
"bridgeIds": {
|
||||
"Rialto": bp_runtime::RIALTO_BRIDGE_INSTANCE,
|
||||
"Rialto": bp_runtime::RIALTO_CHAIN_ID,
|
||||
}
|
||||
})
|
||||
.as_object()
|
||||
@@ -144,12 +144,21 @@ impl Alternative {
|
||||
derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
)),
|
||||
derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
)),
|
||||
derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
)),
|
||||
derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
)),
|
||||
derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
)),
|
||||
derive_account_from_rialto_id(bp_runtime::SourceAccount::Account(
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
)),
|
||||
],
|
||||
true,
|
||||
)
|
||||
@@ -180,7 +189,7 @@ fn testnet_genesis(
|
||||
changes_trie_config: Default::default(),
|
||||
},
|
||||
balances: BalancesConfig {
|
||||
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 40)).collect(),
|
||||
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 50)).collect(),
|
||||
},
|
||||
aura: AuraConfig {
|
||||
authorities: Vec::new(),
|
||||
|
||||
@@ -63,7 +63,7 @@ pub enum Subcommand {
|
||||
Revert(sc_cli::RevertCmd),
|
||||
|
||||
/// Inspect blocks or extrinsics.
|
||||
Inspect(node_inspect::cli::InspectKeyCmd),
|
||||
Inspect(node_inspect::cli::InspectCmd),
|
||||
|
||||
/// Benchmark runtime pallets.
|
||||
Benchmark(frame_benchmarking_cli::BenchmarkCmd),
|
||||
|
||||
@@ -33,14 +33,13 @@ use sc_client_api::{ExecutorProvider, RemoteBackend};
|
||||
use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams};
|
||||
use sc_executor::native_executor_instance;
|
||||
pub use sc_executor::NativeExecutor;
|
||||
use sc_finality_grandpa::SharedVoterState;
|
||||
|
||||
use sc_keystore::LocalKeystore;
|
||||
use sc_service::{error::Error as ServiceError, Configuration, TaskManager};
|
||||
use sc_telemetry::{Telemetry, TelemetryWorker};
|
||||
use sp_consensus::SlotData;
|
||||
use sp_consensus_aura::sr25519::AuthorityPair as AuraPair;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
// Our native executor instance.
|
||||
native_executor_instance!(
|
||||
@@ -65,12 +64,7 @@ pub fn new_partial(
|
||||
sp_consensus::DefaultImportQueue<Block, FullClient>,
|
||||
sc_transaction_pool::FullPool<Block, FullClient>,
|
||||
(
|
||||
sc_consensus_aura::AuraBlockImport<
|
||||
Block,
|
||||
FullClient,
|
||||
sc_finality_grandpa::GrandpaBlockImport<FullBackend, Block, FullClient, FullSelectChain>,
|
||||
AuraPair,
|
||||
>,
|
||||
sc_finality_grandpa::GrandpaBlockImport<FullBackend, Block, FullClient, FullSelectChain>,
|
||||
sc_finality_grandpa::LinkHalf<Block, FullClient, FullSelectChain>,
|
||||
Option<Telemetry>,
|
||||
),
|
||||
@@ -80,6 +74,7 @@ pub fn new_partial(
|
||||
if config.keystore_remote.is_some() {
|
||||
return Err(ServiceError::Other("Remote Keystores are not supported.".to_string()));
|
||||
}
|
||||
|
||||
let telemetry = config
|
||||
.telemetry_endpoints
|
||||
.clone()
|
||||
@@ -92,7 +87,7 @@ pub fn new_partial(
|
||||
.transpose()?;
|
||||
|
||||
let (client, backend, keystore_container, task_manager) = sc_service::new_full_parts::<Block, RuntimeApi, Executor>(
|
||||
&config,
|
||||
config,
|
||||
telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
|
||||
)?;
|
||||
let client = Arc::new(client);
|
||||
@@ -108,7 +103,7 @@ pub fn new_partial(
|
||||
config.transaction_pool.clone(),
|
||||
config.role.is_authority().into(),
|
||||
config.prometheus_registry(),
|
||||
task_manager.spawn_handle(),
|
||||
task_manager.spawn_essential_handle(),
|
||||
client.clone(),
|
||||
);
|
||||
|
||||
@@ -119,14 +114,11 @@ pub fn new_partial(
|
||||
telemetry.as_ref().map(|x| x.handle()),
|
||||
)?;
|
||||
|
||||
let aura_block_import =
|
||||
sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(grandpa_block_import.clone(), client.clone());
|
||||
|
||||
let slot_duration = sc_consensus_aura::slot_duration(&*client)?.slot_duration();
|
||||
|
||||
let import_queue = sc_consensus_aura::import_queue::<AuraPair, _, _, _, _, _, _>(ImportQueueParams {
|
||||
block_import: aura_block_import.clone(),
|
||||
justification_import: Some(Box::new(grandpa_block_import)),
|
||||
block_import: grandpa_block_import.clone(),
|
||||
justification_import: Some(Box::new(grandpa_block_import.clone())),
|
||||
client: client.clone(),
|
||||
create_inherent_data_providers: move |_, ()| async move {
|
||||
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
|
||||
@@ -153,7 +145,7 @@ pub fn new_partial(
|
||||
keystore_container,
|
||||
select_chain,
|
||||
transaction_pool,
|
||||
other: (aura_block_import, grandpa_link, telemetry),
|
||||
other: (grandpa_block_import, grandpa_link, telemetry),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -194,16 +186,15 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
.extra_sets
|
||||
.push(sc_finality_grandpa::grandpa_peers_set_config());
|
||||
|
||||
let (network, network_status_sinks, system_rpc_tx, network_starter) =
|
||||
sc_service::build_network(sc_service::BuildNetworkParams {
|
||||
config: &config,
|
||||
client: client.clone(),
|
||||
transaction_pool: transaction_pool.clone(),
|
||||
spawn_handle: task_manager.spawn_handle(),
|
||||
import_queue,
|
||||
on_demand: None,
|
||||
block_announce_validator_builder: None,
|
||||
})?;
|
||||
let (network, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams {
|
||||
config: &config,
|
||||
client: client.clone(),
|
||||
transaction_pool: transaction_pool.clone(),
|
||||
spawn_handle: task_manager.spawn_handle(),
|
||||
import_queue,
|
||||
on_demand: None,
|
||||
block_announce_validator_builder: None,
|
||||
})?;
|
||||
|
||||
if config.offchain_worker.enabled {
|
||||
sc_service::build_offchain_workers(&config, task_manager.spawn_handle(), client.clone(), network.clone());
|
||||
@@ -215,6 +206,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
let name = config.network.node_name.clone();
|
||||
let enable_grandpa = !config.disable_grandpa;
|
||||
let prometheus_registry = config.prometheus_registry().cloned();
|
||||
let shared_voter_state = sc_finality_grandpa::SharedVoterState::empty();
|
||||
|
||||
let rpc_extensions_builder = {
|
||||
use sc_finality_grandpa::FinalityProofProvider as GrandpaFinalityProofProvider;
|
||||
@@ -230,7 +222,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
|
||||
let justification_stream = grandpa_link.justification_stream();
|
||||
let shared_authority_set = grandpa_link.shared_authority_set().clone();
|
||||
let shared_voter_state = sc_finality_grandpa::SharedVoterState::empty();
|
||||
let shared_voter_state = shared_voter_state.clone();
|
||||
|
||||
let finality_proof_provider =
|
||||
GrandpaFinalityProofProvider::new_for_service(backend, Some(shared_authority_set.clone()));
|
||||
@@ -266,7 +258,6 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
on_demand: None,
|
||||
remote_blockchain: None,
|
||||
backend,
|
||||
network_status_sinks,
|
||||
system_rpc_tx,
|
||||
config,
|
||||
telemetry: telemetry.as_mut(),
|
||||
@@ -286,7 +277,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
let slot_duration = sc_consensus_aura::slot_duration(&*client)?;
|
||||
let raw_slot_duration = slot_duration.slot_duration();
|
||||
|
||||
let aura = sc_consensus_aura::start_aura::<AuraPair, _, _, _, _, _, _, _, _, _, _>(StartAuraParams {
|
||||
let aura = sc_consensus_aura::start_aura::<AuraPair, _, _, _, _, _, _, _, _, _, _, _>(StartAuraParams {
|
||||
slot_duration,
|
||||
client,
|
||||
select_chain,
|
||||
@@ -307,7 +298,9 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
keystore: keystore_container.sync_keystore(),
|
||||
can_author_with,
|
||||
sync_oracle: network.clone(),
|
||||
justification_sync_link: network.clone(),
|
||||
block_proposal_slot_portion: SlotProportion::new(2f32 / 3f32),
|
||||
max_block_proposal_slot_portion: None,
|
||||
telemetry: telemetry.as_ref().map(|x| x.handle()),
|
||||
})?;
|
||||
|
||||
@@ -331,7 +324,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
name: Some(name),
|
||||
observer_enabled: false,
|
||||
keystore,
|
||||
is_authority: role.is_authority(),
|
||||
local_role: role,
|
||||
telemetry: telemetry.as_ref().map(|x| x.handle()),
|
||||
};
|
||||
|
||||
@@ -348,7 +341,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
network,
|
||||
voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(),
|
||||
prometheus_registry,
|
||||
shared_voter_state: SharedVoterState::empty(),
|
||||
shared_voter_state,
|
||||
telemetry: telemetry.as_ref().map(|x| x.handle()),
|
||||
};
|
||||
|
||||
@@ -397,24 +390,22 @@ pub fn new_light(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light(
|
||||
config.transaction_pool.clone(),
|
||||
config.prometheus_registry(),
|
||||
task_manager.spawn_handle(),
|
||||
task_manager.spawn_essential_handle(),
|
||||
client.clone(),
|
||||
on_demand.clone(),
|
||||
));
|
||||
|
||||
let (grandpa_block_import, _) = sc_finality_grandpa::block_import(
|
||||
let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import(
|
||||
client.clone(),
|
||||
&(client.clone() as Arc<_>),
|
||||
select_chain,
|
||||
telemetry.as_ref().map(|x| x.handle()),
|
||||
)?;
|
||||
|
||||
let aura_block_import =
|
||||
sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(grandpa_block_import.clone(), client.clone());
|
||||
|
||||
let slot_duration = sc_consensus_aura::slot_duration(&*client)?.slot_duration();
|
||||
|
||||
let import_queue = sc_consensus_aura::import_queue::<AuraPair, _, _, _, _, _, _>(ImportQueueParams {
|
||||
block_import: aura_block_import,
|
||||
block_import: grandpa_block_import.clone(),
|
||||
justification_import: Some(Box::new(grandpa_block_import)),
|
||||
client: client.clone(),
|
||||
create_inherent_data_providers: move |_, ()| async move {
|
||||
@@ -434,21 +425,40 @@ pub fn new_light(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
telemetry: telemetry.as_ref().map(|x| x.handle()),
|
||||
})?;
|
||||
|
||||
let (network, network_status_sinks, system_rpc_tx, network_starter) =
|
||||
sc_service::build_network(sc_service::BuildNetworkParams {
|
||||
config: &config,
|
||||
client: client.clone(),
|
||||
transaction_pool: transaction_pool.clone(),
|
||||
spawn_handle: task_manager.spawn_handle(),
|
||||
import_queue,
|
||||
on_demand: Some(on_demand.clone()),
|
||||
block_announce_validator_builder: None,
|
||||
})?;
|
||||
let (network, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams {
|
||||
config: &config,
|
||||
client: client.clone(),
|
||||
transaction_pool: transaction_pool.clone(),
|
||||
spawn_handle: task_manager.spawn_handle(),
|
||||
import_queue,
|
||||
on_demand: Some(on_demand.clone()),
|
||||
block_announce_validator_builder: None,
|
||||
})?;
|
||||
|
||||
if config.offchain_worker.enabled {
|
||||
sc_service::build_offchain_workers(&config, task_manager.spawn_handle(), client.clone(), network.clone());
|
||||
}
|
||||
|
||||
let enable_grandpa = !config.disable_grandpa;
|
||||
if enable_grandpa {
|
||||
let name = config.network.node_name.clone();
|
||||
|
||||
let config = sc_finality_grandpa::Config {
|
||||
gossip_duration: std::time::Duration::from_millis(333),
|
||||
justification_period: 512,
|
||||
name: Some(name),
|
||||
observer_enabled: false,
|
||||
keystore: None,
|
||||
local_role: config.role.clone(),
|
||||
telemetry: telemetry.as_ref().map(|x| x.handle()),
|
||||
};
|
||||
|
||||
task_manager.spawn_handle().spawn_blocking(
|
||||
"grandpa-observer",
|
||||
sc_finality_grandpa::run_grandpa_observer(config, grandpa_link, network.clone())?,
|
||||
);
|
||||
}
|
||||
|
||||
sc_service::spawn_tasks(sc_service::SpawnTasksParams {
|
||||
remote_blockchain: Some(backend.remote_blockchain()),
|
||||
transaction_pool,
|
||||
@@ -460,12 +470,10 @@ pub fn new_light(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
keystore: keystore_container.sync_keystore(),
|
||||
backend,
|
||||
network,
|
||||
network_status_sinks,
|
||||
system_rpc_tx,
|
||||
telemetry: telemetry.as_mut(),
|
||||
})?;
|
||||
|
||||
network_starter.start_network();
|
||||
|
||||
Ok(task_manager)
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ sp-trie = { git = "https://github.com/paritytech/substrate", branch = "master" ,
|
||||
sp-version = { git = "https://github.com/paritytech/substrate", branch = "master" , default-features = false }
|
||||
|
||||
[build-dependencies]
|
||||
substrate-wasm-builder = "3.0.0"
|
||||
substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
|
||||
@@ -252,6 +252,7 @@ parameter_types! {
|
||||
// For weight estimation, we assume that the most locks on an individual account will be 50.
|
||||
// This number may need to be adjusted in the future if this assumption no longer holds true.
|
||||
pub const MaxLocks: u32 = 50;
|
||||
pub const MaxReserves: u32 = 50;
|
||||
}
|
||||
|
||||
impl pallet_balances::Config for Runtime {
|
||||
@@ -265,6 +266,8 @@ impl pallet_balances::Config for Runtime {
|
||||
// TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78)
|
||||
type WeightInfo = ();
|
||||
type MaxLocks = MaxLocks;
|
||||
type MaxReserves = MaxReserves;
|
||||
type ReserveIdentifier = [u8; 8];
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
@@ -381,6 +384,7 @@ impl pallet_bridge_messages::Config<WithRialtoMessagesInstance> for Runtime {
|
||||
GetDeliveryConfirmationTransactionFee,
|
||||
RootAccountForPayments,
|
||||
>;
|
||||
type OnDeliveryConfirmed = ();
|
||||
|
||||
type SourceHeaderChain = crate::rialto_messages::Rialto;
|
||||
type MessageDispatch = crate::rialto_messages::FromRialtoMessageDispatch;
|
||||
@@ -600,17 +604,23 @@ impl_runtime_apis! {
|
||||
).ok()
|
||||
}
|
||||
|
||||
fn messages_dispatch_weight(
|
||||
fn message_details(
|
||||
lane: bp_messages::LaneId,
|
||||
begin: bp_messages::MessageNonce,
|
||||
end: bp_messages::MessageNonce,
|
||||
) -> Vec<(bp_messages::MessageNonce, Weight, u32)> {
|
||||
) -> Vec<bp_messages::MessageDetails<Balance>> {
|
||||
(begin..=end).filter_map(|nonce| {
|
||||
let encoded_payload = BridgeRialtoMessages::outbound_message_payload(lane, nonce)?;
|
||||
let message_data = BridgeRialtoMessages::outbound_message_data(lane, nonce)?;
|
||||
let decoded_payload = rialto_messages::ToRialtoMessagePayload::decode(
|
||||
&mut &encoded_payload[..]
|
||||
&mut &message_data.payload[..]
|
||||
).ok()?;
|
||||
Some((nonce, decoded_payload.weight, encoded_payload.len() as _))
|
||||
Some(bp_messages::MessageDetails {
|
||||
nonce,
|
||||
dispatch_weight: decoded_payload.weight,
|
||||
size: message_data.payload.len() as _,
|
||||
delivery_and_dispatch_fee: message_data.fee,
|
||||
dispatch_fee_payment: decoded_payload.dispatch_fee_payment,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -644,7 +654,7 @@ impl_runtime_apis! {
|
||||
/// The byte vector returned by this function should be signed with a Rialto account private key.
|
||||
/// This way, the owner of `millau_account_id` on Millau proves that the Rialto account private key
|
||||
/// is also under his control.
|
||||
pub fn rialto_account_ownership_digest<Call, AccountId, SpecVersion>(
|
||||
pub fn millau_to_rialto_account_ownership_digest<Call, AccountId, SpecVersion>(
|
||||
rialto_call: &Call,
|
||||
millau_account_id: AccountId,
|
||||
rialto_spec_version: SpecVersion,
|
||||
@@ -658,7 +668,8 @@ where
|
||||
rialto_call,
|
||||
millau_account_id,
|
||||
rialto_spec_version,
|
||||
bp_runtime::MILLAU_BRIDGE_INSTANCE,
|
||||
bp_runtime::MILLAU_CHAIN_ID,
|
||||
bp_runtime::RIALTO_CHAIN_ID,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -676,6 +687,7 @@ mod tests {
|
||||
bp_millau::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT,
|
||||
bp_millau::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT,
|
||||
bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT,
|
||||
bp_millau::PAY_INBOUND_DISPATCH_FEE_WEIGHT,
|
||||
);
|
||||
|
||||
let max_incoming_message_proof_size = bp_rialto::EXTRA_STORAGE_PROOF_SIZE.saturating_add(
|
||||
@@ -691,6 +703,7 @@ mod tests {
|
||||
let max_incoming_inbound_lane_data_proof_size = bp_messages::InboundLaneData::<()>::encoded_size_hint(
|
||||
bp_millau::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE,
|
||||
bp_rialto::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE as _,
|
||||
bp_rialto::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE as _,
|
||||
)
|
||||
.unwrap_or(u32::MAX);
|
||||
pallet_bridge_messages::ensure_able_to_receive_confirmation::<Weights>(
|
||||
|
||||
@@ -23,7 +23,7 @@ use bp_messages::{
|
||||
target_chain::{ProvedMessages, SourceHeaderChain},
|
||||
InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter,
|
||||
};
|
||||
use bp_runtime::{InstanceId, RIALTO_BRIDGE_INSTANCE};
|
||||
use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_CHAIN_ID};
|
||||
use bridge_runtime_common::messages::{self, MessageBridge, MessageTransaction};
|
||||
use codec::{Decode, Encode};
|
||||
use frame_support::{
|
||||
@@ -52,7 +52,7 @@ pub type ToRialtoMessageVerifier = messages::source::FromThisChainMessageVerifie
|
||||
pub type FromRialtoMessagePayload = messages::target::FromBridgedChainMessagePayload<WithRialtoMessageBridge>;
|
||||
|
||||
/// Encoded Millau Call as it comes from Rialto.
|
||||
pub type FromRialtoEncodedCall = messages::target::FromBridgedChainEncodedMessageCall<WithRialtoMessageBridge>;
|
||||
pub type FromRialtoEncodedCall = messages::target::FromBridgedChainEncodedMessageCall<crate::Call>;
|
||||
|
||||
/// Messages proof for Rialto -> Millau messages.
|
||||
type FromRialtoMessagesProof = messages::target::FromBridgedChainMessagesProof<bp_rialto::Hash>;
|
||||
@@ -64,6 +64,7 @@ type ToRialtoMessagesDeliveryProof = messages::source::FromBridgedChainMessagesD
|
||||
pub type FromRialtoMessageDispatch = messages::target::FromBridgedChainMessageDispatch<
|
||||
WithRialtoMessageBridge,
|
||||
crate::Runtime,
|
||||
pallet_balances::Pallet<Runtime>,
|
||||
pallet_bridge_dispatch::DefaultInstance,
|
||||
>;
|
||||
|
||||
@@ -72,12 +73,13 @@ pub type FromRialtoMessageDispatch = messages::target::FromBridgedChainMessageDi
|
||||
pub struct WithRialtoMessageBridge;
|
||||
|
||||
impl MessageBridge for WithRialtoMessageBridge {
|
||||
const INSTANCE: InstanceId = RIALTO_BRIDGE_INSTANCE;
|
||||
|
||||
const RELAYER_FEE_PERCENT: u32 = 10;
|
||||
const THIS_CHAIN_ID: ChainId = MILLAU_CHAIN_ID;
|
||||
const BRIDGED_CHAIN_ID: ChainId = RIALTO_CHAIN_ID;
|
||||
|
||||
type ThisChain = Millau;
|
||||
type BridgedChain = Rialto;
|
||||
type BridgedMessagesInstance = crate::WithRialtoMessagesInstance;
|
||||
|
||||
fn bridged_balance_to_this_balance(bridged_balance: bp_rialto::Balance) -> bp_millau::Balance {
|
||||
bp_millau::Balance::try_from(RialtoToMillauConversionRate::get().saturating_mul_int(bridged_balance))
|
||||
@@ -96,8 +98,6 @@ impl messages::ChainWithMessages for Millau {
|
||||
type Signature = bp_millau::Signature;
|
||||
type Weight = Weight;
|
||||
type Balance = bp_millau::Balance;
|
||||
|
||||
type MessagesInstance = crate::WithRialtoMessagesInstance;
|
||||
}
|
||||
|
||||
impl messages::ThisChainWithMessages for Millau {
|
||||
@@ -112,9 +112,12 @@ impl messages::ThisChainWithMessages for Millau {
|
||||
}
|
||||
|
||||
fn estimate_delivery_confirmation_transaction() -> MessageTransaction<Weight> {
|
||||
let inbound_data_size =
|
||||
InboundLaneData::<bp_millau::AccountId>::encoded_size_hint(bp_millau::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE, 1)
|
||||
.unwrap_or(u32::MAX);
|
||||
let inbound_data_size = InboundLaneData::<bp_millau::AccountId>::encoded_size_hint(
|
||||
bp_millau::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE,
|
||||
1,
|
||||
1,
|
||||
)
|
||||
.unwrap_or(u32::MAX);
|
||||
|
||||
MessageTransaction {
|
||||
dispatch_weight: bp_millau::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT,
|
||||
@@ -147,8 +150,6 @@ impl messages::ChainWithMessages for Rialto {
|
||||
type Signature = bp_rialto::Signature;
|
||||
type Weight = Weight;
|
||||
type Balance = bp_rialto::Balance;
|
||||
|
||||
type MessagesInstance = pallet_bridge_messages::DefaultInstance;
|
||||
}
|
||||
|
||||
impl messages::BridgedChainWithMessages for Rialto {
|
||||
@@ -170,6 +171,7 @@ impl messages::BridgedChainWithMessages for Rialto {
|
||||
|
||||
fn estimate_delivery_transaction(
|
||||
message_payload: &[u8],
|
||||
include_pay_dispatch_fee_cost: bool,
|
||||
message_dispatch_weight: Weight,
|
||||
) -> MessageTransaction<Weight> {
|
||||
let message_payload_len = u32::try_from(message_payload.len()).unwrap_or(u32::MAX);
|
||||
@@ -180,6 +182,11 @@ impl messages::BridgedChainWithMessages for Rialto {
|
||||
dispatch_weight: extra_bytes_in_payload
|
||||
.saturating_mul(bp_rialto::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT)
|
||||
.saturating_add(bp_rialto::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT)
|
||||
.saturating_sub(if include_pay_dispatch_fee_cost {
|
||||
0
|
||||
} else {
|
||||
bp_rialto::PAY_INBOUND_DISPATCH_FEE_WEIGHT
|
||||
})
|
||||
.saturating_add(message_dispatch_weight),
|
||||
size: message_payload_len
|
||||
.saturating_add(bp_millau::EXTRA_STORAGE_PROOF_SIZE)
|
||||
|
||||
@@ -52,7 +52,7 @@ sp-timestamp = { git = "https://github.com/paritytech/substrate", branch = "mast
|
||||
substrate-frame-rpc-system = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[build-dependencies]
|
||||
substrate-build-script-utils = "3.0.0"
|
||||
substrate-build-script-utils = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
frame-benchmarking-cli = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[features]
|
||||
|
||||
@@ -73,7 +73,7 @@ impl Alternative {
|
||||
"tokenDecimals": 9,
|
||||
"tokenSymbol": "RLT",
|
||||
"bridgeIds": {
|
||||
"Millau": bp_runtime::MILLAU_BRIDGE_INSTANCE,
|
||||
"Millau": bp_runtime::MILLAU_CHAIN_ID,
|
||||
}
|
||||
})
|
||||
.as_object()
|
||||
@@ -142,12 +142,21 @@ impl Alternative {
|
||||
rialto_runtime::Runtime,
|
||||
pallet_bridge_messages::DefaultInstance,
|
||||
>::relayer_fund_account_id(),
|
||||
derive_account_from_millau_id(bp_runtime::SourceAccount::Account(
|
||||
get_account_id_from_seed::<sr25519::Public>("Alice"),
|
||||
)),
|
||||
derive_account_from_millau_id(bp_runtime::SourceAccount::Account(
|
||||
get_account_id_from_seed::<sr25519::Public>("Bob"),
|
||||
)),
|
||||
derive_account_from_millau_id(bp_runtime::SourceAccount::Account(
|
||||
get_account_id_from_seed::<sr25519::Public>("Charlie"),
|
||||
)),
|
||||
derive_account_from_millau_id(bp_runtime::SourceAccount::Account(
|
||||
get_account_id_from_seed::<sr25519::Public>("Dave"),
|
||||
)),
|
||||
derive_account_from_millau_id(bp_runtime::SourceAccount::Account(
|
||||
get_account_id_from_seed::<sr25519::Public>("Eve"),
|
||||
)),
|
||||
derive_account_from_millau_id(bp_runtime::SourceAccount::Account(
|
||||
get_account_id_from_seed::<sr25519::Public>("Ferdie"),
|
||||
)),
|
||||
@@ -181,7 +190,7 @@ fn testnet_genesis(
|
||||
changes_trie_config: Default::default(),
|
||||
},
|
||||
balances: BalancesConfig {
|
||||
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 40)).collect(),
|
||||
balances: endowed_accounts.iter().cloned().map(|k| (k, 1 << 50)).collect(),
|
||||
},
|
||||
aura: AuraConfig {
|
||||
authorities: Vec::new(),
|
||||
|
||||
@@ -63,7 +63,7 @@ pub enum Subcommand {
|
||||
Revert(sc_cli::RevertCmd),
|
||||
|
||||
/// Inspect blocks or extrinsics.
|
||||
Inspect(node_inspect::cli::InspectKeyCmd),
|
||||
Inspect(node_inspect::cli::InspectCmd),
|
||||
|
||||
/// Benchmark runtime pallets.
|
||||
Benchmark(frame_benchmarking_cli::BenchmarkCmd),
|
||||
|
||||
@@ -28,19 +28,20 @@
|
||||
// =====================================================================================
|
||||
// =====================================================================================
|
||||
|
||||
//! Service and ServiceFactory implementation. Specialized wrapper over substrate service.
|
||||
|
||||
use rialto_runtime::{self, opaque::Block, RuntimeApi};
|
||||
use sc_client_api::{ExecutorProvider, RemoteBackend};
|
||||
use sc_consensus_aura::{ImportQueueParams, SlotProportion, StartAuraParams};
|
||||
use sc_executor::native_executor_instance;
|
||||
pub use sc_executor::NativeExecutor;
|
||||
use sc_finality_grandpa::SharedVoterState;
|
||||
|
||||
use sc_keystore::LocalKeystore;
|
||||
use sc_service::{error::Error as ServiceError, Configuration, TaskManager};
|
||||
use sc_telemetry::{Telemetry, TelemetryWorker};
|
||||
use sp_consensus::SlotData;
|
||||
use sp_consensus_aura::sr25519::AuthorityPair as AuraPair;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use std::{sync::Arc, time::Duration};
|
||||
|
||||
// Our native executor instance.
|
||||
native_executor_instance!(
|
||||
@@ -65,12 +66,7 @@ pub fn new_partial(
|
||||
sp_consensus::DefaultImportQueue<Block, FullClient>,
|
||||
sc_transaction_pool::FullPool<Block, FullClient>,
|
||||
(
|
||||
sc_consensus_aura::AuraBlockImport<
|
||||
Block,
|
||||
FullClient,
|
||||
sc_finality_grandpa::GrandpaBlockImport<FullBackend, Block, FullClient, FullSelectChain>,
|
||||
AuraPair,
|
||||
>,
|
||||
sc_finality_grandpa::GrandpaBlockImport<FullBackend, Block, FullClient, FullSelectChain>,
|
||||
sc_finality_grandpa::LinkHalf<Block, FullClient, FullSelectChain>,
|
||||
Option<Telemetry>,
|
||||
),
|
||||
@@ -93,7 +89,7 @@ pub fn new_partial(
|
||||
.transpose()?;
|
||||
|
||||
let (client, backend, keystore_container, task_manager) = sc_service::new_full_parts::<Block, RuntimeApi, Executor>(
|
||||
&config,
|
||||
config,
|
||||
telemetry.as_ref().map(|(_, telemetry)| telemetry.handle()),
|
||||
)?;
|
||||
let client = Arc::new(client);
|
||||
@@ -109,7 +105,7 @@ pub fn new_partial(
|
||||
config.transaction_pool.clone(),
|
||||
config.role.is_authority().into(),
|
||||
config.prometheus_registry(),
|
||||
task_manager.spawn_handle(),
|
||||
task_manager.spawn_essential_handle(),
|
||||
client.clone(),
|
||||
);
|
||||
|
||||
@@ -120,14 +116,11 @@ pub fn new_partial(
|
||||
telemetry.as_ref().map(|x| x.handle()),
|
||||
)?;
|
||||
|
||||
let aura_block_import =
|
||||
sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(grandpa_block_import.clone(), client.clone());
|
||||
|
||||
let slot_duration = sc_consensus_aura::slot_duration(&*client)?.slot_duration();
|
||||
|
||||
let import_queue = sc_consensus_aura::import_queue::<AuraPair, _, _, _, _, _, _>(ImportQueueParams {
|
||||
block_import: aura_block_import.clone(),
|
||||
justification_import: Some(Box::new(grandpa_block_import)),
|
||||
block_import: grandpa_block_import.clone(),
|
||||
justification_import: Some(Box::new(grandpa_block_import.clone())),
|
||||
client: client.clone(),
|
||||
create_inherent_data_providers: move |_, ()| async move {
|
||||
let timestamp = sp_timestamp::InherentDataProvider::from_system_time();
|
||||
@@ -154,7 +147,7 @@ pub fn new_partial(
|
||||
keystore_container,
|
||||
select_chain,
|
||||
transaction_pool,
|
||||
other: (aura_block_import, grandpa_link, telemetry),
|
||||
other: (grandpa_block_import, grandpa_link, telemetry),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -195,16 +188,15 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
.extra_sets
|
||||
.push(sc_finality_grandpa::grandpa_peers_set_config());
|
||||
|
||||
let (network, network_status_sinks, system_rpc_tx, network_starter) =
|
||||
sc_service::build_network(sc_service::BuildNetworkParams {
|
||||
config: &config,
|
||||
client: client.clone(),
|
||||
transaction_pool: transaction_pool.clone(),
|
||||
spawn_handle: task_manager.spawn_handle(),
|
||||
import_queue,
|
||||
on_demand: None,
|
||||
block_announce_validator_builder: None,
|
||||
})?;
|
||||
let (network, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams {
|
||||
config: &config,
|
||||
client: client.clone(),
|
||||
transaction_pool: transaction_pool.clone(),
|
||||
spawn_handle: task_manager.spawn_handle(),
|
||||
import_queue,
|
||||
on_demand: None,
|
||||
block_announce_validator_builder: None,
|
||||
})?;
|
||||
|
||||
if config.offchain_worker.enabled {
|
||||
sc_service::build_offchain_workers(&config, task_manager.spawn_handle(), client.clone(), network.clone());
|
||||
@@ -217,6 +209,8 @@ 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 = sc_finality_grandpa::SharedVoterState::empty();
|
||||
|
||||
let rpc_extensions_builder = {
|
||||
use sc_finality_grandpa::FinalityProofProvider as GrandpaFinalityProofProvider;
|
||||
|
||||
@@ -231,7 +225,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
|
||||
let justification_stream = grandpa_link.justification_stream();
|
||||
let shared_authority_set = grandpa_link.shared_authority_set().clone();
|
||||
let shared_voter_state = sc_finality_grandpa::SharedVoterState::empty();
|
||||
let shared_voter_state = shared_voter_state.clone();
|
||||
|
||||
let finality_proof_provider =
|
||||
GrandpaFinalityProofProvider::new_for_service(backend, Some(shared_authority_set.clone()));
|
||||
@@ -268,7 +262,6 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
on_demand: None,
|
||||
remote_blockchain: None,
|
||||
backend,
|
||||
network_status_sinks,
|
||||
system_rpc_tx,
|
||||
config,
|
||||
telemetry: telemetry.as_mut(),
|
||||
@@ -287,7 +280,8 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
|
||||
let slot_duration = sc_consensus_aura::slot_duration(&*client)?;
|
||||
let raw_slot_duration = slot_duration.slot_duration();
|
||||
let aura = sc_consensus_aura::start_aura::<AuraPair, _, _, _, _, _, _, _, _, _, _>(StartAuraParams {
|
||||
|
||||
let aura = sc_consensus_aura::start_aura::<AuraPair, _, _, _, _, _, _, _, _, _, _, _>(StartAuraParams {
|
||||
slot_duration,
|
||||
client,
|
||||
select_chain,
|
||||
@@ -308,7 +302,9 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
keystore: keystore_container.sync_keystore(),
|
||||
can_author_with,
|
||||
sync_oracle: network.clone(),
|
||||
justification_sync_link: network.clone(),
|
||||
block_proposal_slot_portion: SlotProportion::new(2f32 / 3f32),
|
||||
max_block_proposal_slot_portion: None,
|
||||
telemetry: telemetry.as_ref().map(|x| x.handle()),
|
||||
})?;
|
||||
|
||||
@@ -332,7 +328,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
name: Some(name),
|
||||
observer_enabled: false,
|
||||
keystore,
|
||||
is_authority: role.is_authority(),
|
||||
local_role: role,
|
||||
telemetry: telemetry.as_ref().map(|x| x.handle()),
|
||||
};
|
||||
|
||||
@@ -349,7 +345,7 @@ pub fn new_full(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
network,
|
||||
voting_rule: sc_finality_grandpa::VotingRulesBuilder::default().build(),
|
||||
prometheus_registry,
|
||||
shared_voter_state: SharedVoterState::empty(),
|
||||
shared_voter_state,
|
||||
telemetry: telemetry.as_ref().map(|x| x.handle()),
|
||||
};
|
||||
|
||||
@@ -398,24 +394,22 @@ pub fn new_light(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
let transaction_pool = Arc::new(sc_transaction_pool::BasicPool::new_light(
|
||||
config.transaction_pool.clone(),
|
||||
config.prometheus_registry(),
|
||||
task_manager.spawn_handle(),
|
||||
task_manager.spawn_essential_handle(),
|
||||
client.clone(),
|
||||
on_demand.clone(),
|
||||
));
|
||||
|
||||
let (grandpa_block_import, _) = sc_finality_grandpa::block_import(
|
||||
let (grandpa_block_import, grandpa_link) = sc_finality_grandpa::block_import(
|
||||
client.clone(),
|
||||
&(client.clone() as Arc<_>),
|
||||
select_chain,
|
||||
telemetry.as_ref().map(|x| x.handle()),
|
||||
)?;
|
||||
|
||||
let aura_block_import =
|
||||
sc_consensus_aura::AuraBlockImport::<_, _, _, AuraPair>::new(grandpa_block_import.clone(), client.clone());
|
||||
|
||||
let slot_duration = sc_consensus_aura::slot_duration(&*client)?.slot_duration();
|
||||
|
||||
let import_queue = sc_consensus_aura::import_queue::<AuraPair, _, _, _, _, _, _>(ImportQueueParams {
|
||||
block_import: aura_block_import,
|
||||
block_import: grandpa_block_import.clone(),
|
||||
justification_import: Some(Box::new(grandpa_block_import)),
|
||||
client: client.clone(),
|
||||
create_inherent_data_providers: move |_, ()| async move {
|
||||
@@ -435,21 +429,40 @@ pub fn new_light(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
telemetry: telemetry.as_ref().map(|x| x.handle()),
|
||||
})?;
|
||||
|
||||
let (network, network_status_sinks, system_rpc_tx, network_starter) =
|
||||
sc_service::build_network(sc_service::BuildNetworkParams {
|
||||
config: &config,
|
||||
client: client.clone(),
|
||||
transaction_pool: transaction_pool.clone(),
|
||||
spawn_handle: task_manager.spawn_handle(),
|
||||
import_queue,
|
||||
on_demand: Some(on_demand.clone()),
|
||||
block_announce_validator_builder: None,
|
||||
})?;
|
||||
let (network, system_rpc_tx, network_starter) = sc_service::build_network(sc_service::BuildNetworkParams {
|
||||
config: &config,
|
||||
client: client.clone(),
|
||||
transaction_pool: transaction_pool.clone(),
|
||||
spawn_handle: task_manager.spawn_handle(),
|
||||
import_queue,
|
||||
on_demand: Some(on_demand.clone()),
|
||||
block_announce_validator_builder: None,
|
||||
})?;
|
||||
|
||||
if config.offchain_worker.enabled {
|
||||
sc_service::build_offchain_workers(&config, task_manager.spawn_handle(), client.clone(), network.clone());
|
||||
}
|
||||
|
||||
let enable_grandpa = !config.disable_grandpa;
|
||||
if enable_grandpa {
|
||||
let name = config.network.node_name.clone();
|
||||
|
||||
let config = sc_finality_grandpa::Config {
|
||||
gossip_duration: std::time::Duration::from_millis(333),
|
||||
justification_period: 512,
|
||||
name: Some(name),
|
||||
observer_enabled: false,
|
||||
keystore: None,
|
||||
local_role: config.role.clone(),
|
||||
telemetry: telemetry.as_ref().map(|x| x.handle()),
|
||||
};
|
||||
|
||||
task_manager.spawn_handle().spawn_blocking(
|
||||
"grandpa-observer",
|
||||
sc_finality_grandpa::run_grandpa_observer(config, grandpa_link, network.clone())?,
|
||||
);
|
||||
}
|
||||
|
||||
sc_service::spawn_tasks(sc_service::SpawnTasksParams {
|
||||
remote_blockchain: Some(backend.remote_blockchain()),
|
||||
transaction_pool,
|
||||
@@ -461,12 +474,10 @@ pub fn new_light(mut config: Configuration) -> Result<TaskManager, ServiceError>
|
||||
keystore: keystore_container.sync_keystore(),
|
||||
backend,
|
||||
network,
|
||||
network_status_sinks,
|
||||
system_rpc_tx,
|
||||
telemetry: telemetry.as_mut(),
|
||||
})?;
|
||||
|
||||
network_starter.start_network();
|
||||
|
||||
Ok(task_manager)
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ sp-version = { git = "https://github.com/paritytech/substrate", branch = "master
|
||||
libsecp256k1 = { version = "0.3.4", features = ["hmac"] }
|
||||
|
||||
[build-dependencies]
|
||||
substrate-wasm-builder = "3.0.0"
|
||||
substrate-wasm-builder = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
|
||||
@@ -359,6 +359,7 @@ parameter_types! {
|
||||
// For weight estimation, we assume that the most locks on an individual account will be 50.
|
||||
// This number may need to be adjusted in the future if this assumption no longer holds true.
|
||||
pub const MaxLocks: u32 = 50;
|
||||
pub const MaxReserves: u32 = 50;
|
||||
}
|
||||
|
||||
impl pallet_balances::Config for Runtime {
|
||||
@@ -372,6 +373,8 @@ impl pallet_balances::Config for Runtime {
|
||||
// TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78)
|
||||
type WeightInfo = ();
|
||||
type MaxLocks = MaxLocks;
|
||||
type MaxReserves = MaxReserves;
|
||||
type ReserveIdentifier = [u8; 8];
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
@@ -488,6 +491,7 @@ impl pallet_bridge_messages::Config<WithMillauMessagesInstance> for Runtime {
|
||||
GetDeliveryConfirmationTransactionFee,
|
||||
RootAccountForPayments,
|
||||
>;
|
||||
type OnDeliveryConfirmed = ();
|
||||
|
||||
type SourceHeaderChain = crate::millau_messages::Millau;
|
||||
type MessageDispatch = crate::millau_messages::FromMillauMessageDispatch;
|
||||
@@ -751,17 +755,23 @@ impl_runtime_apis! {
|
||||
).ok()
|
||||
}
|
||||
|
||||
fn messages_dispatch_weight(
|
||||
fn message_details(
|
||||
lane: bp_messages::LaneId,
|
||||
begin: bp_messages::MessageNonce,
|
||||
end: bp_messages::MessageNonce,
|
||||
) -> Vec<(bp_messages::MessageNonce, Weight, u32)> {
|
||||
) -> Vec<bp_messages::MessageDetails<Balance>> {
|
||||
(begin..=end).filter_map(|nonce| {
|
||||
let encoded_payload = BridgeMillauMessages::outbound_message_payload(lane, nonce)?;
|
||||
let message_data = BridgeMillauMessages::outbound_message_data(lane, nonce)?;
|
||||
let decoded_payload = millau_messages::ToMillauMessagePayload::decode(
|
||||
&mut &encoded_payload[..]
|
||||
&mut &message_data.payload[..]
|
||||
).ok()?;
|
||||
Some((nonce, decoded_payload.weight, encoded_payload.len() as _))
|
||||
Some(bp_messages::MessageDetails {
|
||||
nonce,
|
||||
dispatch_weight: decoded_payload.weight,
|
||||
size: message_data.payload.len() as _,
|
||||
delivery_and_dispatch_fee: message_data.fee,
|
||||
dispatch_fee_payment: decoded_payload.dispatch_fee_payment,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
@@ -853,6 +863,7 @@ impl_runtime_apis! {
|
||||
}
|
||||
|
||||
use crate::millau_messages::{ToMillauMessagePayload, WithMillauMessageBridge};
|
||||
use bp_runtime::messages::DispatchFeePayment;
|
||||
use bridge_runtime_common::messages;
|
||||
use pallet_bridge_messages::benchmarking::{
|
||||
Pallet as MessagesBench,
|
||||
@@ -896,6 +907,7 @@ impl_runtime_apis! {
|
||||
weight: params.size as _,
|
||||
origin: dispatch_origin,
|
||||
call: message_payload,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
|
||||
};
|
||||
(message, pallet_bridge_messages::benchmarking::MESSAGE_FEE.into())
|
||||
}
|
||||
@@ -903,16 +915,16 @@ impl_runtime_apis! {
|
||||
fn prepare_message_proof(
|
||||
params: MessageProofParams,
|
||||
) -> (millau_messages::FromMillauMessagesProof, Weight) {
|
||||
use crate::millau_messages::{Millau, WithMillauMessageBridge};
|
||||
use crate::millau_messages::WithMillauMessageBridge;
|
||||
use bp_messages::MessageKey;
|
||||
use bridge_runtime_common::{
|
||||
messages::ChainWithMessages,
|
||||
messages::MessageBridge,
|
||||
messages_benchmarking::{ed25519_sign, prepare_message_proof},
|
||||
};
|
||||
use codec::Encode;
|
||||
use frame_support::weights::GetDispatchInfo;
|
||||
use pallet_bridge_messages::storage_keys;
|
||||
use sp_runtime::traits::Header;
|
||||
use sp_runtime::traits::{Header, IdentifyAccount};
|
||||
|
||||
let remark = match params.size {
|
||||
MessagesProofSize::Minimal(ref size) => vec![0u8; *size as _],
|
||||
@@ -925,20 +937,26 @@ impl_runtime_apis! {
|
||||
let (rialto_raw_public, rialto_raw_signature) = ed25519_sign(
|
||||
&call,
|
||||
&millau_account_id,
|
||||
VERSION.spec_version,
|
||||
bp_runtime::MILLAU_CHAIN_ID,
|
||||
bp_runtime::RIALTO_CHAIN_ID,
|
||||
);
|
||||
let rialto_public = MultiSigner::Ed25519(sp_core::ed25519::Public::from_raw(rialto_raw_public));
|
||||
let rialto_signature = MultiSignature::Ed25519(sp_core::ed25519::Signature::from_raw(
|
||||
rialto_raw_signature,
|
||||
));
|
||||
|
||||
if params.dispatch_fee_payment == DispatchFeePayment::AtTargetChain {
|
||||
Self::endow_account(&rialto_public.clone().into_account());
|
||||
}
|
||||
|
||||
let make_millau_message_key = |message_key: MessageKey| storage_keys::message_key::<
|
||||
Runtime,
|
||||
<Millau as ChainWithMessages>::MessagesInstance,
|
||||
<WithMillauMessageBridge as MessageBridge>::BridgedMessagesInstance,
|
||||
>(
|
||||
&message_key.lane_id, message_key.nonce,
|
||||
).0;
|
||||
let make_millau_outbound_lane_data_key = |lane_id| storage_keys::outbound_lane_data_key::<
|
||||
<Millau as ChainWithMessages>::MessagesInstance,
|
||||
<WithMillauMessageBridge as MessageBridge>::BridgedMessagesInstance,
|
||||
>(
|
||||
&lane_id,
|
||||
).0;
|
||||
@@ -951,6 +969,7 @@ impl_runtime_apis! {
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
let dispatch_fee_payment = params.dispatch_fee_payment.clone();
|
||||
prepare_message_proof::<WithMillauMessageBridge, bp_millau::Hasher, Runtime, (), _, _, _>(
|
||||
params,
|
||||
make_millau_message_key,
|
||||
@@ -969,6 +988,7 @@ impl_runtime_apis! {
|
||||
rialto_public,
|
||||
rialto_signature,
|
||||
),
|
||||
dispatch_fee_payment,
|
||||
call: call.encode(),
|
||||
}.encode(),
|
||||
)
|
||||
@@ -977,18 +997,14 @@ impl_runtime_apis! {
|
||||
fn prepare_message_delivery_proof(
|
||||
params: MessageDeliveryProofParams<Self::AccountId>,
|
||||
) -> millau_messages::ToMillauMessagesDeliveryProof {
|
||||
use crate::millau_messages::{Millau, WithMillauMessageBridge};
|
||||
use bridge_runtime_common::{
|
||||
messages::ChainWithMessages,
|
||||
messages_benchmarking::prepare_message_delivery_proof,
|
||||
};
|
||||
use crate::millau_messages::WithMillauMessageBridge;
|
||||
use bridge_runtime_common::{messages_benchmarking::prepare_message_delivery_proof};
|
||||
use sp_runtime::traits::Header;
|
||||
|
||||
prepare_message_delivery_proof::<WithMillauMessageBridge, bp_millau::Hasher, Runtime, (), _, _>(
|
||||
params,
|
||||
|lane_id| pallet_bridge_messages::storage_keys::inbound_lane_data_key::<
|
||||
Runtime,
|
||||
<Millau as ChainWithMessages>::MessagesInstance,
|
||||
<WithMillauMessageBridge as MessageBridge>::BridgedMessagesInstance,
|
||||
>(
|
||||
&lane_id,
|
||||
).0,
|
||||
@@ -1001,6 +1017,18 @@ impl_runtime_apis! {
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fn is_message_dispatched(nonce: bp_messages::MessageNonce) -> bool {
|
||||
frame_system::Pallet::<Runtime>::events()
|
||||
.into_iter()
|
||||
.map(|event_record| event_record.event)
|
||||
.any(|event| matches!(
|
||||
event,
|
||||
Event::BridgeDispatch(pallet_bridge_dispatch::Event::<Runtime, _>::MessageDispatched(
|
||||
_, ([0, 0, 0, 0], nonce_from_event), _,
|
||||
)) if nonce_from_event == nonce
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
add_benchmark!(
|
||||
@@ -1028,7 +1056,7 @@ impl_runtime_apis! {
|
||||
/// The byte vector returned by this function should be signed with a Millau account private key.
|
||||
/// This way, the owner of `rialto_account_id` on Rialto proves that the 'millau' account private key
|
||||
/// is also under his control.
|
||||
pub fn millau_account_ownership_digest<Call, AccountId, SpecVersion>(
|
||||
pub fn rialto_to_millau_account_ownership_digest<Call, AccountId, SpecVersion>(
|
||||
millau_call: &Call,
|
||||
rialto_account_id: AccountId,
|
||||
millau_spec_version: SpecVersion,
|
||||
@@ -1042,7 +1070,8 @@ where
|
||||
millau_call,
|
||||
rialto_account_id,
|
||||
millau_spec_version,
|
||||
bp_runtime::RIALTO_BRIDGE_INSTANCE,
|
||||
bp_runtime::RIALTO_CHAIN_ID,
|
||||
bp_runtime::MILLAU_CHAIN_ID,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1095,6 +1124,7 @@ mod tests {
|
||||
bp_rialto::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT,
|
||||
bp_rialto::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT,
|
||||
bp_rialto::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT,
|
||||
bp_rialto::PAY_INBOUND_DISPATCH_FEE_WEIGHT,
|
||||
);
|
||||
|
||||
let max_incoming_message_proof_size = bp_millau::EXTRA_STORAGE_PROOF_SIZE.saturating_add(
|
||||
@@ -1110,6 +1140,7 @@ mod tests {
|
||||
let max_incoming_inbound_lane_data_proof_size = bp_messages::InboundLaneData::<()>::encoded_size_hint(
|
||||
bp_rialto::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE,
|
||||
bp_millau::MAX_UNREWARDED_RELAYER_ENTRIES_AT_INBOUND_LANE as _,
|
||||
bp_millau::MAX_UNCONFIRMED_MESSAGES_AT_INBOUND_LANE as _,
|
||||
)
|
||||
.unwrap_or(u32::MAX);
|
||||
pallet_bridge_messages::ensure_able_to_receive_confirmation::<Weights>(
|
||||
|
||||
@@ -23,7 +23,7 @@ use bp_messages::{
|
||||
target_chain::{ProvedMessages, SourceHeaderChain},
|
||||
InboundLaneData, LaneId, Message, MessageNonce, Parameter as MessagesParameter,
|
||||
};
|
||||
use bp_runtime::{InstanceId, MILLAU_BRIDGE_INSTANCE};
|
||||
use bp_runtime::{ChainId, MILLAU_CHAIN_ID, RIALTO_CHAIN_ID};
|
||||
use bridge_runtime_common::messages::{self, MessageBridge, MessageTransaction};
|
||||
use codec::{Decode, Encode};
|
||||
use frame_support::{
|
||||
@@ -52,12 +52,13 @@ pub type ToMillauMessageVerifier = messages::source::FromThisChainMessageVerifie
|
||||
pub type FromMillauMessagePayload = messages::target::FromBridgedChainMessagePayload<WithMillauMessageBridge>;
|
||||
|
||||
/// Encoded Rialto Call as it comes from Millau.
|
||||
pub type FromMillauEncodedCall = messages::target::FromBridgedChainEncodedMessageCall<WithMillauMessageBridge>;
|
||||
pub type FromMillauEncodedCall = messages::target::FromBridgedChainEncodedMessageCall<crate::Call>;
|
||||
|
||||
/// Call-dispatch based message dispatch for Millau -> Rialto messages.
|
||||
pub type FromMillauMessageDispatch = messages::target::FromBridgedChainMessageDispatch<
|
||||
WithMillauMessageBridge,
|
||||
crate::Runtime,
|
||||
pallet_balances::Pallet<Runtime>,
|
||||
pallet_bridge_dispatch::DefaultInstance,
|
||||
>;
|
||||
|
||||
@@ -72,12 +73,13 @@ pub type ToMillauMessagesDeliveryProof = messages::source::FromBridgedChainMessa
|
||||
pub struct WithMillauMessageBridge;
|
||||
|
||||
impl MessageBridge for WithMillauMessageBridge {
|
||||
const INSTANCE: InstanceId = MILLAU_BRIDGE_INSTANCE;
|
||||
|
||||
const RELAYER_FEE_PERCENT: u32 = 10;
|
||||
const THIS_CHAIN_ID: ChainId = RIALTO_CHAIN_ID;
|
||||
const BRIDGED_CHAIN_ID: ChainId = MILLAU_CHAIN_ID;
|
||||
|
||||
type ThisChain = Rialto;
|
||||
type BridgedChain = Millau;
|
||||
type BridgedMessagesInstance = crate::WithMillauMessagesInstance;
|
||||
|
||||
fn bridged_balance_to_this_balance(bridged_balance: bp_millau::Balance) -> bp_rialto::Balance {
|
||||
bp_rialto::Balance::try_from(MillauToRialtoConversionRate::get().saturating_mul_int(bridged_balance))
|
||||
@@ -96,8 +98,6 @@ impl messages::ChainWithMessages for Rialto {
|
||||
type Signature = bp_rialto::Signature;
|
||||
type Weight = Weight;
|
||||
type Balance = bp_rialto::Balance;
|
||||
|
||||
type MessagesInstance = crate::WithMillauMessagesInstance;
|
||||
}
|
||||
|
||||
impl messages::ThisChainWithMessages for Rialto {
|
||||
@@ -112,9 +112,12 @@ impl messages::ThisChainWithMessages for Rialto {
|
||||
}
|
||||
|
||||
fn estimate_delivery_confirmation_transaction() -> MessageTransaction<Weight> {
|
||||
let inbound_data_size =
|
||||
InboundLaneData::<bp_rialto::AccountId>::encoded_size_hint(bp_rialto::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE, 1)
|
||||
.unwrap_or(u32::MAX);
|
||||
let inbound_data_size = InboundLaneData::<bp_rialto::AccountId>::encoded_size_hint(
|
||||
bp_rialto::MAXIMAL_ENCODED_ACCOUNT_ID_SIZE,
|
||||
1,
|
||||
1,
|
||||
)
|
||||
.unwrap_or(u32::MAX);
|
||||
|
||||
MessageTransaction {
|
||||
dispatch_weight: bp_rialto::MAX_SINGLE_MESSAGE_DELIVERY_CONFIRMATION_TX_WEIGHT,
|
||||
@@ -147,8 +150,6 @@ impl messages::ChainWithMessages for Millau {
|
||||
type Signature = bp_millau::Signature;
|
||||
type Weight = Weight;
|
||||
type Balance = bp_millau::Balance;
|
||||
|
||||
type MessagesInstance = pallet_bridge_messages::DefaultInstance;
|
||||
}
|
||||
|
||||
impl messages::BridgedChainWithMessages for Millau {
|
||||
@@ -170,6 +171,7 @@ impl messages::BridgedChainWithMessages for Millau {
|
||||
|
||||
fn estimate_delivery_transaction(
|
||||
message_payload: &[u8],
|
||||
include_pay_dispatch_fee_cost: bool,
|
||||
message_dispatch_weight: Weight,
|
||||
) -> MessageTransaction<Weight> {
|
||||
let message_payload_len = u32::try_from(message_payload.len()).unwrap_or(u32::MAX);
|
||||
@@ -180,6 +182,11 @@ impl messages::BridgedChainWithMessages for Millau {
|
||||
dispatch_weight: extra_bytes_in_payload
|
||||
.saturating_mul(bp_millau::ADDITIONAL_MESSAGE_BYTE_DELIVERY_WEIGHT)
|
||||
.saturating_add(bp_millau::DEFAULT_MESSAGE_DELIVERY_TX_WEIGHT)
|
||||
.saturating_sub(if include_pay_dispatch_fee_cost {
|
||||
0
|
||||
} else {
|
||||
bp_millau::PAY_INBOUND_DISPATCH_FEE_WEIGHT
|
||||
})
|
||||
.saturating_add(message_dispatch_weight),
|
||||
size: message_payload_len
|
||||
.saturating_add(bp_rialto::EXTRA_STORAGE_PROOF_SIZE)
|
||||
@@ -256,3 +263,87 @@ impl MessagesParameter for RialtoToMillauMessagesParameter {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::{AccountId, Call, ExistentialDeposit, Runtime, SystemCall, SystemConfig, VERSION};
|
||||
use bp_message_dispatch::CallOrigin;
|
||||
use bp_messages::{
|
||||
target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch},
|
||||
MessageKey,
|
||||
};
|
||||
use bp_runtime::{derive_account_id, messages::DispatchFeePayment, SourceAccount};
|
||||
use bridge_runtime_common::messages::target::{FromBridgedChainEncodedMessageCall, FromBridgedChainMessagePayload};
|
||||
use frame_support::{
|
||||
traits::Currency,
|
||||
weights::{GetDispatchInfo, WeightToFeePolynomial},
|
||||
};
|
||||
use sp_runtime::traits::Convert;
|
||||
|
||||
#[test]
|
||||
fn transfer_happens_when_dispatch_fee_is_paid_at_target_chain() {
|
||||
// this test actually belongs to the `bridge-runtime-common` crate, but there we have no
|
||||
// mock runtime. Making another one there just for this test, given that both crates
|
||||
// live n single repo is an overkill
|
||||
let mut ext: sp_io::TestExternalities = SystemConfig::default().build_storage::<Runtime>().unwrap().into();
|
||||
ext.execute_with(|| {
|
||||
let bridge = MILLAU_CHAIN_ID;
|
||||
let call: Call = SystemCall::remark(vec![]).into();
|
||||
let dispatch_weight = call.get_dispatch_info().weight;
|
||||
let dispatch_fee = <Runtime as pallet_transaction_payment::Config>::WeightToFee::calc(&dispatch_weight);
|
||||
assert!(dispatch_fee > 0);
|
||||
|
||||
// create relayer account with minimal balance
|
||||
let relayer_account: AccountId = [1u8; 32].into();
|
||||
let initial_amount = ExistentialDeposit::get();
|
||||
let _ = <pallet_balances::Pallet<Runtime> as Currency<AccountId>>::deposit_creating(
|
||||
&relayer_account,
|
||||
initial_amount,
|
||||
);
|
||||
|
||||
// create dispatch account with minimal balance + dispatch fee
|
||||
let dispatch_account = derive_account_id::<<Runtime as pallet_bridge_dispatch::Config>::SourceChainAccountId>(
|
||||
bridge,
|
||||
SourceAccount::Root,
|
||||
);
|
||||
let dispatch_account =
|
||||
<Runtime as pallet_bridge_dispatch::Config>::AccountIdConverter::convert(dispatch_account);
|
||||
let _ = <pallet_balances::Pallet<Runtime> as Currency<AccountId>>::deposit_creating(
|
||||
&dispatch_account,
|
||||
initial_amount + dispatch_fee,
|
||||
);
|
||||
|
||||
// dispatch message with intention to pay dispatch fee at the target chain
|
||||
FromMillauMessageDispatch::dispatch(
|
||||
&relayer_account,
|
||||
DispatchMessage {
|
||||
key: MessageKey {
|
||||
lane_id: Default::default(),
|
||||
nonce: 0,
|
||||
},
|
||||
data: DispatchMessageData {
|
||||
payload: Ok(FromBridgedChainMessagePayload::<WithMillauMessageBridge> {
|
||||
spec_version: VERSION.spec_version,
|
||||
weight: dispatch_weight,
|
||||
origin: CallOrigin::SourceRoot,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
|
||||
call: FromBridgedChainEncodedMessageCall::new(call.encode()),
|
||||
}),
|
||||
fee: 1,
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
// ensure that fee has been transferred from dispatch to relayer account
|
||||
assert_eq!(
|
||||
<pallet_balances::Pallet<Runtime> as Currency<AccountId>>::free_balance(&relayer_account),
|
||||
initial_amount + dispatch_fee,
|
||||
);
|
||||
assert_eq!(
|
||||
<pallet_balances::Pallet<Runtime> as Currency<AccountId>>::free_balance(&dispatch_account),
|
||||
initial_amount,
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@ pallet-bridge-messages = { path = "../../modules/messages", default-features = f
|
||||
# Substrate dependencies
|
||||
|
||||
frame-support = { git = "https://github.com/paritytech/substrate", branch = "master" , default-features = false }
|
||||
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" , default-features = false }
|
||||
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-state-machine = { git = "https://github.com/paritytech/substrate", branch = "master" , default-features = false, optional = true }
|
||||
@@ -42,6 +43,7 @@ std = [
|
||||
"pallet-bridge-dispatch/std",
|
||||
"pallet-bridge-grandpa/std",
|
||||
"pallet-bridge-messages/std",
|
||||
"pallet-transaction-payment/std",
|
||||
"sp-core/std",
|
||||
"sp-runtime/std",
|
||||
"sp-state-machine/std",
|
||||
|
||||
@@ -102,7 +102,9 @@ This trait represents this chain from bridge point of view. Let's review every m
|
||||
have declared dispatch weight larger than 50% of the maximal bridged extrinsic weight.
|
||||
|
||||
- `MessageBridge::estimate_delivery_transaction`: you will need to return estimated dispatch weight and
|
||||
size of the delivery transaction that delivers a given message to the target chain.
|
||||
size of the delivery transaction that delivers a given message to the target chain. The transaction
|
||||
weight must or must not include the weight of pay-dispatch-fee operation, depending on the value
|
||||
of `include_pay_dispatch_fee_cost` argument.
|
||||
|
||||
- `MessageBridge::transaction_payment`: you'll need to return fee that the submitter
|
||||
must pay for given transaction on bridged chain. The best case is when you have the same conversion
|
||||
|
||||
@@ -26,9 +26,16 @@ use bp_messages::{
|
||||
target_chain::{DispatchMessage, MessageDispatch, ProvedLaneMessages, ProvedMessages},
|
||||
InboundLaneData, LaneId, Message, MessageData, MessageKey, MessageNonce, OutboundLaneData,
|
||||
};
|
||||
use bp_runtime::{InstanceId, Size, StorageProofChecker};
|
||||
use bp_runtime::{
|
||||
messages::{DispatchFeePayment, MessageDispatchResult},
|
||||
ChainId, Size, StorageProofChecker,
|
||||
};
|
||||
use codec::{Decode, Encode};
|
||||
use frame_support::{traits::Instance, weights::Weight, RuntimeDebug};
|
||||
use frame_support::{
|
||||
traits::{Currency, ExistenceRequirement, Instance},
|
||||
weights::{Weight, WeightToFeePolynomial},
|
||||
RuntimeDebug,
|
||||
};
|
||||
use hash_db::Hasher;
|
||||
use sp_runtime::{
|
||||
traits::{AtLeast32BitUnsigned, CheckedAdd, CheckedDiv, CheckedMul},
|
||||
@@ -39,16 +46,20 @@ use sp_trie::StorageProof;
|
||||
|
||||
/// Bidirectional message bridge.
|
||||
pub trait MessageBridge {
|
||||
/// Instance id of this bridge.
|
||||
const INSTANCE: InstanceId;
|
||||
|
||||
/// Relayer interest (in percents).
|
||||
const RELAYER_FEE_PERCENT: u32;
|
||||
|
||||
/// Identifier of this chain.
|
||||
const THIS_CHAIN_ID: ChainId;
|
||||
/// Identifier of the Bridged chain.
|
||||
const BRIDGED_CHAIN_ID: ChainId;
|
||||
|
||||
/// This chain in context of message bridge.
|
||||
type ThisChain: ThisChainWithMessages;
|
||||
/// Bridged chain in context of message bridge.
|
||||
type BridgedChain: BridgedChainWithMessages;
|
||||
/// Instance of the `pallet-bridge-messages` pallet at the Bridged chain.
|
||||
type BridgedMessagesInstance: Instance;
|
||||
|
||||
/// Convert Bridged chain balance into This chain balance.
|
||||
fn bridged_balance_to_this_balance(bridged_balance: BalanceOf<BridgedChain<Self>>) -> BalanceOf<ThisChain<Self>>;
|
||||
@@ -71,9 +82,6 @@ pub trait ChainWithMessages {
|
||||
type Weight: From<frame_support::weights::Weight> + PartialOrd;
|
||||
/// Type of balances that is used on the chain.
|
||||
type Balance: Encode + Decode + CheckedAdd + CheckedDiv + CheckedMul + PartialOrd + From<u32> + Copy;
|
||||
|
||||
/// Instance of the `pallet-bridge-messages` pallet.
|
||||
type MessagesInstance: Instance;
|
||||
}
|
||||
|
||||
/// Message related transaction parameters estimation.
|
||||
@@ -124,6 +132,7 @@ pub trait BridgedChainWithMessages: ChainWithMessages {
|
||||
/// Estimate size and weight of single message delivery transaction at the Bridged chain.
|
||||
fn estimate_delivery_transaction(
|
||||
message_payload: &[u8],
|
||||
include_pay_dispatch_fee_cost: bool,
|
||||
message_dispatch_weight: WeightOf<Self>,
|
||||
) -> MessageTransaction<WeightOf<Self>>;
|
||||
|
||||
@@ -139,7 +148,6 @@ pub(crate) type SignerOf<C> = <C as ChainWithMessages>::Signer;
|
||||
pub(crate) type SignatureOf<C> = <C as ChainWithMessages>::Signature;
|
||||
pub(crate) type WeightOf<C> = <C as ChainWithMessages>::Weight;
|
||||
pub(crate) type BalanceOf<C> = <C as ChainWithMessages>::Balance;
|
||||
pub(crate) type MessagesInstanceOf<C> = <C as ChainWithMessages>::MessagesInstance;
|
||||
|
||||
pub(crate) type CallOf<C> = <C as ThisChainWithMessages>::Call;
|
||||
|
||||
@@ -326,8 +334,19 @@ pub mod source {
|
||||
relayer_fee_percent: u32,
|
||||
) -> Result<BalanceOf<ThisChain<B>>, &'static str> {
|
||||
// the fee (in Bridged tokens) of all transactions that are made on the Bridged chain
|
||||
let delivery_transaction =
|
||||
BridgedChain::<B>::estimate_delivery_transaction(&payload.call, payload.weight.into());
|
||||
//
|
||||
// if we're going to pay dispatch fee at the target chain, then we don't include weight
|
||||
// of the message dispatch in the delivery transaction cost
|
||||
let pay_dispatch_fee_at_target_chain = payload.dispatch_fee_payment == DispatchFeePayment::AtTargetChain;
|
||||
let delivery_transaction = BridgedChain::<B>::estimate_delivery_transaction(
|
||||
&payload.call,
|
||||
pay_dispatch_fee_at_target_chain,
|
||||
if pay_dispatch_fee_at_target_chain {
|
||||
0.into()
|
||||
} else {
|
||||
payload.weight.into()
|
||||
},
|
||||
);
|
||||
let delivery_transaction_fee = BridgedChain::<B>::transaction_payment(delivery_transaction);
|
||||
|
||||
// the fee (in This tokens) of all transactions that are made on This chain
|
||||
@@ -357,7 +376,6 @@ pub mod source {
|
||||
) -> Result<ParsedMessagesDeliveryProofFromBridgedChain<B>, &'static str>
|
||||
where
|
||||
ThisRuntime: pallet_bridge_grandpa::Config<GrandpaInstance>,
|
||||
ThisRuntime: pallet_bridge_messages::Config<MessagesInstanceOf<BridgedChain<B>>>,
|
||||
HashOf<BridgedChain<B>>:
|
||||
Into<bp_runtime::HashOf<<ThisRuntime as pallet_bridge_grandpa::Config<GrandpaInstance>>::BridgedChain>>,
|
||||
{
|
||||
@@ -372,10 +390,8 @@ pub mod source {
|
||||
|storage| {
|
||||
// Messages delivery proof is just proof of single storage key read => any error
|
||||
// is fatal.
|
||||
let storage_inbound_lane_data_key = pallet_bridge_messages::storage_keys::inbound_lane_data_key::<
|
||||
ThisRuntime,
|
||||
MessagesInstanceOf<BridgedChain<B>>,
|
||||
>(&lane);
|
||||
let storage_inbound_lane_data_key =
|
||||
pallet_bridge_messages::storage_keys::inbound_lane_data_key::<B::BridgedMessagesInstance>(&lane);
|
||||
let raw_inbound_lane_data = storage
|
||||
.read_value(storage_inbound_lane_data_key.0.as_ref())
|
||||
.map_err(|_| "Failed to read inbound lane state from storage proof")?
|
||||
@@ -406,7 +422,7 @@ pub mod target {
|
||||
AccountIdOf<BridgedChain<B>>,
|
||||
SignerOf<ThisChain<B>>,
|
||||
SignatureOf<ThisChain<B>>,
|
||||
FromBridgedChainEncodedMessageCall<B>,
|
||||
FromBridgedChainEncodedMessageCall<CallOf<ThisChain<B>>>,
|
||||
>;
|
||||
|
||||
/// Messages proof from bridged chain:
|
||||
@@ -444,33 +460,51 @@ pub mod target {
|
||||
/// Our Call is opaque (`Vec<u8>`) for Bridged chain. So it is encoded, prefixed with
|
||||
/// vector length. Custom decode implementation here is exactly to deal with this.
|
||||
#[derive(Decode, Encode, RuntimeDebug, PartialEq)]
|
||||
pub struct FromBridgedChainEncodedMessageCall<B> {
|
||||
pub(crate) encoded_call: Vec<u8>,
|
||||
pub(crate) _marker: PhantomData<B>,
|
||||
pub struct FromBridgedChainEncodedMessageCall<DecodedCall> {
|
||||
encoded_call: Vec<u8>,
|
||||
_marker: PhantomData<DecodedCall>,
|
||||
}
|
||||
|
||||
impl<B: MessageBridge> From<FromBridgedChainEncodedMessageCall<B>> for Result<CallOf<ThisChain<B>>, ()> {
|
||||
fn from(encoded_call: FromBridgedChainEncodedMessageCall<B>) -> Self {
|
||||
CallOf::<ThisChain<B>>::decode(&mut &encoded_call.encoded_call[..]).map_err(drop)
|
||||
impl<DecodedCall> FromBridgedChainEncodedMessageCall<DecodedCall> {
|
||||
/// Create encoded call.
|
||||
pub fn new(encoded_call: Vec<u8>) -> Self {
|
||||
FromBridgedChainEncodedMessageCall {
|
||||
encoded_call,
|
||||
_marker: PhantomData::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<DecodedCall: Decode> From<FromBridgedChainEncodedMessageCall<DecodedCall>> for Result<DecodedCall, ()> {
|
||||
fn from(encoded_call: FromBridgedChainEncodedMessageCall<DecodedCall>) -> Self {
|
||||
DecodedCall::decode(&mut &encoded_call.encoded_call[..]).map_err(drop)
|
||||
}
|
||||
}
|
||||
|
||||
/// Dispatching Bridged -> This chain messages.
|
||||
#[derive(RuntimeDebug, Clone, Copy)]
|
||||
pub struct FromBridgedChainMessageDispatch<B, ThisRuntime, ThisDispatchInstance> {
|
||||
_marker: PhantomData<(B, ThisRuntime, ThisDispatchInstance)>,
|
||||
pub struct FromBridgedChainMessageDispatch<B, ThisRuntime, ThisCurrency, ThisDispatchInstance> {
|
||||
_marker: PhantomData<(B, ThisRuntime, ThisCurrency, ThisDispatchInstance)>,
|
||||
}
|
||||
|
||||
impl<B: MessageBridge, ThisRuntime, ThisDispatchInstance>
|
||||
MessageDispatch<<BridgedChain<B> as ChainWithMessages>::Balance>
|
||||
for FromBridgedChainMessageDispatch<B, ThisRuntime, ThisDispatchInstance>
|
||||
impl<B: MessageBridge, ThisRuntime, ThisCurrency, ThisDispatchInstance>
|
||||
MessageDispatch<AccountIdOf<ThisChain<B>>, BalanceOf<BridgedChain<B>>>
|
||||
for FromBridgedChainMessageDispatch<B, ThisRuntime, ThisCurrency, ThisDispatchInstance>
|
||||
where
|
||||
ThisDispatchInstance: frame_support::traits::Instance,
|
||||
ThisRuntime: pallet_bridge_dispatch::Config<ThisDispatchInstance, MessageId = (LaneId, MessageNonce)>,
|
||||
<ThisRuntime as pallet_bridge_dispatch::Config<ThisDispatchInstance>>::Event:
|
||||
From<pallet_bridge_dispatch::RawEvent<(LaneId, MessageNonce), ThisDispatchInstance>>,
|
||||
pallet_bridge_dispatch::Pallet<ThisRuntime, ThisDispatchInstance>:
|
||||
bp_message_dispatch::MessageDispatch<(LaneId, MessageNonce), Message = FromBridgedChainMessagePayload<B>>,
|
||||
ThisRuntime: pallet_bridge_dispatch::Config<ThisDispatchInstance, MessageId = (LaneId, MessageNonce)>
|
||||
+ pallet_transaction_payment::Config,
|
||||
<ThisRuntime as pallet_transaction_payment::Config>::OnChargeTransaction:
|
||||
pallet_transaction_payment::OnChargeTransaction<ThisRuntime, Balance = BalanceOf<ThisChain<B>>>,
|
||||
ThisCurrency: Currency<AccountIdOf<ThisChain<B>>, Balance = BalanceOf<ThisChain<B>>>,
|
||||
<ThisRuntime as pallet_bridge_dispatch::Config<ThisDispatchInstance>>::Event: From<
|
||||
pallet_bridge_dispatch::RawEvent<(LaneId, MessageNonce), AccountIdOf<ThisChain<B>>, ThisDispatchInstance>,
|
||||
>,
|
||||
pallet_bridge_dispatch::Pallet<ThisRuntime, ThisDispatchInstance>: bp_message_dispatch::MessageDispatch<
|
||||
AccountIdOf<ThisChain<B>>,
|
||||
(LaneId, MessageNonce),
|
||||
Message = FromBridgedChainMessagePayload<B>,
|
||||
>,
|
||||
{
|
||||
type DispatchPayload = FromBridgedChainMessagePayload<B>;
|
||||
|
||||
@@ -480,13 +514,26 @@ pub mod target {
|
||||
message.data.payload.as_ref().map(|payload| payload.weight).unwrap_or(0)
|
||||
}
|
||||
|
||||
fn dispatch(message: DispatchMessage<Self::DispatchPayload, BalanceOf<BridgedChain<B>>>) {
|
||||
fn dispatch(
|
||||
relayer_account: &AccountIdOf<ThisChain<B>>,
|
||||
message: DispatchMessage<Self::DispatchPayload, BalanceOf<BridgedChain<B>>>,
|
||||
) -> MessageDispatchResult {
|
||||
let message_id = (message.key.lane_id, message.key.nonce);
|
||||
pallet_bridge_dispatch::Pallet::<ThisRuntime, ThisDispatchInstance>::dispatch(
|
||||
B::INSTANCE,
|
||||
B::BRIDGED_CHAIN_ID,
|
||||
B::THIS_CHAIN_ID,
|
||||
message_id,
|
||||
message.data.payload.map_err(drop),
|
||||
);
|
||||
|dispatch_origin, dispatch_weight| {
|
||||
ThisCurrency::transfer(
|
||||
dispatch_origin,
|
||||
relayer_account,
|
||||
ThisRuntime::WeightToFee::calc(&dispatch_weight),
|
||||
ExistenceRequirement::AllowDeath,
|
||||
)
|
||||
.map_err(drop)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -511,7 +558,7 @@ pub mod target {
|
||||
) -> Result<ProvedMessages<Message<BalanceOf<BridgedChain<B>>>>, &'static str>
|
||||
where
|
||||
ThisRuntime: pallet_bridge_grandpa::Config<GrandpaInstance>,
|
||||
ThisRuntime: pallet_bridge_messages::Config<MessagesInstanceOf<BridgedChain<B>>>,
|
||||
ThisRuntime: pallet_bridge_messages::Config<B::BridgedMessagesInstance>,
|
||||
HashOf<BridgedChain<B>>:
|
||||
Into<bp_runtime::HashOf<<ThisRuntime as pallet_bridge_grandpa::Config<GrandpaInstance>>::BridgedChain>>,
|
||||
{
|
||||
@@ -524,7 +571,7 @@ pub mod target {
|
||||
StorageProof::new(bridged_storage_proof),
|
||||
|storage_adapter| storage_adapter,
|
||||
)
|
||||
.map(|storage| StorageProofCheckerAdapter::<_, B, ThisRuntime> {
|
||||
.map(|storage| StorageProofCheckerAdapter::<_, B> {
|
||||
storage,
|
||||
_dummy: Default::default(),
|
||||
})
|
||||
@@ -564,31 +611,29 @@ pub mod target {
|
||||
fn read_raw_message(&self, message_key: &MessageKey) -> Option<Vec<u8>>;
|
||||
}
|
||||
|
||||
struct StorageProofCheckerAdapter<H: Hasher, B, ThisRuntime> {
|
||||
struct StorageProofCheckerAdapter<H: Hasher, B> {
|
||||
storage: StorageProofChecker<H>,
|
||||
_dummy: sp_std::marker::PhantomData<(B, ThisRuntime)>,
|
||||
_dummy: sp_std::marker::PhantomData<B>,
|
||||
}
|
||||
|
||||
impl<H, B, ThisRuntime> MessageProofParser for StorageProofCheckerAdapter<H, B, ThisRuntime>
|
||||
impl<H, B> MessageProofParser for StorageProofCheckerAdapter<H, B>
|
||||
where
|
||||
H: Hasher,
|
||||
B: MessageBridge,
|
||||
ThisRuntime: pallet_bridge_messages::Config<MessagesInstanceOf<BridgedChain<B>>>,
|
||||
{
|
||||
fn read_raw_outbound_lane_data(&self, lane_id: &LaneId) -> Option<Vec<u8>> {
|
||||
let storage_outbound_lane_data_key = pallet_bridge_messages::storage_keys::outbound_lane_data_key::<
|
||||
MessagesInstanceOf<BridgedChain<B>>,
|
||||
>(lane_id);
|
||||
let storage_outbound_lane_data_key =
|
||||
pallet_bridge_messages::storage_keys::outbound_lane_data_key::<B::BridgedMessagesInstance>(lane_id);
|
||||
self.storage
|
||||
.read_value(storage_outbound_lane_data_key.0.as_ref())
|
||||
.ok()?
|
||||
}
|
||||
|
||||
fn read_raw_message(&self, message_key: &MessageKey) -> Option<Vec<u8>> {
|
||||
let storage_message_key = pallet_bridge_messages::storage_keys::message_key::<
|
||||
ThisRuntime,
|
||||
MessagesInstanceOf<BridgedChain<B>>,
|
||||
>(&message_key.lane_id, message_key.nonce);
|
||||
let storage_message_key = pallet_bridge_messages::storage_keys::message_key::<B::BridgedMessagesInstance>(
|
||||
&message_key.lane_id,
|
||||
message_key.nonce,
|
||||
);
|
||||
self.storage.read_value(storage_message_key.0.as_ref()).ok()?
|
||||
}
|
||||
}
|
||||
@@ -692,11 +737,13 @@ mod tests {
|
||||
struct OnThisChainBridge;
|
||||
|
||||
impl MessageBridge for OnThisChainBridge {
|
||||
const INSTANCE: InstanceId = *b"this";
|
||||
const RELAYER_FEE_PERCENT: u32 = 10;
|
||||
const THIS_CHAIN_ID: ChainId = *b"this";
|
||||
const BRIDGED_CHAIN_ID: ChainId = *b"brdg";
|
||||
|
||||
type ThisChain = ThisChain;
|
||||
type BridgedChain = BridgedChain;
|
||||
type BridgedMessagesInstance = pallet_bridge_messages::DefaultInstance;
|
||||
|
||||
fn bridged_balance_to_this_balance(bridged_balance: BridgedChainBalance) -> ThisChainBalance {
|
||||
ThisChainBalance(bridged_balance.0 * BRIDGED_CHAIN_TO_THIS_CHAIN_BALANCE_RATE as u32)
|
||||
@@ -708,11 +755,13 @@ mod tests {
|
||||
struct OnBridgedChainBridge;
|
||||
|
||||
impl MessageBridge for OnBridgedChainBridge {
|
||||
const INSTANCE: InstanceId = *b"brdg";
|
||||
const RELAYER_FEE_PERCENT: u32 = 20;
|
||||
const THIS_CHAIN_ID: ChainId = *b"brdg";
|
||||
const BRIDGED_CHAIN_ID: ChainId = *b"this";
|
||||
|
||||
type ThisChain = BridgedChain;
|
||||
type BridgedChain = ThisChain;
|
||||
type BridgedMessagesInstance = pallet_bridge_messages::DefaultInstance;
|
||||
|
||||
fn bridged_balance_to_this_balance(_this_balance: ThisChainBalance) -> BridgedChainBalance {
|
||||
unreachable!()
|
||||
@@ -815,8 +864,6 @@ mod tests {
|
||||
type Signature = ThisChainSignature;
|
||||
type Weight = frame_support::weights::Weight;
|
||||
type Balance = ThisChainBalance;
|
||||
|
||||
type MessagesInstance = pallet_bridge_messages::DefaultInstance;
|
||||
}
|
||||
|
||||
impl ThisChainWithMessages for ThisChain {
|
||||
@@ -853,6 +900,7 @@ mod tests {
|
||||
|
||||
fn estimate_delivery_transaction(
|
||||
_message_payload: &[u8],
|
||||
_include_pay_dispatch_fee_cost: bool,
|
||||
_message_dispatch_weight: WeightOf<Self>,
|
||||
) -> MessageTransaction<WeightOf<Self>> {
|
||||
unreachable!()
|
||||
@@ -872,8 +920,6 @@ mod tests {
|
||||
type Signature = BridgedChainSignature;
|
||||
type Weight = frame_support::weights::Weight;
|
||||
type Balance = BridgedChainBalance;
|
||||
|
||||
type MessagesInstance = pallet_bridge_messages::DefaultInstance;
|
||||
}
|
||||
|
||||
impl ThisChainWithMessages for BridgedChain {
|
||||
@@ -908,6 +954,7 @@ mod tests {
|
||||
|
||||
fn estimate_delivery_transaction(
|
||||
_message_payload: &[u8],
|
||||
_include_pay_dispatch_fee_cost: bool,
|
||||
message_dispatch_weight: WeightOf<Self>,
|
||||
) -> MessageTransaction<WeightOf<Self>> {
|
||||
MessageTransaction {
|
||||
@@ -932,6 +979,7 @@ mod tests {
|
||||
spec_version: 1,
|
||||
weight: 100,
|
||||
origin: bp_message_dispatch::CallOrigin::SourceRoot,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
|
||||
call: ThisChainCall::Transfer.encode(),
|
||||
}
|
||||
.encode();
|
||||
@@ -946,10 +994,10 @@ mod tests {
|
||||
spec_version: 1,
|
||||
weight: 100,
|
||||
origin: bp_message_dispatch::CallOrigin::SourceRoot,
|
||||
call: target::FromBridgedChainEncodedMessageCall::<OnThisChainBridge> {
|
||||
encoded_call: ThisChainCall::Transfer.encode(),
|
||||
_marker: PhantomData::default(),
|
||||
},
|
||||
dispatch_fee_payment: DispatchFeePayment::AtTargetChain,
|
||||
call: target::FromBridgedChainEncodedMessageCall::<ThisChainCall>::new(
|
||||
ThisChainCall::Transfer.encode(),
|
||||
),
|
||||
}
|
||||
);
|
||||
assert_eq!(Ok(ThisChainCall::Transfer), message_on_this_chain.call.into());
|
||||
@@ -963,6 +1011,7 @@ mod tests {
|
||||
spec_version: 1,
|
||||
weight: 100,
|
||||
origin: bp_message_dispatch::CallOrigin::SourceRoot,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
|
||||
call: vec![42],
|
||||
}
|
||||
}
|
||||
@@ -983,12 +1032,27 @@ mod tests {
|
||||
Ok(ThisChainBalance(EXPECTED_MINIMAL_FEE)),
|
||||
);
|
||||
|
||||
// let's check if estimation is less than hardcoded, if dispatch is paid at target chain
|
||||
let mut payload_with_pay_on_target = regular_outbound_message_payload();
|
||||
payload_with_pay_on_target.dispatch_fee_payment = DispatchFeePayment::AtTargetChain;
|
||||
let fee_at_source = source::estimate_message_dispatch_and_delivery_fee::<OnThisChainBridge>(
|
||||
&payload_with_pay_on_target,
|
||||
OnThisChainBridge::RELAYER_FEE_PERCENT,
|
||||
)
|
||||
.expect("estimate_message_dispatch_and_delivery_fee failed for pay-at-target-chain message");
|
||||
assert!(
|
||||
fee_at_source < EXPECTED_MINIMAL_FEE.into(),
|
||||
"Computed fee {:?} without prepaid dispatch must be less than the fee with prepaid dispatch {}",
|
||||
fee_at_source,
|
||||
EXPECTED_MINIMAL_FEE,
|
||||
);
|
||||
|
||||
// and now check that the verifier checks the fee
|
||||
assert_eq!(
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Root,
|
||||
&ThisChainBalance(1),
|
||||
&TEST_LANE_ID,
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
&payload,
|
||||
),
|
||||
@@ -998,7 +1062,7 @@ mod tests {
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Root,
|
||||
&ThisChainBalance(1_000_000),
|
||||
&TEST_LANE_ID,
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
&payload,
|
||||
)
|
||||
@@ -1013,6 +1077,7 @@ mod tests {
|
||||
spec_version: 1,
|
||||
weight: 100,
|
||||
origin: bp_message_dispatch::CallOrigin::SourceRoot,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
|
||||
call: vec![42],
|
||||
};
|
||||
|
||||
@@ -1021,7 +1086,7 @@ mod tests {
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Signed(ThisChainAccountId(0)),
|
||||
&ThisChainBalance(1_000_000),
|
||||
&TEST_LANE_ID,
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
&payload,
|
||||
),
|
||||
@@ -1031,7 +1096,7 @@ mod tests {
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::None,
|
||||
&ThisChainBalance(1_000_000),
|
||||
&TEST_LANE_ID,
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
&payload,
|
||||
),
|
||||
@@ -1041,7 +1106,7 @@ mod tests {
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Root,
|
||||
&ThisChainBalance(1_000_000),
|
||||
&TEST_LANE_ID,
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
&payload,
|
||||
)
|
||||
@@ -1056,6 +1121,7 @@ mod tests {
|
||||
spec_version: 1,
|
||||
weight: 100,
|
||||
origin: bp_message_dispatch::CallOrigin::SourceAccount(ThisChainAccountId(1)),
|
||||
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
|
||||
call: vec![42],
|
||||
};
|
||||
|
||||
@@ -1064,7 +1130,7 @@ mod tests {
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Signed(ThisChainAccountId(0)),
|
||||
&ThisChainBalance(1_000_000),
|
||||
&TEST_LANE_ID,
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
&payload,
|
||||
),
|
||||
@@ -1074,7 +1140,7 @@ mod tests {
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Signed(ThisChainAccountId(1)),
|
||||
&ThisChainBalance(1_000_000),
|
||||
&TEST_LANE_ID,
|
||||
TEST_LANE_ID,
|
||||
&test_lane_outbound_data(),
|
||||
&payload,
|
||||
)
|
||||
@@ -1102,7 +1168,7 @@ mod tests {
|
||||
source::FromThisChainMessageVerifier::<OnThisChainBridge>::verify_message(
|
||||
&Sender::Root,
|
||||
&ThisChainBalance(1_000_000),
|
||||
&TEST_LANE_ID,
|
||||
TEST_LANE_ID,
|
||||
&OutboundLaneData {
|
||||
latest_received_nonce: 100,
|
||||
latest_generated_nonce: 100 + MAXIMAL_PENDING_MESSAGES_AT_TEST_LANE + 1,
|
||||
@@ -1123,6 +1189,7 @@ mod tests {
|
||||
spec_version: 1,
|
||||
weight: 5,
|
||||
origin: bp_message_dispatch::CallOrigin::SourceRoot,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
|
||||
call: vec![1, 2, 3, 4, 5, 6],
|
||||
},)
|
||||
.is_err()
|
||||
@@ -1138,6 +1205,7 @@ mod tests {
|
||||
spec_version: 1,
|
||||
weight: BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT + 1,
|
||||
origin: bp_message_dispatch::CallOrigin::SourceRoot,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
|
||||
call: vec![1, 2, 3, 4, 5, 6],
|
||||
},)
|
||||
.is_err()
|
||||
@@ -1153,6 +1221,7 @@ mod tests {
|
||||
spec_version: 1,
|
||||
weight: BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT,
|
||||
origin: bp_message_dispatch::CallOrigin::SourceRoot,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
|
||||
call: vec![0; source::maximal_message_size::<OnThisChainBridge>() as usize + 1],
|
||||
},)
|
||||
.is_err()
|
||||
@@ -1168,6 +1237,7 @@ mod tests {
|
||||
spec_version: 1,
|
||||
weight: BRIDGED_CHAIN_MAX_EXTRINSIC_WEIGHT,
|
||||
origin: bp_message_dispatch::CallOrigin::SourceRoot,
|
||||
dispatch_fee_payment: DispatchFeePayment::AtSourceChain,
|
||||
call: vec![0; source::maximal_message_size::<OnThisChainBridge>() as _],
|
||||
},),
|
||||
Ok(()),
|
||||
|
||||
@@ -25,6 +25,7 @@ use crate::messages::{
|
||||
};
|
||||
|
||||
use bp_messages::{LaneId, MessageData, MessageKey, MessagePayload};
|
||||
use bp_runtime::ChainId;
|
||||
use codec::Encode;
|
||||
use ed25519_dalek::{PublicKey, SecretKey, Signer, KEYPAIR_LENGTH, SECRET_KEY_LENGTH};
|
||||
use frame_support::weights::Weight;
|
||||
@@ -37,7 +38,13 @@ use sp_trie::{record_all_keys, trie_types::TrieDBMut, Layout, MemoryDB, Recorder
|
||||
/// Generate ed25519 signature to be used in `pallet_brdige_call_dispatch::CallOrigin::TargetAccount`.
|
||||
///
|
||||
/// Returns public key of the signer and the signature itself.
|
||||
pub fn ed25519_sign(target_call: &impl Encode, source_account_id: &impl Encode) -> ([u8; 32], [u8; 64]) {
|
||||
pub fn ed25519_sign(
|
||||
target_call: &impl Encode,
|
||||
source_account_id: &impl Encode,
|
||||
target_spec_version: u32,
|
||||
source_chain_id: ChainId,
|
||||
target_chain_id: ChainId,
|
||||
) -> ([u8; 32], [u8; 64]) {
|
||||
// key from the repo example (https://docs.rs/ed25519-dalek/1.0.1/ed25519_dalek/struct.SecretKey.html)
|
||||
let target_secret = SecretKey::from_bytes(&[
|
||||
157, 097, 177, 157, 239, 253, 090, 096, 186, 132, 074, 244, 146, 236, 044, 196, 068, 073, 197, 105, 123, 050,
|
||||
@@ -51,9 +58,13 @@ pub fn ed25519_sign(target_call: &impl Encode, source_account_id: &impl Encode)
|
||||
target_pair_bytes[SECRET_KEY_LENGTH..].copy_from_slice(&target_public.to_bytes());
|
||||
let target_pair = ed25519_dalek::Keypair::from_bytes(&target_pair_bytes).expect("hardcoded pair is valid");
|
||||
|
||||
let mut signature_message = Vec::new();
|
||||
target_call.encode_to(&mut signature_message);
|
||||
source_account_id.encode_to(&mut signature_message);
|
||||
let signature_message = pallet_bridge_dispatch::account_ownership_digest(
|
||||
target_call,
|
||||
source_account_id,
|
||||
target_spec_version,
|
||||
source_chain_id,
|
||||
target_chain_id,
|
||||
);
|
||||
let target_origin_signature = target_pair
|
||||
.try_sign(&signature_message)
|
||||
.expect("Ed25519 try_sign should not fail in benchmarks");
|
||||
|
||||
Reference in New Issue
Block a user