Verify all Batchs published by the prior set

The new set publishing a `Batch` completes the handover protocol. The new set
should only publish a `Batch` once it believes the old set has completed all of
its on-external-chain activity, marking it honest and finite.

With the handover comes the acceptance of liability, hence the requirement for
all of the on-Serai-chain activity also needing verification. While most
activity would be verified in-real-time (upon ::Batch messages), the new set
will now explicitly verify the complete set of `Batch`s before beginning its
preprocess for its own `Batch` (the one accepting the handover).
This commit is contained in:
Luke Parker
2023-10-13 03:36:59 -04:00
parent 9aeece5bf6
commit 02edfd2935
4 changed files with 86 additions and 42 deletions

View File

@@ -8,6 +8,7 @@ use blake2::{
use scale::{Encode, Decode};
use serai_client::{
primitives::NetworkId,
validator_sets::primitives::ValidatorSet,
in_instructions::primitives::{Batch, SignedBatch},
};
@@ -95,15 +96,24 @@ impl<D: Db> MainDb<D> {
getter.get(Self::first_preprocess_key(network, id))
}
fn last_received_batch_key(network: NetworkId) -> Vec<u8> {
Self::main_key(b"last_received_batch", network.encode())
}
fn expected_batch_key(network: NetworkId, id: u32) -> Vec<u8> {
Self::main_key(b"expected_batch", (network, id).encode())
}
pub fn save_expected_batch(txn: &mut D::Transaction<'_>, batch: &Batch) {
txn.put(Self::last_received_batch_key(batch.network), batch.id.to_le_bytes());
txn.put(
Self::expected_batch_key(batch.network, batch.id),
Blake2b::<U32>::digest(batch.instructions.encode()),
);
}
pub fn last_received_batch<G: Get>(getter: &G, network: NetworkId) -> Option<u32> {
getter
.get(Self::last_received_batch_key(network))
.map(|id| u32::from_le_bytes(id.try_into().unwrap()))
}
pub fn expected_batch<G: Get>(getter: &G, network: NetworkId, id: u32) -> Option<[u8; 32]> {
getter.get(Self::expected_batch_key(network, id)).map(|batch| batch.try_into().unwrap())
}
@@ -131,4 +141,14 @@ impl<D: Db> MainDb<D> {
.get(Self::last_verified_batch_key(network))
.map(|id| u32::from_le_bytes(id.try_into().unwrap()))
}
fn did_handover_key(set: ValidatorSet) -> Vec<u8> {
Self::main_key(b"did_handover", set.encode())
}
pub fn set_did_handover(txn: &mut D::Transaction<'_>, set: ValidatorSet) {
txn.put(Self::did_handover_key(set), []);
}
pub fn did_handover<G: Get>(getter: &G, set: ValidatorSet) -> bool {
getter.get(Self::did_handover_key(set)).is_some()
}
}