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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions domains/client/domain-executor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ tokio = { version = "1.27.0", features = ["macros"] }
core-payments-domain-test-runtime = { version = "0.1.0", path = "../../test/runtime/core-payments" }
core-eth-relay-domain-test-runtime = { version = "0.1.0", path = "../../test/runtime/core-eth-relay" }
core-payments-domain-runtime = { version = "0.1.0", path = "../../runtime/core-payments" }
domain-client-message-relayer = { version = "0.1.0", path = "../relayer" }
domain-test-primitives = { version = "0.1.0", path = "../../test/primitives" }
domain-test-service = { version = "0.1.0", path = "../../test/service" }
pallet-balances = { version = "4.0.0-dev", git = "https://github.com/subspace/substrate", rev = "9cf78129a2638d3f370868863d16f4fe32b4ad30" }
Expand Down
1 change: 1 addition & 0 deletions domains/client/domain-executor/src/core_domain_worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ pub(super) async fn start_worker<
)
.await;
} else {
drop(handle_slot_notifications_fut);
handle_block_import_notifications_fut.await
}
}
200 changes: 198 additions & 2 deletions domains/client/domain-executor/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use codec::{Decode, Encode};
use domain_runtime_primitives::{AccountIdConverter, DomainCoreApi, Hash};
use domain_runtime_primitives::{AccountId, AccountIdConverter, DomainCoreApi, Hash};
use domain_test_primitives::TimestampApi;
use domain_test_service::system_domain_test_runtime::{Address, Header, UncheckedExtrinsic};
use domain_test_service::Keyring::{Alice, Bob, Charlie, Ferdie};
Expand All @@ -10,7 +10,7 @@ use sc_service::{BasePath, Role};
use sc_transaction_pool_api::error::Error as TxPoolError;
use sc_transaction_pool_api::TransactionPool;
use sp_api::{AsTrieBackend, ProvideRuntimeApi};
use sp_core::traits::FetchRuntimeCode;
use sp_core::traits::{FetchRuntimeCode, SpawnEssentialNamed};
use sp_core::Pair;
use sp_domain_digests::AsPredigest;
use sp_domains::fraud_proof::{ExecutionPhase, FraudProof, InvalidStateTransitionProof};
Expand All @@ -22,6 +22,7 @@ use sp_runtime::traits::{BlakeTwo256, Convert, Header as HeaderT};
use sp_runtime::OpaqueExtrinsic;
use subspace_core_primitives::BlockNumber;
use subspace_fraud_proof::invalid_state_transition_proof::ExecutionProver;
use subspace_runtime_primitives::opaque::Block as PBlock;
use subspace_test_service::{
produce_block_with, produce_blocks, produce_blocks_until, MockPrimaryNode,
};
Expand Down Expand Up @@ -1234,3 +1235,198 @@ async fn test_cross_domains_message_should_work() {
.await
.unwrap();
}

