Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions crates/hashi/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -969,4 +969,35 @@ mod tests {
// Should be a no-op, not an error.
db.prune_messages_below(100).unwrap();
}

#[test]
fn test_epoch_store_writes_at_explicit_epoch_not_self_epoch() {
use crate::storage::EpochPublicMessagesStore;
use crate::storage::PublicMessagesStore;
use std::collections::BTreeMap;
use std::num::NonZeroU16;

let tmpdir = tempfile::Builder::new().tempdir().unwrap();
let db = std::sync::Arc::new(Database::open(tmpdir.path()).unwrap());

let mut store = EpochPublicMessagesStore::new(db.clone(), 87);

let dealer = Address::new([1u8; 32]);
let mut rotation_msgs: BTreeMap<NonZeroU16, avss::Message> = BTreeMap::new();
rotation_msgs.insert(NonZeroU16::new(1).unwrap(), create_test_message());

store
.store_rotation_messages(71, &dealer, &rotation_msgs)
.unwrap();

assert!(
store.get_rotation_messages(71, &dealer).unwrap().is_some(),
"rotation messages written with explicit epoch=71 must be readable at epoch=71"
);

assert!(
store.get_rotation_messages(87, &dealer).unwrap().is_none(),
"rotation messages must not leak to the store's self.epoch=87"
);
}
}
62 changes: 38 additions & 24 deletions crates/hashi/src/mpc/mpc_except_signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -262,19 +262,19 @@ impl MpcManager {
}
let signature = match &request.messages {
Messages::Dkg(msg) => {
self.store_dkg_message(sender, msg)?;
self.store_dkg_message(self.mpc_config.epoch, sender, msg)?;
self.try_sign_dkg_message(sender, &request.messages)?
}
Messages::Rotation(msgs) => {
let previous = self
.previous_output
.clone()
.ok_or_else(|| MpcError::NotReady("Rotation not started".into()))?;
self.store_rotation_messages(sender, msgs)?;
self.store_rotation_messages(self.mpc_config.epoch, sender, msgs)?;
self.try_sign_rotation_messages(&previous, sender, &request.messages)?
}
Messages::NonceGeneration(nonce) => {
self.store_nonce_message(sender, nonce);
self.store_nonce_message(self.mpc_config.epoch, sender, nonce)?;
self.try_sign_nonce_message(sender, &request.messages)?
}
};
Expand Down Expand Up @@ -1381,37 +1381,43 @@ impl MpcManager {
dealer.create_message(rng)
}

fn store_dkg_message(&mut self, dealer: Address, message: &avss::Message) -> MpcResult<()> {
fn store_dkg_message(
&mut self,
epoch: u64,
dealer: Address,
message: &avss::Message,
) -> MpcResult<()> {
self.dkg_messages.insert(dealer, message.clone());
self.public_messages_store
.store_dealer_message(&dealer, message)
.store_dealer_message(epoch, &dealer, message)
.map_err(|e| MpcError::StorageError(e.to_string()))?;
Ok(())
}

fn store_rotation_messages(
&mut self,
epoch: u64,
dealer: Address,
messages: &RotationMessages,
) -> MpcResult<()> {
self.rotation_messages.insert(dealer, messages.clone());
self.public_messages_store
.store_rotation_messages(&dealer, messages)
.store_rotation_messages(epoch, &dealer, messages)
.map_err(|e| MpcError::StorageError(e.to_string()))?;
Ok(())
}

// TODO: Change return type to `MpcResult<()>` and propagate disk errors
// (mirroring `store_dkg_message` and `store_rotation_messages`).
fn store_nonce_message(&mut self, dealer: Address, nonce: &NonceMessage) {
fn store_nonce_message(
&mut self,
epoch: u64,
dealer: Address,
nonce: &NonceMessage,
) -> MpcResult<()> {
self.nonce_messages.insert(dealer, nonce.clone());
if let Err(e) = self.public_messages_store.store_nonce_message(
nonce.batch_index,
&dealer,
&nonce.message,
) {
tracing::error!("Failed to persist nonce message for dealer {dealer:?}: {e}");
}
self.public_messages_store
.store_nonce_message(epoch, nonce.batch_index, &dealer, &nonce.message)
.map_err(|e| MpcError::StorageError(e.to_string()))?;
Ok(())
}

fn needs_nonce_retrieval(
Expand Down Expand Up @@ -1808,7 +1814,8 @@ impl MpcManager {
);
};
let mut mgr = mpc_manager.write().unwrap();
mgr.store_dkg_message(message.dealer_address, msg)?;
let epoch = mgr.mpc_config.epoch;
mgr.store_dkg_message(epoch, message.dealer_address, msg)?;
return Ok(());
}
tracing::info!(
Expand Down Expand Up @@ -1869,7 +1876,8 @@ impl MpcManager {
);
};
let mut mgr = mpc_manager.write().unwrap();
mgr.store_nonce_message(message.dealer_address, nonce);
let epoch = mgr.mpc_config.epoch;
mgr.store_nonce_message(epoch, message.dealer_address, nonce)?;
return Ok(());
}
tracing::info!(
Expand Down Expand Up @@ -1901,7 +1909,7 @@ impl MpcManager {
Some(msg) => Messages::Dkg(msg.clone()),
None => {
let msg = self.create_dealer_message(rng);
self.store_dkg_message(self.address, &msg)?;
self.store_dkg_message(self.mpc_config.epoch, self.address, &msg)?;
Messages::Dkg(msg)
}
};
Expand All @@ -1918,7 +1926,7 @@ impl MpcManager {
Some(msgs) => Messages::Rotation(msgs.clone()),
None => {
let msgs = self.create_rotation_messages(previous, rng);
self.store_rotation_messages(self.address, &msgs)?;
self.store_rotation_messages(self.mpc_config.epoch, self.address, &msgs)?;
Messages::Rotation(msgs)
}
};
Expand All @@ -1936,7 +1944,7 @@ impl MpcManager {
None => {
let msgs = self.create_nonce_dealer_message(batch_index, rng)?;
if let Messages::NonceGeneration(ref nonce) = msgs {
self.store_nonce_message(self.address, nonce);
self.store_nonce_message(self.mpc_config.epoch, self.address, nonce)?;
}
msgs
}
Expand Down Expand Up @@ -2028,7 +2036,8 @@ impl MpcManager {
continue;
};
let mut mgr = mpc_manager.write().unwrap();
mgr.store_rotation_messages(message.dealer_address, msgs)?;
let epoch = mgr.mpc_config.epoch;
mgr.store_rotation_messages(epoch, message.dealer_address, msgs)?;
return Ok(());
}
tracing::info!(
Expand Down Expand Up @@ -3313,12 +3322,17 @@ impl MpcManager {
let actual_hash = compute_messages_hash(&response.messages);
if actual_hash == message.messages_hash {
let mut mgr = mpc_manager.write().unwrap();
let source_epoch = mgr.source_epoch;
match &response.messages {
Messages::Dkg(msg) => {
mgr.store_dkg_message(message.dealer_address, msg)?;
mgr.store_dkg_message(source_epoch, message.dealer_address, msg)?;
}
Messages::Rotation(msgs) => {
mgr.store_rotation_messages(message.dealer_address, msgs)?;
mgr.store_rotation_messages(
source_epoch,
message.dealer_address,
msgs,
)?;
}
_ => {
tracing::warn!(
Expand Down
Loading
Loading