Skip to content

Commit

Permalink
feat: delayed finalization (#214)
Browse files Browse the repository at this point in the history
Adds `--finalize-delay-sec` cli argument, based on the great work by
@shunsukew at inkdevhub/swanky-node#61.

Manual testing by starting node with/without option, along with example
contract upload:
```shell
# build example contract
cargo contract build --manifest-path=../ink-examples/erc20/Cargo.toml

# start node
cargo run

# upload contract
cargo contract upload --suri //Alice --execute --manifest-path=../ink-examples/erc20/Cargo.toml
# check finalized head remains at genesis
sleep 1
test $(curl -sH "Content-Type: application/json" -d '{"id":"1", "jsonrpc":"2.0", "method": "chainHead_unstable_genesisHash", "params":[]}' http://localhost:9944 | jq .result) \
  = $(curl -sH "Content-Type: application/json" -d '{"id":"1", "jsonrpc":"2.0", "method": "chain_getFinalizedHead", "params":[]}' http://localhost:9944 | jq .result) && echo PASS || echo FAIL


# start node (with delayed finalization)
cargo run -- --finalize-delay-sec 1

# upload contract
cargo contract upload --suri //Alice --execute --manifest-path=../ink-examples/erc20/Cargo.toml
# check finalized head matches chain head
sleep 1
test $(curl -sH "Content-Type: application/json" -d '{"id":"1", "jsonrpc":"2.0", "method": "chain_getHead", "params":[]}' http://localhost:9944 | jq .result) \
  = $(curl -sH "Content-Type: application/json" -d '{"id":"1", "jsonrpc":"2.0", "method": "chain_getFinalizedHead", "params":[]}' http://localhost:9944 | jq .result) && echo PASS || echo FAIL

```

Closes #160
  • Loading branch information
evilrobot-01 authored Nov 29, 2023
1 parent f1d8389 commit 813d99f
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 4 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ for a production deployment, but a great fit for development and testing:_
[#42](https://github.com/paritytech/substrate-contracts-node/pull/42).
Hereby blocks are authored immediately at every transaction, so there
is none of the typical six seconds block time associated with `grandpa` or `aura`.
* By default, either manual or instant seal does not result in block finalization unless the `engine_finalizeBlock`
RPC is executed. However, it is possible to configure the finalization of sealed blocks to occur after a certain
amount of time by setting the `--finalize-delay-sec` option to a specific value, which specifies the number of seconds
to delay before finalizing the blocks. The default value is 1 second.
```shell
./target/release/substrate-contracts-node --finalize-delay-sec 5
```
* _If no CLI arguments are passed the node is started in development mode
by default._
* A custom logging filter is applied by default that hides block production noise
Expand Down
4 changes: 4 additions & 0 deletions node/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ pub struct Cli {
/// Relay chain arguments
#[arg(raw = true)]
pub relay_chain_args: Vec<String>,

/// The number of seconds to delay before finalizing blocks.
#[arg(long, default_value_t = 1)]
pub finalize_delay_sec: u8,
}

#[derive(Debug)]
Expand Down
2 changes: 1 addition & 1 deletion node/src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ pub fn run() -> Result<()> {

runner.run_node_until_exit(|config| async move {
if config.chain_spec.name() == "Development" { // TODO
return service::dev::new_full(config).map_err(sc_cli::Error::Service);
return service::dev::new_full(config, cli.finalize_delay_sec.into()).map_err(sc_cli::Error::Service);
}

let hwbench = (!cli.no_hardware_benchmarks)
Expand Down
20 changes: 17 additions & 3 deletions node/src/service/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@ pub fn new_partial(
})
}

pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
pub fn new_full(
config: Configuration,
finalize_delay_sec: u64,
) -> Result<TaskManager, ServiceError> {
let sc_service::PartialComponents {
client,
backend,
Expand Down Expand Up @@ -195,7 +198,7 @@ pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
let params = sc_consensus_manual_seal::InstantSealParams {
block_import: client.clone(),
env: proposer,
client,
client: client.clone(),
pool: transaction_pool,
select_chain,
consensus_data_provider: None,
Expand All @@ -205,10 +208,21 @@ pub fn new_full(config: Configuration) -> Result<TaskManager, ServiceError> {
};

let authorship_future = sc_consensus_manual_seal::run_instant_seal(params);

task_manager
.spawn_essential_handle()
.spawn_blocking("instant-seal", None, authorship_future);

let delayed_finalize_params = sc_consensus_manual_seal::DelayedFinalizeParams {
client,
spawn_handle: task_manager.spawn_handle(),
delay_sec: finalize_delay_sec,
};
task_manager.spawn_essential_handle().spawn_blocking(
"delayed_finalize",
None,
sc_consensus_manual_seal::run_delayed_finalize(delayed_finalize_params),
);

network_starter.start_network();
Ok(task_manager)
}

0 comments on commit 813d99f

Please sign in to comment.