From 58a5e6fad111a3cd0d4d40678ff490b7a0866ce9 Mon Sep 17 00:00:00 2001 From: Peter Goodspeed-Niklaus Date: Tue, 7 Jul 2020 15:35:59 +0200 Subject: [PATCH] wait a fixed time before getting availability chunks; clone context to each job --- Cargo.lock | 1 + node/bitfield-signing/Cargo.toml | 1 + node/bitfield-signing/src/lib.rs | 38 ++++++++++++++++--- .../src/node/availability/bitfield-signing.md | 3 +- 4 files changed, 35 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b36be543cccc..3b6b85c78d12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4424,6 +4424,7 @@ dependencies = [ "log 0.4.8", "polkadot-node-subsystem", "polkadot-primitives", + "wasm-timer", ] [[package]] diff --git a/node/bitfield-signing/Cargo.toml b/node/bitfield-signing/Cargo.toml index 5bcf0c020dfe..21189c9d5f9d 100644 --- a/node/bitfield-signing/Cargo.toml +++ b/node/bitfield-signing/Cargo.toml @@ -11,3 +11,4 @@ futures = "0.3.5" log = "0.4.8" polkadot-primitives = { path = "../../primitives" } polkadot-node-subsystem = { path = "../subsystem" } +wasm-timer = "0.2.4" diff --git a/node/bitfield-signing/src/lib.rs b/node/bitfield-signing/src/lib.rs index defb86224398..ba8e9a905c24 100644 --- a/node/bitfield-signing/src/lib.rs +++ b/node/bitfield-signing/src/lib.rs @@ -16,15 +16,28 @@ //! The bitfield signing subsystem produces `SignedAvailabilityBitfield`s once per block. -use futures::{channel::oneshot, future::{abortable, AbortHandle}, Future}; +use futures::{ + channel::{mpsc, oneshot}, + future::{abortable, AbortHandle}, + prelude::*, + Future, +}; use polkadot_node_subsystem::{ messages::{AllMessages, BitfieldSigningMessage}, OverseerSignal, SubsystemResult, }; use polkadot_node_subsystem::{FromOverseer, SpawnedSubsystem, Subsystem, SubsystemContext}; use polkadot_primitives::Hash; -use std::{collections::HashMap, pin::Pin}; +use std::{ + collections::HashMap, + pin::Pin, + time::{Duration, Instant}, +}; +/// Delay between starting a bitfield signing job and its attempting to create a bitfield. +const JOB_DELAY: Duration = Duration::from_millis(1500); + +/// JobCanceler aborts all abort handles on drop. #[derive(Debug, Default)] struct JobCanceler(HashMap); @@ -38,12 +51,13 @@ impl Drop for JobCanceler { } } +/// Bitfield signing subsystem. struct BitfieldSigning; impl BitfieldSigning { async fn run(mut ctx: Context) -> SubsystemResult<()> where - Context: SubsystemContext, + Context: SubsystemContext + Clone, { let mut active_jobs = JobCanceler::default(); @@ -55,7 +69,8 @@ impl BitfieldSigning { unreachable!("BitfieldSigningMessage is uninstantiable; qed") } Ok(Signal(StartWork(hash))) => { - let (future, abort_handle) = abortable(bitfield_signing_job(hash.clone())); + let (future, abort_handle) = + abortable(bitfield_signing_job(hash.clone(), ctx.clone())); // future currently returns a Result based on whether or not it was aborted; // let's ignore all that and return () unconditionally, to fit the interface. let future = async move { @@ -82,7 +97,7 @@ impl BitfieldSigning { impl Subsystem for BitfieldSigning where - Context: SubsystemContext, + Context: SubsystemContext + Clone, { fn start(self, ctx: Context) -> SpawnedSubsystem { SpawnedSubsystem(Box::pin(async move { @@ -93,7 +108,18 @@ where } } -async fn bitfield_signing_job(hash: Hash) { +async fn bitfield_signing_job(hash: Hash, ctx: Context) +where + Context: SubsystemContext, +{ + // first up, figure out when we need to wait until + let delay = wasm_timer::Delay::new_at(Instant::now() + JOB_DELAY); + // next, do some prerequisite work + todo!(); + // now, wait for the delay to be complete + if let Err(_) = delay.await { + return; + } // let (tx, _) = oneshot::channel(); // ctx.send_message(AllMessages::CandidateValidation( diff --git a/roadmap/implementors-guide/src/node/availability/bitfield-signing.md b/roadmap/implementors-guide/src/node/availability/bitfield-signing.md index 24c9d8dbedc8..4ad33f09ea99 100644 --- a/roadmap/implementors-guide/src/node/availability/bitfield-signing.md +++ b/roadmap/implementors-guide/src/node/availability/bitfield-signing.md @@ -22,9 +22,8 @@ Upon onset of a new relay-chain head with `StartWork`, launch bitfield signing j Localized to a specific relay-parent `r` If not running as a validator, do nothing. +- Start by waiting a fixed period of time so the availability store has the chance to make candidates available. - Determine our validator index `i`, the set of backed candidates pending availability in `r`, and which bit of the bitfield each corresponds to. - Start with an empty bitfield. For each bit in the bitfield, if there is a candidate pending availability, query the [Availability Store](../utility/availability-store.md) for whether we have the availability chunk for our validator index. - For all chunks we have, set the corresponding bit in the bitfield. - Sign the bitfield and dispatch a `BitfieldDistribution::DistributeBitfield` message. - -Note that because the bitfield signing job is launched once per block and executes immediately, the signed availability statement for block `N` is best considered as a report of the candidates available at the end of block `N-1`.