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:
akildemir
2023-08-14 18:57:38 +03:00
committed by GitHub
parent a3441a6871
commit e680eabb62
17 changed files with 234 additions and 155 deletions

View File

@@ -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(),
},
),
)