From 0da4f4398e11328c06a1986bba6c98779b68568b Mon Sep 17 00:00:00 2001 From: Bear Wang Date: Sat, 12 Oct 2024 09:31:03 +0800 Subject: [PATCH] Fix pending runtime api (#1608) * Fix pending runtime api * Fix validation and add test * Revert useless change * Format --------- Co-authored-by: fisher --- Cargo.lock | 1 + Cargo.toml | 1 + node/Cargo.toml | 1 + node/src/service/mod.rs | 68 +++++++++++++++++++++++++-------- tests/ethereum/test-block.ts | 11 ++++++ tests/ethereum/test-contract.ts | 11 ++++++ 6 files changed, 78 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 85fdffb0f..a7d4b90b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2639,6 +2639,7 @@ dependencies = [ "cumulus-primitives-core", "cumulus-primitives-parachain-inherent", "cumulus-relay-chain-interface", + "cumulus-test-relay-sproof-builder", "darwinia-runtime", "dc-primitives", "fc-api", diff --git a/Cargo.toml b/Cargo.toml index d597ed81f..83da3abdd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -107,6 +107,7 @@ cumulus-primitives-core = { git = "https://github.com/darwini cumulus-primitives-parachain-inherent = { git = "https://github.com/darwinia-network/polkadot-sdk", branch = "release-polkadot-v1.7.2", default-features = false } cumulus-primitives-utility = { git = "https://github.com/darwinia-network/polkadot-sdk", branch = "release-polkadot-v1.7.2", default-features = false } cumulus-relay-chain-interface = { git = "https://github.com/darwinia-network/polkadot-sdk", branch = "release-polkadot-v1.7.2" } +cumulus-test-relay-sproof-builder = { git = "https://github.com/darwinia-network/polkadot-sdk", branch = "release-polkadot-v1.7.2" } frame-benchmarking = { git = "https://github.com/darwinia-network/polkadot-sdk", branch = "release-polkadot-v1.7.2", default-features = false } frame-benchmarking-cli = { git = "https://github.com/darwinia-network/polkadot-sdk", branch = "release-polkadot-v1.7.2" } frame-executive = { git = "https://github.com/darwinia-network/polkadot-sdk", branch = "release-polkadot-v1.7.2", default-features = false } diff --git a/node/Cargo.toml b/node/Cargo.toml index f25e5dbab..e10d698c0 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -56,6 +56,7 @@ cumulus-primitives-aura = { workspace = true, features = ["std"] } cumulus-primitives-core = { workspace = true, features = ["std"] } cumulus-primitives-parachain-inherent = { workspace = true, features = ["std"] } cumulus-relay-chain-interface = { workspace = true } +cumulus-test-relay-sproof-builder = { workspace = true } frame-benchmarking = { workspace = true, optional = true, features = ["std"] } frame-benchmarking-cli = { workspace = true } pallet-transaction-payment-rpc = { workspace = true } diff --git a/node/src/service/mod.rs b/node/src/service/mod.rs index dea6d1928..a6ddf4513 100644 --- a/node/src/service/mod.rs +++ b/node/src/service/mod.rs @@ -43,6 +43,7 @@ use dc_primitives::*; use sc_client_api::{Backend, HeaderBackend}; use sc_consensus::ImportQueue; use sc_network::NetworkBlock; +use sp_consensus_aura::{Slot, SlotDuration}; use sp_core::Encode; #[cfg(all(feature = "runtime-benchmarks", feature = "evm-tracing"))] @@ -389,16 +390,34 @@ where let collator = parachain_config.role.is_authority(); let eth_rpc_config = eth_rpc_config.clone(); let sync_service = sync_service.clone(); - let slot_duration = sc_consensus_aura::slot_duration(&*client)?; let pending_create_inherent_data_providers = move |_, ()| async move { - let current = sp_timestamp::InherentDataProvider::from_system_time(); - let next_slot = current.timestamp().as_millis() + slot_duration.as_millis(); - let timestamp = sp_timestamp::InherentDataProvider::new(next_slot.into()); - let slot = sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( - *timestamp, - slot_duration, + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + let relay_chain_slot = Slot::from_timestamp( + timestamp.timestamp(), + SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS as u64), ); - Ok((slot, timestamp)) + + // Create a mocked parachain inherent data provider to pass all validations in the + // parachain system. Without this, the pending functionality will fail. + let mut state_proof_builder = + cumulus_test_relay_sproof_builder::RelayStateSproofBuilder::default(); + state_proof_builder.para_id = para_id; + state_proof_builder.current_slot = relay_chain_slot; + state_proof_builder.included_para_head = Some(polkadot_primitives::HeadData(vec![])); + let (relay_parent_storage_root, relay_chain_state) = + state_proof_builder.into_state_root_and_proof(); + let parachain_inherent_data = + cumulus_primitives_parachain_inherent::ParachainInherentData { + validation_data: cumulus_primitives_core::PersistedValidationData { + relay_parent_number: u32::MAX, + relay_parent_storage_root, + ..Default::default() + }, + relay_chain_state, + downward_messages: Default::default(), + horizontal_messages: Default::default(), + }; + Ok((timestamp, parachain_inherent_data)) }; Box::new(move |deny_unsafe, subscription_task_executor| { @@ -897,15 +916,34 @@ where let collator = config.role.is_authority(); let eth_rpc_config = eth_rpc_config.clone(); let sync_service = sync_service.clone(); + let pending_create_inherent_data_providers = move |_, ()| async move { - let current = sp_timestamp::InherentDataProvider::from_system_time(); - let next_slot = current.timestamp().as_millis() + slot_duration.as_millis(); - let timestamp = sp_timestamp::InherentDataProvider::new(next_slot.into()); - let slot = sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( - *timestamp, - slot_duration, + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + let relay_chain_slot = Slot::from_timestamp( + timestamp.timestamp(), + SlotDuration::from_millis(RELAY_CHAIN_SLOT_DURATION_MILLIS as u64), ); - Ok((slot, timestamp)) + // Create a mocked parachain inherent data provider to pass all validations in the + // parachain system. Without this, the pending functionality will fail. + let mut state_proof_builder = + cumulus_test_relay_sproof_builder::RelayStateSproofBuilder::default(); + state_proof_builder.para_id = para_id; + state_proof_builder.current_slot = relay_chain_slot; + state_proof_builder.included_para_head = Some(polkadot_primitives::HeadData(vec![])); + let (relay_parent_storage_root, relay_chain_state) = + state_proof_builder.into_state_root_and_proof(); + let parachain_inherent_data = + cumulus_primitives_parachain_inherent::ParachainInherentData { + validation_data: cumulus_primitives_core::PersistedValidationData { + relay_parent_number: u32::MAX, + relay_parent_storage_root, + ..Default::default() + }, + relay_chain_state, + downward_messages: Default::default(), + horizontal_messages: Default::default(), + }; + Ok((timestamp, parachain_inherent_data)) }; Box::new(move |deny_unsafe, subscription_task_executor| { diff --git a/tests/ethereum/test-block.ts b/tests/ethereum/test-block.ts index c9b5b364f..e36388ec4 100644 --- a/tests/ethereum/test-block.ts +++ b/tests/ethereum/test-block.ts @@ -9,6 +9,17 @@ describe("Test Block RPC", () => { expect(await web3.eth.getBlockNumber()).to.not.equal(0); }); + it("Get block by tags", async () => { + let earliest = await web3.eth.getBlock("earliest"); + expect(earliest.number).to.equal(0); + + let latest = await web3.eth.getBlock("latest"); + expect(latest.number).to.be.a("number"); + + let pending = await web3.eth.getBlock("pending"); + expect(pending.number).to.be.a("number"); + }); + it("Get block by hash", async () => { let latest_block = await web3.eth.getBlock("latest"); let block = await web3.eth.getBlock(latest_block.hash); diff --git a/tests/ethereum/test-contract.ts b/tests/ethereum/test-contract.ts index 8e76865c9..22ef8e870 100644 --- a/tests/ethereum/test-contract.ts +++ b/tests/ethereum/test-contract.ts @@ -38,6 +38,17 @@ describe("Test contract", () => { expect(await inc.methods.number().call()).to.be.equal("5"); }); + step("Get default number in pending block", async function () { + const result = await web3.eth.call( + { + to: inc.options.address, + data: inc.methods.number().encodeABI(), + }, + "pending" + ); + expect(web3.utils.hexToNumberString(result)).to.be.equal("5"); + }); + step("Increase number", async function () { let receipt = await inc.methods.increment(3).send(); transact_hash = receipt.transactionHash;