mirror of
https://github.com/serai-dex/serai.git
synced 2024-11-16 17:07:35 +00:00
Use a single Substrate signer, per intentions in #227
Removes key from Update as well, since it's no longer variable.
This commit is contained in:
parent
b91bd44476
commit
bccdabb53d
8 changed files with 33 additions and 47 deletions
|
@ -569,7 +569,7 @@ pub async fn handle_processors<D: Db, Pro: Processors, P: P2p>(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
ProcessorMessage::Substrate(inner_msg) => match inner_msg {
|
ProcessorMessage::Substrate(inner_msg) => match inner_msg {
|
||||||
processor_messages::substrate::ProcessorMessage::Update { key: _, batch } => {
|
processor_messages::substrate::ProcessorMessage::Update { batch } => {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
batch.batch.network, msg.network,
|
batch.batch.network, msg.network,
|
||||||
"processor sent us a batch for a different network than it was for",
|
"processor sent us a batch for a different network than it was for",
|
||||||
|
|
|
@ -176,7 +176,7 @@ pub mod substrate {
|
||||||
|
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, Serialize, Deserialize)]
|
#[derive(Clone, PartialEq, Eq, Debug, Zeroize, Serialize, Deserialize)]
|
||||||
pub enum ProcessorMessage {
|
pub enum ProcessorMessage {
|
||||||
Update { key: [u8; 32], batch: SignedBatch },
|
Update { batch: SignedBatch },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -157,8 +157,8 @@ struct TributaryMutable<N: Network, D: Db> {
|
||||||
// Substrate may mark tasks as completed, invalidating any existing mutable borrows.
|
// Substrate may mark tasks as completed, invalidating any existing mutable borrows.
|
||||||
// The safety of this follows as written above.
|
// The safety of this follows as written above.
|
||||||
|
|
||||||
// TODO: There should only be one SubstrateSigner at a time (see #277)
|
// There should only be one SubstrateSigner at a time (see #277)
|
||||||
substrate_signers: HashMap<[u8; 32], SubstrateSigner<D>>,
|
substrate_signer: Option<SubstrateSigner<D>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Items which are mutably borrowed by Substrate.
|
// Items which are mutably borrowed by Substrate.
|
||||||
|
@ -308,7 +308,9 @@ async fn handle_coordinator_msg<D: Db, N: Network, Co: Coordinator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
CoordinatorMessage::Coordinator(msg) => {
|
CoordinatorMessage::Coordinator(msg) => {
|
||||||
tributary_mutable.substrate_signers.get_mut(msg.key()).unwrap().handle(txn, msg).await;
|
if let Some(substrate_signer) = tributary_mutable.substrate_signer.as_mut() {
|
||||||
|
substrate_signer.handle(txn, msg).await;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CoordinatorMessage::Substrate(msg) => {
|
CoordinatorMessage::Substrate(msg) => {
|
||||||
|
@ -317,7 +319,7 @@ async fn handle_coordinator_msg<D: Db, N: Network, Co: Coordinator>(
|
||||||
// This is the first key pair for this network so no block has been finalized yet
|
// This is the first key pair for this network so no block has been finalized yet
|
||||||
let activation_number = if context.network_latest_finalized_block.0 == [0; 32] {
|
let activation_number = if context.network_latest_finalized_block.0 == [0; 32] {
|
||||||
assert!(tributary_mutable.signers.is_empty());
|
assert!(tributary_mutable.signers.is_empty());
|
||||||
assert!(tributary_mutable.substrate_signers.is_empty());
|
assert!(tributary_mutable.substrate_signer.is_none());
|
||||||
assert!(substrate_mutable.schedulers.is_empty());
|
assert!(substrate_mutable.schedulers.is_empty());
|
||||||
|
|
||||||
// Wait until a network's block's time exceeds Serai's time
|
// Wait until a network's block's time exceeds Serai's time
|
||||||
|
@ -373,10 +375,9 @@ async fn handle_coordinator_msg<D: Db, N: Network, Co: Coordinator>(
|
||||||
// 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, network_keys } =
|
let KeyConfirmed { substrate_keys, network_keys } =
|
||||||
tributary_mutable.key_gen.confirm(txn, set, key_pair).await;
|
tributary_mutable.key_gen.confirm(txn, set, key_pair).await;
|
||||||
tributary_mutable.substrate_signers.insert(
|
// TODO2: Don't immediately set this, set it once it's active
|
||||||
substrate_keys.group_key().to_bytes(),
|
tributary_mutable.substrate_signer =
|
||||||
SubstrateSigner::new(N::NETWORK, substrate_keys),
|
Some(SubstrateSigner::new(N::NETWORK, substrate_keys));
|
||||||
);
|
|
||||||
|
|
||||||
let key = network_keys.group_key();
|
let key = network_keys.group_key();
|
||||||
|
|
||||||
|
@ -408,9 +409,9 @@ async fn handle_coordinator_msg<D: Db, N: Network, Co: Coordinator>(
|
||||||
// We now have to acknowledge every block for this key up to the acknowledged block
|
// We now have to acknowledge every block for this key up to the acknowledged block
|
||||||
let outputs = substrate_mutable.scanner.ack_up_to_block(txn, key, block_id).await;
|
let outputs = substrate_mutable.scanner.ack_up_to_block(txn, key, block_id).await;
|
||||||
// Since this block was acknowledged, we no longer have to sign the batch for it
|
// Since this block was acknowledged, we no longer have to sign the batch for it
|
||||||
for batch_id in batches {
|
if let Some(substrate_signer) = tributary_mutable.substrate_signer.as_mut() {
|
||||||
for (_, signer) in tributary_mutable.substrate_signers.iter_mut() {
|
for batch_id in batches {
|
||||||
signer.batch_signed(txn, batch_id);
|
substrate_signer.batch_signed(txn, batch_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -506,7 +507,7 @@ async fn boot<N: Network, D: Db>(
|
||||||
let (mut scanner, active_keys) = Scanner::new(network.clone(), raw_db.clone());
|
let (mut scanner, active_keys) = Scanner::new(network.clone(), raw_db.clone());
|
||||||
|
|
||||||
let mut schedulers = HashMap::<Vec<u8>, Scheduler<N>>::new();
|
let mut schedulers = HashMap::<Vec<u8>, Scheduler<N>>::new();
|
||||||
let mut substrate_signers = HashMap::new();
|
let mut substrate_signer = None;
|
||||||
let mut signers = HashMap::new();
|
let mut signers = HashMap::new();
|
||||||
|
|
||||||
let main_db = MainDb::new(raw_db.clone());
|
let main_db = MainDb::new(raw_db.clone());
|
||||||
|
@ -516,11 +517,10 @@ async fn boot<N: Network, D: Db>(
|
||||||
|
|
||||||
let (substrate_keys, network_keys) = key_gen.keys(key);
|
let (substrate_keys, network_keys) = key_gen.keys(key);
|
||||||
|
|
||||||
let substrate_key = substrate_keys.group_key();
|
|
||||||
let substrate_signer = SubstrateSigner::new(N::NETWORK, substrate_keys);
|
|
||||||
// We don't have to load any state for this since the Scanner will re-fire any events
|
// We don't have to load any state for this since the Scanner will re-fire any events
|
||||||
// necessary
|
// necessary
|
||||||
substrate_signers.insert(substrate_key.to_bytes(), substrate_signer);
|
// TODO2: This uses most recent as signer, use the active one
|
||||||
|
substrate_signer = Some(SubstrateSigner::new(N::NETWORK, substrate_keys));
|
||||||
|
|
||||||
let mut signer = Signer::new(network.clone(), network_keys);
|
let mut signer = Signer::new(network.clone(), network_keys);
|
||||||
|
|
||||||
|
@ -554,7 +554,7 @@ async fn boot<N: Network, D: Db>(
|
||||||
|
|
||||||
(
|
(
|
||||||
main_db,
|
main_db,
|
||||||
TributaryMutable { key_gen, substrate_signers, signers },
|
TributaryMutable { key_gen, substrate_signer, signers },
|
||||||
SubstrateMutable { scanner, schedulers },
|
SubstrateMutable { scanner, schedulers },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -603,7 +603,7 @@ async fn run<N: Network, D: Db, Co: Coordinator>(mut raw_db: D, network: N, mut
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (key, signer) in tributary_mutable.substrate_signers.iter_mut() {
|
if let Some(signer) = tributary_mutable.substrate_signer.as_mut() {
|
||||||
while let Some(msg) = signer.events.pop_front() {
|
while let Some(msg) = signer.events.pop_front() {
|
||||||
match msg {
|
match msg {
|
||||||
SubstrateSignerEvent::ProcessorMessage(msg) => {
|
SubstrateSignerEvent::ProcessorMessage(msg) => {
|
||||||
|
@ -612,7 +612,6 @@ async fn run<N: Network, D: Db, Co: Coordinator>(mut raw_db: D, network: N, mut
|
||||||
SubstrateSignerEvent::SignedBatch(batch) => {
|
SubstrateSignerEvent::SignedBatch(batch) => {
|
||||||
coordinator
|
coordinator
|
||||||
.send(ProcessorMessage::Substrate(messages::substrate::ProcessorMessage::Update {
|
.send(ProcessorMessage::Substrate(messages::substrate::ProcessorMessage::Update {
|
||||||
key: *key,
|
|
||||||
batch,
|
batch,
|
||||||
}))
|
}))
|
||||||
.await;
|
.await;
|
||||||
|
@ -665,7 +664,7 @@ async fn run<N: Network, D: Db, Co: Coordinator>(mut raw_db: D, network: N, mut
|
||||||
let mut txn = raw_db.txn();
|
let mut txn = raw_db.txn();
|
||||||
|
|
||||||
match msg.unwrap() {
|
match msg.unwrap() {
|
||||||
ScannerEvent::Block { key, block, outputs } => {
|
ScannerEvent::Block { block, outputs } => {
|
||||||
let mut block_hash = [0; 32];
|
let mut block_hash = [0; 32];
|
||||||
block_hash.copy_from_slice(block.as_ref());
|
block_hash.copy_from_slice(block.as_ref());
|
||||||
// TODO: Move this out from Scanner now that the Scanner no longer handles batches
|
// TODO: Move this out from Scanner now that the Scanner no longer handles batches
|
||||||
|
@ -735,13 +734,11 @@ async fn run<N: Network, D: Db, Co: Coordinator>(mut raw_db: D, network: N, mut
|
||||||
for batch in batches {
|
for batch in batches {
|
||||||
info!("created batch {} ({} instructions)", batch.id, batch.instructions.len());
|
info!("created batch {} ({} instructions)", batch.id, batch.instructions.len());
|
||||||
|
|
||||||
// TODO: Don't reload both sets of keys in full just to get the Substrate public key
|
if let Some(substrate_signer) = tributary_mutable.substrate_signer.as_mut() {
|
||||||
tributary_mutable
|
substrate_signer
|
||||||
.substrate_signers
|
.sign(&mut txn, batch)
|
||||||
.get_mut(tributary_mutable.key_gen.keys(&key).0.group_key().to_bytes().as_slice())
|
.await;
|
||||||
.unwrap()
|
}
|
||||||
.sign(&mut txn, batch)
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -22,11 +22,7 @@ use crate::{
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub enum ScannerEvent<N: Network> {
|
pub enum ScannerEvent<N: Network> {
|
||||||
// Block scanned
|
// Block scanned
|
||||||
Block {
|
Block { block: <N::Block as Block<N>>::Id, outputs: Vec<N::Output> },
|
||||||
key: <N::Curve as Ciphersuite>::G,
|
|
||||||
block: <N::Block as Block<N>>::Id,
|
|
||||||
outputs: Vec<N::Output>,
|
|
||||||
},
|
|
||||||
// Eventuality completion found on-chain
|
// Eventuality completion found on-chain
|
||||||
Completed([u8; 32], <N::Transaction as Transaction<N>>::Id),
|
Completed([u8; 32], <N::Transaction as Transaction<N>>::Id),
|
||||||
}
|
}
|
||||||
|
@ -507,7 +503,8 @@ impl<N: Network, D: Db> Scanner<N, D> {
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
|
||||||
// Send all outputs
|
// Send all outputs
|
||||||
if !scanner.emit(ScannerEvent::Block { key, block: block_id, outputs }) {
|
// TODO2: Fire this with all outputs for all keys, not for each key
|
||||||
|
if !scanner.emit(ScannerEvent::Block { block: block_id, outputs }) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Write this number as scanned so we won't re-fire these outputs
|
// Write this number as scanned so we won't re-fire these outputs
|
||||||
|
|
|
@ -51,8 +51,7 @@ async fn spend<N: Network, D: Db>(
|
||||||
network.mine_block().await;
|
network.mine_block().await;
|
||||||
}
|
}
|
||||||
match timeout(Duration::from_secs(30), scanner.events.recv()).await.unwrap().unwrap() {
|
match timeout(Duration::from_secs(30), scanner.events.recv()).await.unwrap().unwrap() {
|
||||||
ScannerEvent::Block { key: this_key, block: _, outputs } => {
|
ScannerEvent::Block { block: _, outputs } => {
|
||||||
assert_eq!(this_key, key);
|
|
||||||
assert_eq!(outputs.len(), 1);
|
assert_eq!(outputs.len(), 1);
|
||||||
// Make sure this is actually a change output
|
// Make sure this is actually a change output
|
||||||
assert_eq!(outputs[0].kind(), OutputType::Change);
|
assert_eq!(outputs[0].kind(), OutputType::Change);
|
||||||
|
@ -89,8 +88,7 @@ pub async fn test_addresses<N: Network>(network: N) {
|
||||||
// Verify the Scanner picked them up
|
// Verify the Scanner picked them up
|
||||||
let outputs =
|
let outputs =
|
||||||
match timeout(Duration::from_secs(30), scanner.events.recv()).await.unwrap().unwrap() {
|
match timeout(Duration::from_secs(30), scanner.events.recv()).await.unwrap().unwrap() {
|
||||||
ScannerEvent::Block { key: this_key, block, outputs } => {
|
ScannerEvent::Block { block, outputs } => {
|
||||||
assert_eq!(this_key, key);
|
|
||||||
assert_eq!(block, block_id);
|
assert_eq!(block, block_id);
|
||||||
assert_eq!(outputs.len(), 1);
|
assert_eq!(outputs.len(), 1);
|
||||||
assert_eq!(outputs[0].kind(), OutputType::Branch);
|
assert_eq!(outputs[0].kind(), OutputType::Branch);
|
||||||
|
|
|
@ -55,8 +55,7 @@ pub async fn test_scanner<N: Network>(network: N) {
|
||||||
let verify_event = |mut scanner: ScannerHandle<N, MemDb>| async {
|
let verify_event = |mut scanner: ScannerHandle<N, MemDb>| async {
|
||||||
let outputs =
|
let outputs =
|
||||||
match timeout(Duration::from_secs(30), scanner.events.recv()).await.unwrap().unwrap() {
|
match timeout(Duration::from_secs(30), scanner.events.recv()).await.unwrap().unwrap() {
|
||||||
ScannerEvent::Block { key, block, outputs } => {
|
ScannerEvent::Block { block, outputs } => {
|
||||||
assert_eq!(key, keys.group_key());
|
|
||||||
assert_eq!(block, block_id);
|
assert_eq!(block, block_id);
|
||||||
assert_eq!(outputs.len(), 1);
|
assert_eq!(outputs.len(), 1);
|
||||||
assert_eq!(outputs[0].kind(), OutputType::External);
|
assert_eq!(outputs[0].kind(), OutputType::External);
|
||||||
|
|
|
@ -36,8 +36,7 @@ pub async fn test_wallet<N: Network>(network: N) {
|
||||||
let block_id = block.id();
|
let block_id = block.id();
|
||||||
|
|
||||||
match timeout(Duration::from_secs(30), scanner.events.recv()).await.unwrap().unwrap() {
|
match timeout(Duration::from_secs(30), scanner.events.recv()).await.unwrap().unwrap() {
|
||||||
ScannerEvent::Block { key: this_key, block, outputs } => {
|
ScannerEvent::Block { block, outputs } => {
|
||||||
assert_eq!(this_key, key);
|
|
||||||
assert_eq!(block, block_id);
|
assert_eq!(block, block_id);
|
||||||
assert_eq!(outputs.len(), 1);
|
assert_eq!(outputs.len(), 1);
|
||||||
(block_id, outputs)
|
(block_id, outputs)
|
||||||
|
@ -109,8 +108,7 @@ pub async fn test_wallet<N: Network>(network: N) {
|
||||||
}
|
}
|
||||||
|
|
||||||
match timeout(Duration::from_secs(30), scanner.events.recv()).await.unwrap().unwrap() {
|
match timeout(Duration::from_secs(30), scanner.events.recv()).await.unwrap().unwrap() {
|
||||||
ScannerEvent::Block { key: this_key, block: block_id, outputs: these_outputs } => {
|
ScannerEvent::Block { block: block_id, outputs: these_outputs } => {
|
||||||
assert_eq!(this_key, key);
|
|
||||||
assert_eq!(block_id, block.id());
|
assert_eq!(block_id, block.id());
|
||||||
assert_eq!(these_outputs, outputs);
|
assert_eq!(these_outputs, outputs);
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,11 +122,8 @@ pub(crate) async fn sign_batch(
|
||||||
if preprocesses.contains_key(&i) {
|
if preprocesses.contains_key(&i) {
|
||||||
match coordinator.recv_message().await {
|
match coordinator.recv_message().await {
|
||||||
messages::ProcessorMessage::Substrate(messages::substrate::ProcessorMessage::Update {
|
messages::ProcessorMessage::Substrate(messages::substrate::ProcessorMessage::Update {
|
||||||
key,
|
|
||||||
batch: this_batch,
|
batch: this_batch,
|
||||||
}) => {
|
}) => {
|
||||||
assert_eq!(key.as_slice(), &id.key);
|
|
||||||
|
|
||||||
if batch.is_none() {
|
if batch.is_none() {
|
||||||
assert!(PublicKey::from_raw(id.key.clone().try_into().unwrap())
|
assert!(PublicKey::from_raw(id.key.clone().try_into().unwrap())
|
||||||
.verify(&batch_message(&this_batch.batch), &this_batch.signature));
|
.verify(&batch_message(&this_batch.batch), &this_batch.signature));
|
||||||
|
|
Loading…
Reference in a new issue