Add Batch messages from processor, verify Batchs published on-chain

Renames Update to SignedBatch.

Checks Batch equality via a hash of the InInstructions. That prevents needing
to keep the Batch in node state or TX introspect.
This commit is contained in:
Luke Parker
2023-09-29 03:51:01 -04:00
parent 0be567ff69
commit 0eff3d9453
18 changed files with 281 additions and 80 deletions

View File

@@ -2,7 +2,10 @@ use scale::{Encode, Decode};
pub use serai_db::*;
use serai_client::validator_sets::primitives::{Session, KeyPair};
use serai_client::{
primitives::NetworkId,
validator_sets::primitives::{Session, KeyPair},
};
#[derive(Debug)]
pub struct SubstrateDb<D: Db>(pub D);
@@ -55,4 +58,23 @@ impl<D: Db> SubstrateDb<D> {
txn.put(key_0, session.clone());
txn.put(Self::session_key(&key_pair.1), session);
}
fn batch_instructions_key(network: NetworkId, id: u32) -> Vec<u8> {
Self::substrate_key(b"batch", (network, id).encode())
}
pub fn batch_instructions_hash<G: Get>(
getter: &G,
network: NetworkId,
id: u32,
) -> Option<[u8; 32]> {
getter.get(Self::batch_instructions_key(network, id)).map(|bytes| bytes.try_into().unwrap())
}
pub fn save_batch_instructions_hash(
txn: &mut D::Transaction<'_>,
network: NetworkId,
id: u32,
hash: [u8; 32],
) {
txn.put(Self::batch_instructions_key(network, id), hash);
}
}

View File

@@ -123,7 +123,8 @@ async fn handle_key_gen<D: Db, Pro: Processors>(
Ok(())
}
async fn handle_batch_and_burns<Pro: Processors>(
async fn handle_batch_and_burns<D: Db, Pro: Processors>(
db: &mut D,
processors: &Pro,
serai: &Serai,
block: &Block,
@@ -149,9 +150,15 @@ async fn handle_batch_and_burns<Pro: Processors>(
let mut burns = HashMap::new();
for batch in serai.get_batch_events(hash).await? {
if let InInstructionsEvent::Batch { network, id, block: network_block } = batch {
if let InInstructionsEvent::Batch { network, id, block: network_block, instructions_hash } =
batch
{
network_had_event(&mut burns, &mut batches, network);
let mut txn = db.txn();
SubstrateDb::<D>::save_batch_instructions_hash(&mut txn, network, id, instructions_hash);
txn.commit();
// Make sure this is the only Batch event for this network in this Block
assert!(batch_block.insert(network, network_block).is_none());
@@ -277,7 +284,7 @@ async fn handle_block<D: Db, CNT: Clone + Fn(&mut D, TributarySpec), Pro: Proces
// This does break the uniqueness of (hash, event_id) -> one event, yet
// (network, (hash, event_id)) remains valid as a unique ID for an event
if !SubstrateDb::<D>::handled_event(&db.0, hash, event_id) {
handle_batch_and_burns(processors, serai, &block).await?;
handle_batch_and_burns(&mut db.0, processors, serai, &block).await?;
}
let mut txn = db.0.txn();
SubstrateDb::<D>::handle_event(&mut txn, hash, event_id);