Correct when the Processor starts using the first key

It waited for CONFIRMATIONS + 1 confirmations, instead of CONFIRMATIONS
confirmations.

Also adds a lib interface to access the coin traits and its constants.
This commit is contained in:
Luke Parker 2023-07-24 15:36:35 -04:00
parent 6df1b46313
commit 5e565fa3ef
No known key found for this signature in database
4 changed files with 44 additions and 21 deletions

View file

@ -0,0 +1,14 @@
use ciphersuite::Ciphersuite;
use crate::coins::Coin;
// Generate a static additional key for a given chain in a globally consistent manner
// Doesn't consider the current group key to increase the simplicity of verifying Serai's status
// Takes an index, k, to support protocols which use multiple secondary keys
// Presumably a view key
pub fn additional_key<C: Coin>(k: u64) -> <C::Curve as Ciphersuite>::F {
<C::Curve as Ciphersuite>::hash_to_F(
b"Serai DEX Additional Key",
&[C::ID.as_bytes(), &k.to_le_bytes()].concat(),
)
}

7
processor/src/lib.rs Normal file
View file

@ -0,0 +1,7 @@
mod plan;
pub use plan::*;
pub mod coins;
mod additional_key;
pub use additional_key::additional_key;

View file

@ -32,12 +32,6 @@ use message_queue::{Service, client::MessageQueue};
mod plan; mod plan;
pub use plan::*; pub use plan::*;
mod db;
pub use db::*;
mod coordinator;
pub use coordinator::*;
mod coins; mod coins;
use coins::{OutputType, Output, PostFeeBranch, Block, Coin}; use coins::{OutputType, Output, PostFeeBranch, Block, Coin};
#[cfg(feature = "bitcoin")] #[cfg(feature = "bitcoin")]
@ -45,6 +39,15 @@ use coins::Bitcoin;
#[cfg(feature = "monero")] #[cfg(feature = "monero")]
use coins::Monero; use coins::Monero;
mod additional_key;
pub use additional_key::additional_key;
mod db;
pub use db::*;
mod coordinator;
pub use coordinator::*;
mod key_gen; mod key_gen;
use key_gen::{KeyConfirmed, KeyGen}; use key_gen::{KeyConfirmed, KeyGen};
@ -63,17 +66,6 @@ use scheduler::Scheduler;
#[cfg(test)] #[cfg(test)]
mod tests; mod tests;
// Generate a static additional key for a given chain in a globally consistent manner
// Doesn't consider the current group key to increase the simplicity of verifying Serai's status
// Takes an index, k, to support protocols which use multiple secondary keys
// Presumably a view key
pub(crate) fn additional_key<C: Coin>(k: u64) -> <C::Curve as Ciphersuite>::F {
<C::Curve as Ciphersuite>::hash_to_F(
b"Serai DEX Additional Key",
&[C::ID.as_bytes(), &k.to_le_bytes()].concat(),
)
}
async fn get_latest_block_number<C: Coin>(coin: &C) -> usize { async fn get_latest_block_number<C: Coin>(coin: &C) -> usize {
loop { loop {
match coin.get_latest_block_number().await { match coin.get_latest_block_number().await {
@ -328,9 +320,14 @@ async fn handle_coordinator_msg<D: Db, C: Coin, Co: Coordinator>(
assert!(substrate_mutable.schedulers.is_empty()); assert!(substrate_mutable.schedulers.is_empty());
// Wait until a coin's block's time exceeds Serai's time // Wait until a coin's block's time exceeds Serai's time
// TODO: This assumes the coin has a monotonic clock for its blocks' times, which
// isn't a viable assumption
// If the latest block number is 10, then the block indexd by 1 has 10 confirms
// 10 + 1 - 10 = 1
while get_block( while get_block(
coin, coin,
get_latest_block_number(coin).await.saturating_sub(C::CONFIRMATIONS), (get_latest_block_number(coin).await + 1).saturating_sub(C::CONFIRMATIONS),
) )
.await .await
.time() < .time() <
@ -345,9 +342,12 @@ async fn handle_coordinator_msg<D: Db, C: Coin, Co: Coordinator>(
} }
// Find the first block to do so // Find the first block to do so
let mut earliest = get_latest_block_number(coin).await.saturating_sub(C::CONFIRMATIONS); let mut earliest = (get_latest_block_number(coin).await + 1).saturating_sub(C::CONFIRMATIONS);
assert!(get_block(coin, earliest).await.time() >= context.serai_time); assert!(get_block(coin, earliest).await.time() >= context.serai_time);
while get_block(coin, earliest - 1).await.time() >= context.serai_time { // earliest > 0 prevents a panic if Serai creates keys before the genesis block
// which... should be impossible
// Yet a prevented panic is a prevented panic
while (earliest > 0) && (get_block(coin, earliest - 1).await.time() >= context.serai_time) {
earliest -= 1; earliest -= 1;
} }
@ -364,6 +364,8 @@ async fn handle_coordinator_msg<D: Db, C: Coin, Co: Coordinator>(
.expect("KeyConfirmed from context we haven't synced") .expect("KeyConfirmed from context we haven't synced")
}; };
info!("activating {set:?}'s keys at {activation_number}");
// See TributaryMutable's struct definition for why this block is safe // See TributaryMutable's struct definition for why this block is safe
let KeyConfirmed { substrate_keys, coin_keys } = let KeyConfirmed { substrate_keys, coin_keys } =
tributary_mutable.key_gen.confirm(txn, set, key_pair).await; tributary_mutable.key_gen.confirm(txn, set, key_pair).await;

View file

@ -278,7 +278,7 @@ impl<C: Coin, D: Db> ScannerHandle<C, D> {
panic!("only a single key is supported at this time"); panic!("only a single key is supported at this time");
} }
info!("Rotating to key {}", hex::encode(key.to_bytes())); info!("Rotating scanner to key {} at {activation_number}", hex::encode(key.to_bytes()));
let (_, outputs) = ScannerDb::<C, D>::save_scanned_block(txn, &key, activation_number); let (_, outputs) = ScannerDb::<C, D>::save_scanned_block(txn, &key, activation_number);
scanner.ram_scanned.insert(key.to_bytes().as_ref().to_vec(), activation_number); scanner.ram_scanned.insert(key.to_bytes().as_ref().to_vec(), activation_number);