diff --git a/processor/src/additional_key.rs b/processor/src/additional_key.rs new file mode 100644 index 00000000..0c492581 --- /dev/null +++ b/processor/src/additional_key.rs @@ -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(k: u64) -> ::F { + ::hash_to_F( + b"Serai DEX Additional Key", + &[C::ID.as_bytes(), &k.to_le_bytes()].concat(), + ) +} diff --git a/processor/src/lib.rs b/processor/src/lib.rs new file mode 100644 index 00000000..265cbb5f --- /dev/null +++ b/processor/src/lib.rs @@ -0,0 +1,7 @@ +mod plan; +pub use plan::*; + +pub mod coins; + +mod additional_key; +pub use additional_key::additional_key; diff --git a/processor/src/main.rs b/processor/src/main.rs index e7c618c2..7c40b654 100644 --- a/processor/src/main.rs +++ b/processor/src/main.rs @@ -32,12 +32,6 @@ use message_queue::{Service, client::MessageQueue}; mod plan; pub use plan::*; -mod db; -pub use db::*; - -mod coordinator; -pub use coordinator::*; - mod coins; use coins::{OutputType, Output, PostFeeBranch, Block, Coin}; #[cfg(feature = "bitcoin")] @@ -45,6 +39,15 @@ use coins::Bitcoin; #[cfg(feature = "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; use key_gen::{KeyConfirmed, KeyGen}; @@ -63,17 +66,6 @@ use scheduler::Scheduler; #[cfg(test)] 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(k: u64) -> ::F { - ::hash_to_F( - b"Serai DEX Additional Key", - &[C::ID.as_bytes(), &k.to_le_bytes()].concat(), - ) -} - async fn get_latest_block_number(coin: &C) -> usize { loop { match coin.get_latest_block_number().await { @@ -328,9 +320,14 @@ async fn handle_coordinator_msg( assert!(substrate_mutable.schedulers.is_empty()); // 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( coin, - get_latest_block_number(coin).await.saturating_sub(C::CONFIRMATIONS), + (get_latest_block_number(coin).await + 1).saturating_sub(C::CONFIRMATIONS), ) .await .time() < @@ -345,9 +342,12 @@ async fn handle_coordinator_msg( } // 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); - 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; } @@ -364,6 +364,8 @@ async fn handle_coordinator_msg( .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 let KeyConfirmed { substrate_keys, coin_keys } = tributary_mutable.key_gen.confirm(txn, set, key_pair).await; diff --git a/processor/src/scanner.rs b/processor/src/scanner.rs index fd2fd110..5ef52730 100644 --- a/processor/src/scanner.rs +++ b/processor/src/scanner.rs @@ -278,7 +278,7 @@ impl ScannerHandle { 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::::save_scanned_block(txn, &key, activation_number); scanner.ram_scanned.insert(key.to_bytes().as_ref().to_vec(), activation_number);