diff --git a/.github/workflows/frontier-rpc-tests.yml b/.github/workflows/frontier-rpc-tests.yml new file mode 100644 index 0000000000..ec83cafc78 --- /dev/null +++ b/.github/workflows/frontier-rpc-tests.yml @@ -0,0 +1,52 @@ +name: Frontier RPC Tests +on: + workflow_dispatch: + push: + branches: [ master ] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.ref != 'refs/heads/master' }} + +jobs: + tests: + runs-on: ubuntu-latest + steps: + - name: Checkout the source code + uses: actions/checkout@v4 + + - name: Install deps + run: sudo apt -y install protobuf-compiler + + - name: Install & display rust toolchain + run: rustup show + + - name: Check targets are installed correctly + run: rustup target list --installed + + - name: Build astar-collator + run: cargo build --release --locked --features manual-seal --bin astar-collator + + - name: Clone frontier tests + run: git clone https://github.com/AstarNetwork/frontier-tests.git --depth 1 + + - name: Setup node + uses: actions/setup-node@v4 + with: + node-version: 18.x + cache: 'npm' + cache-dependency-path: frontier-tests/package-lock.json + + - name: Install dependencies + working-directory: frontier-tests + run: npm install --frozen + + - name: Build contracts + working-directory: frontier-tests + run: npm run build + + - name: Run frontier RPC tests + working-directory: frontier-tests + run: npm run test + env: + BINARY_PATH: ${{ github.workspace }}/target/release/astar-collator diff --git a/Cargo.lock b/Cargo.lock index b6f411ff52..dbbc622df2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -686,6 +686,7 @@ dependencies = [ "sc-consensus-aura", "sc-consensus-babe", "sc-consensus-grandpa", + "sc-consensus-manual-seal", "sc-executor", "sc-network", "sc-network-sync", @@ -12874,6 +12875,41 @@ dependencies = [ "thiserror", ] +[[package]] +name = "sc-consensus-manual-seal" +version = "0.10.0-dev" +source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.3.0#401f8a3e9448db854f5605b679fa085b8f445039" +dependencies = [ + "assert_matches", + "async-trait", + "futures 0.3.30", + "futures-timer", + "jsonrpsee", + "log", + "parity-scale-codec", + "sc-client-api", + "sc-consensus", + "sc-consensus-aura", + "sc-consensus-babe", + "sc-consensus-epochs", + "sc-transaction-pool", + "sc-transaction-pool-api", + "serde", + "sp-api", + "sp-blockchain", + "sp-consensus", + "sp-consensus-aura", + "sp-consensus-babe", + "sp-consensus-slots", + "sp-core", + "sp-inherents", + "sp-keystore", + "sp-runtime", + "sp-timestamp", + "substrate-prometheus-endpoint", + "thiserror", +] + [[package]] name = "sc-consensus-slots" version = "0.10.0-dev" diff --git a/Cargo.toml b/Cargo.toml index f4c2949c95..f4e0835d72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -132,6 +132,7 @@ sc-consensus-aura = { git = "https://github.com/paritytech/polkadot-sdk", branch sc-consensus-babe = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.3.0" } sc-executor = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.3.0" } sc-consensus-grandpa = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.3.0" } +sc-consensus-manual-seal = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.3.0" } sc-network = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.3.0" } sc-network-sync = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.3.0" } sc-offchain = { git = "https://github.com/paritytech/polkadot-sdk", branch = "release-polkadot-v1.3.0" } diff --git a/bin/collator/Cargo.toml b/bin/collator/Cargo.toml index d9e207f8b1..198b41b09b 100644 --- a/bin/collator/Cargo.toml +++ b/bin/collator/Cargo.toml @@ -56,6 +56,7 @@ sc-consensus = { workspace = true } sc-consensus-aura = { workspace = true } sc-consensus-babe = { workspace = true } sc-consensus-grandpa = { workspace = true } +sc-consensus-manual-seal = { workspace = true, optional = true } sc-executor = { workspace = true } sc-network = { workspace = true } sc-network-sync = { workspace = true } @@ -173,3 +174,6 @@ evm-tracing = [ "moonbeam-rpc-trace", "moonbeam-rpc-txpool", ] +manual-seal = [ + "sc-consensus-manual-seal", +] diff --git a/bin/collator/src/local/service.rs b/bin/collator/src/local/service.rs index ee53aea2b0..32de813ccd 100644 --- a/bin/collator/src/local/service.rs +++ b/bin/collator/src/local/service.rs @@ -139,6 +139,15 @@ pub fn new_partial( let frontier_block_import = FrontierBlockImport::new(grandpa_block_import.clone(), client.clone()); let slot_duration = sc_consensus_aura::slot_duration(&*client)?; + + #[cfg(feature = "manual-seal")] + let import_queue = sc_consensus_manual_seal::import_queue( + Box::new(client.clone()), + &task_manager.spawn_essential_handle(), + config.prometheus_registry(), + ); + + #[cfg(not(feature = "manual-seal"))] let import_queue = sc_consensus_aura::import_queue::( ImportQueueParams { block_import: frontier_block_import.clone(), @@ -366,6 +375,8 @@ pub fn start_node( block_data_cache: block_data_cache.clone(), overrides: overrides.clone(), enable_evm_rpc: true, // enable EVM RPC for dev node by default + #[cfg(feature = "manual-seal")] + command_sink: None, }; crate::rpc::create_full( @@ -626,6 +637,10 @@ pub fn start_node(config: Configuration) -> Result { prometheus_registry.clone(), )); + // Channel for the rpc handler to communicate with the authorship task. + #[cfg(feature = "manual-seal")] + let (command_sink, commands_stream) = futures::channel::mpsc::channel(1024); + let rpc_extensions_builder = { let client = client.clone(); let network = network.clone(); @@ -649,6 +664,8 @@ pub fn start_node(config: Configuration) -> Result { block_data_cache: block_data_cache.clone(), overrides: overrides.clone(), enable_evm_rpc: true, // enable EVM RPC for dev node by default + #[cfg(feature = "manual-seal")] + command_sink: Some(command_sink.clone()), }; crate::rpc::create_full(deps, subscription, pubsub_notification_sinks.clone()) @@ -682,6 +699,33 @@ pub fn start_node(config: Configuration) -> Result { let slot_duration = sc_consensus_aura::slot_duration(&*client)?; + #[cfg(feature = "manual-seal")] + let aura = sc_consensus_manual_seal::run_manual_seal( + sc_consensus_manual_seal::ManualSealParams { + block_import, + env: proposer_factory, + client: client.clone(), + pool: transaction_pool.clone(), + commands_stream, + select_chain, + consensus_data_provider: Some(Box::new( + sc_consensus_manual_seal::consensus::aura::AuraConsensusDataProvider::new( + client.clone(), + ), + )), + create_inherent_data_providers: move |_, ()| async move { + let timestamp = sp_timestamp::InherentDataProvider::from_system_time(); + let slot = + sp_consensus_aura::inherents::InherentDataProvider::from_timestamp_and_slot_duration( + *timestamp, + slot_duration.clone(), + ); + Ok((slot, timestamp)) + }, + }, + ); + + #[cfg(not(feature = "manual-seal"))] let aura = sc_consensus_aura::start_aura::( StartAuraParams { slot_duration, diff --git a/bin/collator/src/parachain/service.rs b/bin/collator/src/parachain/service.rs index 9865e8e88d..72e2bfd30e 100644 --- a/bin/collator/src/parachain/service.rs +++ b/bin/collator/src/parachain/service.rs @@ -492,6 +492,8 @@ where block_data_cache: block_data_cache.clone(), overrides: overrides.clone(), enable_evm_rpc: additional_config.enable_evm_rpc, + #[cfg(feature = "manual-seal")] + command_sink: None, }; crate::rpc::create_full(deps, subscription, pubsub_notification_sinks.clone()) @@ -834,6 +836,8 @@ where block_data_cache: block_data_cache.clone(), overrides: overrides.clone(), enable_evm_rpc: additional_config.enable_evm_rpc, + #[cfg(feature = "manual-seal")] + command_sink: None, }; crate::rpc::create_full( diff --git a/bin/collator/src/rpc.rs b/bin/collator/src/rpc.rs index b3c143c99d..05fe036730 100644 --- a/bin/collator/src/rpc.rs +++ b/bin/collator/src/rpc.rs @@ -134,6 +134,10 @@ pub struct FullDeps { pub block_data_cache: Arc>, /// Enable EVM RPC servers pub enable_evm_rpc: bool, + /// Command sink for manual sealing + #[cfg(feature = "manual-seal")] + pub command_sink: + Option>>, } /// Instantiate all RPC extensions and Tracing RPC. @@ -291,12 +295,20 @@ where overrides, block_data_cache, enable_evm_rpc, + #[cfg(feature = "manual-seal")] + command_sink, } = deps; io.merge(System::new(client.clone(), pool.clone(), deny_unsafe).into_rpc())?; io.merge(TransactionPayment::new(client.clone()).into_rpc())?; io.merge(sc_rpc::dev::Dev::new(client.clone(), deny_unsafe).into_rpc())?; + #[cfg(feature = "manual-seal")] + if let Some(command_sink) = command_sink { + use sc_consensus_manual_seal::rpc::ManualSealApiServer; + io.merge(sc_consensus_manual_seal::rpc::ManualSeal::new(command_sink).into_rpc())?; + } + if !enable_evm_rpc { return Ok(io); }