#[substrate_test_utils::test(flavor = "multi_thread")]
async fn test_unordered_cross_domains_message_should_work() {
let directory = TempDir::new().expect("Must be able to create temporary directory");

let mut builder = sc_cli::LoggerBuilder::new("");
builder.with_colors(false);
let _ = builder.init();

let tokio_handle = tokio::runtime::Handle::current();

// Start Ferdie
let mut ferdie = MockPrimaryNode::run_mock_primary_node(
tokio_handle.clone(),
Ferdie,
BasePath::new(directory.path().join("ferdie")),
);

// Run Alice (a system domain authority node)
let mut alice = domain_test_service::SystemDomainNodeBuilder::new(
tokio_handle.clone(),
Alice,
BasePath::new(directory.path().join("alice")),
)
.run_relayer()
.build_with_mock_primary_node(Role::Authority, &mut ferdie)
.await;

// Run Bob (a core payments domain authority node)
let mut bob = domain_test_service::CoreDomainNodeBuilder::new(
tokio_handle.clone(),
Bob,
BasePath::new(directory.path().join("bob")),
)
.run_relayer()
.build_core_payments_node(Role::Authority, &mut ferdie, &alice)
.await;

// Run Charlie (a core eth relay domain full node) and don't its relayer worker
let charlie = domain_test_service::CoreDomainNodeBuilder::new(
tokio_handle.clone(),
Charlie,
BasePath::new(directory.path().join("charlie")),
)
.build_core_payments_node(Role::Full, &mut ferdie, &alice)
.await;
let gossip_msg_sink = ferdie.xdm_gossip_worker_builder().gossip_msg_sink();

// Run the cross domain gossip message worker
ferdie.start_cross_domain_gossip_message_worker();

produce_blocks!(ferdie, alice, bob, 3).await.unwrap();

// Open channel between the system domain and the core payments domain
let fee_model = FeeModel {
outbox_fee: ExecutionFee {
relayer_pool_fee: 2,
compute_fee: 0,
},
inbox_fee: ExecutionFee {
relayer_pool_fee: 0,
compute_fee: 5,
},
};
bob.construct_and_send_extrinsic(pallet_sudo::Call::sudo {
call: Box::new(core_payments_domain_test_runtime::RuntimeCall::Messenger(
pallet_messenger::Call::initiate_channel {
dst_domain_id: DomainId::SYSTEM,
params: InitiateChannelParams {
max_outgoing_messages: 1000,
fee_model,
},
},
)),
})
.await
.expect("Failed to construct and send extrinsic");
// Wait until channel open
produce_blocks_until!(ferdie, alice, bob, charlie, {
alice
.get_open_channel_for_domain(DomainId::CORE_PAYMENTS)
.is_some()
&& bob.get_open_channel_for_domain(DomainId::SYSTEM).is_some()
})
.await
.unwrap();

// Register `charlie` as relayer such that message will assign to it, but as its relayer
// is not started these massage won't be relayed.
bob.construct_and_send_extrinsic(pallet_messenger::Call::join_relayer_set {
relayer_id: Charlie.into(),
})
.await
.expect("Failed to construct and send extrinsic");
produce_blocks!(ferdie, alice, bob, charlie, 3)
.await
.unwrap();

// Create cross domain message, only message assigned to `alice` and `bob` will be relayed
// and send to tx pool, and these message is unordered because the message assigned to `charlie`
// is not relayed.
let relayer_id: AccountId = Charlie.into();
let alice_transfer_amount = 1;
let bob_transfer_amount = 2;
let pre_alice_free_balance = alice.free_balance(alice.key.to_account_id());
let pre_bob_free_balance = bob.free_balance(bob.key.to_account_id());
let mut alice_account_nonce = alice.account_nonce();
let mut bob_account_nonce = bob.account_nonce();
// Assigne `inbox_response` message to `charlie`
for _ in 0..10 {
let tx = alice.construct_extrinsic(
alice_account_nonce,
pallet_transporter::Call::transfer {
dst_location: pallet_transporter::Location {
domain_id: DomainId::CORE_PAYMENTS,
account_id: AccountIdConverter::convert(Bob.into()),
},
amount: alice_transfer_amount,
},
);
alice
.send_extrinsic(tx)
.await
.expect("Failed to send extrinsic");
alice_account_nonce += 1;

produce_blocks!(ferdie, alice, bob, charlie, 1)
.await
.unwrap();
}
// Assigne `outbox` message to `charlie`
for _ in 0..10 {
let tx = bob.construct_extrinsic(
bob_account_nonce,
pallet_transporter::Call::transfer {
dst_location: pallet_transporter::Location {
domain_id: DomainId::SYSTEM,
account_id: AccountIdConverter::convert(Alice.into()),
},
amount: bob_transfer_amount,
},
);
bob.send_extrinsic(tx)
.await
.expect("Failed to send extrinsic");
bob_account_nonce += 1;

produce_blocks!(ferdie, alice, bob, charlie, 1)
.await
.unwrap();
}

// Run charlie's relayer worker, the message assigned to `charlie` will be relayed
// and send to tx pool now
let relayer_worker = domain_client_message_relayer::worker::relay_core_domain_messages::<
Comment thread
vedhavyas marked this conversation as resolved.
_,
_,
PBlock,
_,
_,
_,
_,
_,
>(
relayer_id,
charlie.client.clone(),
alice.client.clone(),
alice.sync_service.clone(),
charlie.sync_service.clone(),
gossip_msg_sink,
);
bob.task_manager
.spawn_essential_handle()
.spawn_essential_blocking(
"core-domain-relayer-charlie",
None,
Box::pin(relayer_worker),
);

// Wait until all message are relayed and handled
let fee = fee_model.outbox_fee().unwrap() + fee_model.inbox_fee().unwrap();
produce_blocks_until!(ferdie, alice, bob, {
let post_alice_free_balance = alice.free_balance(alice.key.to_account_id());
let post_bob_free_balance = bob.free_balance(bob.key.to_account_id());

post_alice_free_balance
== pre_alice_free_balance - alice_transfer_amount * 10 + bob_transfer_amount * 10
- fee * 10
&& post_bob_free_balance
== pre_bob_free_balance - bob_transfer_amount * 10 + alice_transfer_amount * 10
- fee * 10
})
.await
.unwrap();
}
9 changes: 9 additions & 0 deletions domains/pallets/messenger/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ include = [

[dependencies]
codec = { package = "parity-scale-codec", version = "3.4.0", default-features = false, features = ["derive"] }
frame-benchmarking = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "9cf78129a2638d3f370868863d16f4fe32b4ad30", optional = true }
frame-support = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "9cf78129a2638d3f370868863d16f4fe32b4ad30" }
frame-system = { version = "4.0.0-dev", default-features = false, git = "https://github.com/subspace/substrate", rev = "9cf78129a2638d3f370868863d16f4fe32b4ad30" }
log = { version = "0.4.17", default-features = false }
Expand All @@ -36,6 +37,7 @@ sp-state-machine = { version = "0.13.0", git = "https://github.com/subspace/subs
default = ["std"]
std = [
"codec/std",
"frame-benchmarking?/std",
"frame-support/std",
"frame-system/std",
"log/std",
Expand All @@ -48,3 +50,10 @@ std = [
"sp-trie/std",
]
try-runtime = ["frame-support/try-runtime"]
runtime-benchmarks = [
"frame-benchmarking",
"frame-benchmarking/runtime-benchmarks",
Comment thread
NingLin-P marked this conversation as resolved.
Outdated
"frame-support/runtime-benchmarks",
"frame-system/runtime-benchmarks",
"sp-messenger/runtime-benchmarks",
]
Loading