mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 04:09:23 +00:00
Improve batch handling (#316)
* restrict batch size to ~25kb * add batch size check to node * rate limit batches to 1 per serai block * add support for multiple batches for block * fix review comments * Misc fixes Doesn't yet update tests/processor until data flow is inspected. * Move the block from SignId to ProcessorMessage::BatchPreprocesses * Misc clean up --------- Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
This commit is contained in:
@@ -535,7 +535,7 @@ pub async fn handle_processors<D: Db, Pro: Processors, P: P2p>(
|
||||
|
||||
Some(Transaction::SubstrateBlock(block))
|
||||
}
|
||||
coordinator::ProcessorMessage::BatchPreprocess { id, preprocess } => {
|
||||
coordinator::ProcessorMessage::BatchPreprocess { id, block, preprocess } => {
|
||||
// If this is the first attempt instance, synchronize around the block first
|
||||
if id.attempt == 0 {
|
||||
// Save the preprocess to disk so we can publish it later
|
||||
@@ -545,7 +545,9 @@ pub async fn handle_processors<D: Db, Pro: Processors, P: P2p>(
|
||||
MainDb::<D>::save_first_preprocess(&mut txn, id.id, preprocess);
|
||||
txn.commit();
|
||||
|
||||
Some(Transaction::ExternalBlock(id.id))
|
||||
// TODO: This will publish one ExternalBlock per Batch. We should only publish one per
|
||||
// all batches within a block
|
||||
Some(Transaction::ExternalBlock(block.0))
|
||||
} else {
|
||||
Some(Transaction::BatchPreprocess(SignData {
|
||||
plan: id.id,
|
||||
|
||||
@@ -8,7 +8,7 @@ use frost::ThresholdParams;
|
||||
|
||||
use serai_client::{
|
||||
SeraiError, Block, Serai,
|
||||
primitives::BlockHash,
|
||||
primitives::{BlockHash, NetworkId},
|
||||
validator_sets::{
|
||||
primitives::{Session, ValidatorSet, KeyPair},
|
||||
ValidatorSetsEvent,
|
||||
@@ -157,21 +157,23 @@ async fn handle_batch_and_burns<Pro: Processors>(
|
||||
// While that shouldn't be needed, ensuring order never hurts, and may enable design choices
|
||||
// with regards to Processor <-> Coordinator message passing
|
||||
let mut networks_with_event = vec![];
|
||||
let mut network_had_event = |burns: &mut HashMap<_, _>, network| {
|
||||
let mut network_had_event = |burns: &mut HashMap<_, _>, batches: &mut HashMap<_, _>, network| {
|
||||
// Don't insert this network multiple times
|
||||
// A Vec is still used in order to maintain the insertion order
|
||||
if !networks_with_event.contains(&network) {
|
||||
networks_with_event.push(network);
|
||||
burns.insert(network, vec![]);
|
||||
batches.insert(network, vec![]);
|
||||
}
|
||||
};
|
||||
|
||||
let mut batch_block = HashMap::new();
|
||||
let mut batches = HashMap::<NetworkId, Vec<u32>>::new();
|
||||
let mut burns = HashMap::new();
|
||||
|
||||
for batch in serai.get_batch_events(hash).await? {
|
||||
if let InInstructionsEvent::Batch { network, id: _, block: network_block } = batch {
|
||||
network_had_event(&mut burns, network);
|
||||
if let InInstructionsEvent::Batch { network, id, block: network_block } = batch {
|
||||
network_had_event(&mut burns, &mut batches, network);
|
||||
|
||||
// Track what Serai acknowledges as the latest block for this network
|
||||
// If this Substrate block has multiple batches, the last batch's block will overwrite the
|
||||
@@ -180,6 +182,9 @@ async fn handle_batch_and_burns<Pro: Processors>(
|
||||
// the last batch will be the latest batch, so its block will be the latest block
|
||||
// This is just a mild optimization to prevent needing an additional RPC call to grab this
|
||||
batch_block.insert(network, network_block);
|
||||
|
||||
// Add the batch included by this block
|
||||
batches.get_mut(&network).unwrap().push(id);
|
||||
} else {
|
||||
panic!("Batch event wasn't Batch: {batch:?}");
|
||||
}
|
||||
@@ -188,12 +193,10 @@ async fn handle_batch_and_burns<Pro: Processors>(
|
||||
for burn in serai.get_burn_events(hash).await? {
|
||||
if let TokensEvent::Burn { address: _, balance, instruction } = burn {
|
||||
let network = balance.coin.network();
|
||||
network_had_event(&mut burns, network);
|
||||
network_had_event(&mut burns, &mut batches, network);
|
||||
|
||||
// network_had_event should register an entry in burns
|
||||
let mut burns_so_far = burns.remove(&network).unwrap();
|
||||
burns_so_far.push(OutInstructionWithBalance { balance, instruction });
|
||||
burns.insert(network, burns_so_far);
|
||||
burns.get_mut(&network).unwrap().push(OutInstructionWithBalance { balance, instruction });
|
||||
} else {
|
||||
panic!("Burn event wasn't Burn: {burn:?}");
|
||||
}
|
||||
@@ -230,6 +233,7 @@ async fn handle_batch_and_burns<Pro: Processors>(
|
||||
.map(|keys| keys.1.into_inner())
|
||||
.expect("batch/burn for network which never set keys"),
|
||||
burns: burns.remove(&network).unwrap(),
|
||||
batches: batches.remove(&network).unwrap(),
|
||||
},
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user