diff --git a/coordinator/src/tributary/db.rs b/coordinator/src/tributary/db.rs
index 31ae2e1e..fbcfcc01 100644
--- a/coordinator/src/tributary/db.rs
+++ b/coordinator/src/tributary/db.rs
@@ -189,6 +189,8 @@ create_db!(
// The latest Substrate block to cosign.
LatestSubstrateBlockToCosign: (set: ValidatorSet) -> [u8; 32],
+ // If we're actively cosigning or not.
+ ActivelyCosigning: (set: ValidatorSet) -> (),
// The weight accumulated for a topic.
AccumulatedWeight: (set: ValidatorSet, topic: Topic) -> u64,
@@ -236,6 +238,33 @@ impl TributaryDb {
) {
LatestSubstrateBlockToCosign::set(txn, set, &substrate_block_hash);
}
+ pub(crate) fn actively_cosigning(txn: &mut impl DbTxn, set: ValidatorSet) -> bool {
+ ActivelyCosigning::get(txn, set).is_some()
+ }
+ pub(crate) fn start_cosigning(
+ txn: &mut impl DbTxn,
+ set: ValidatorSet,
+ substrate_block_number: u64,
+ ) {
+ assert!(
+ ActivelyCosigning::get(txn, set).is_none(),
+ "starting cosigning while already cosigning"
+ );
+ ActivelyCosigning::set(txn, set, &());
+
+ TributaryDb::recognize_topic(
+ txn,
+ set,
+ Topic::Sign {
+ id: VariantSignId::Cosign(substrate_block_number),
+ attempt: 0,
+ round: SigningProtocolRound::Preprocess,
+ },
+ );
+ }
+ pub(crate) fn finish_cosigning(txn: &mut impl DbTxn, set: ValidatorSet) {
+ assert!(ActivelyCosigning::take(txn, set).is_some(), "finished cosigning but not cosigning");
+ }
pub(crate) fn recognize_topic(txn: &mut impl DbTxn, set: ValidatorSet, topic: Topic) {
AccumulatedWeight::set(txn, set, topic, &0);
diff --git a/coordinator/src/tributary/scan.rs b/coordinator/src/tributary/scan.rs
index 1a53bdda..bfc9760b 100644
--- a/coordinator/src/tributary/scan.rs
+++ b/coordinator/src/tributary/scan.rs
@@ -36,6 +36,34 @@ struct ScanBlock<'a, D: DbTxn, TD: Db> {
tributary: &'a TributaryReader
,
}
impl<'a, D: DbTxn, TD: Db> ScanBlock<'a, D, TD> {
+ fn potentially_start_cosign(&mut self) {
+ // Don't start a new cosigning instance if we're actively running one
+ if TributaryDb::actively_cosigning(self.txn, self.set) {
+ return;
+ }
+
+ // Start cosigning the latest intended-to-be-cosigned block
+ let Some(latest_substrate_block_to_cosign) =
+ TributaryDb::latest_substrate_block_to_cosign(self.txn, self.set)
+ else {
+ return;
+ };
+
+ let substrate_block_number = todo!("TODO");
+
+ // Mark us as actively cosigning
+ TributaryDb::start_cosigning(self.txn, self.set, substrate_block_number);
+ // Send the message for the processor to start signing
+ TributaryDb::send_message(
+ self.txn,
+ self.set,
+ messages::coordinator::CoordinatorMessage::CosignSubstrateBlock {
+ session: self.set.session,
+ block_number: substrate_block_number,
+ block: latest_substrate_block_to_cosign,
+ },
+ );
+ }
fn handle_application_tx(&mut self, block_number: u64, tx: Transaction) {
let signer = |signed: Signed| SeraiAddress(signed.signer.to_bytes());
@@ -105,41 +133,25 @@ impl<'a, D: DbTxn, TD: Db> ScanBlock<'a, D, TD> {
Transaction::Cosign { substrate_block_hash } => {
// Update the latest intended-to-be-cosigned Substrate block
TributaryDb::set_latest_substrate_block_to_cosign(self.txn, self.set, substrate_block_hash);
-
- // TODO: If we aren't currently cosigning a block, start cosigning this one
+ // Start a new cosign if we weren't already working on one
+ self.potentially_start_cosign();
}
Transaction::Cosigned { substrate_block_hash } => {
- // Start cosigning the latest intended-to-be-cosigned block
+ TributaryDb::finish_cosigning(self.txn, self.set);
+
+ // Fetch the latest intended-to-be-cosigned block
let Some(latest_substrate_block_to_cosign) =
TributaryDb::latest_substrate_block_to_cosign(self.txn, self.set)
else {
return;
};
- // If this is the block we just cosigned, return
+ // If this is the block we just cosigned, return, preventing us from signing it again
if latest_substrate_block_to_cosign == substrate_block_hash {
return;
}
- let substrate_block_number = todo!("TODO");
- // Whitelist the topic
- TributaryDb::recognize_topic(
- self.txn,
- self.set,
- Topic::Sign {
- id: VariantSignId::Cosign(substrate_block_number),
- attempt: 0,
- round: SigningProtocolRound::Preprocess,
- },
- );
- // Send the message for the processor to start signing
- TributaryDb::send_message(
- self.txn,
- self.set,
- messages::coordinator::CoordinatorMessage::CosignSubstrateBlock {
- session: self.set.session,
- block_number: substrate_block_number,
- block: substrate_block_hash,
- },
- );
+
+ // Since we do have a new cosign to work on, start it
+ self.potentially_start_cosign();
}
Transaction::SubstrateBlock { hash } => {
// Whitelist all of the IDs this Substrate block causes to be signed
|