Stop trying to publish a Batch if another node does

This commit is contained in:
Luke Parker 2023-08-26 21:36:13 -04:00
parent 9adefa4c2c
commit 22f3c9e58f
No known key found for this signature in database
3 changed files with 28 additions and 7 deletions

View file

@ -596,8 +596,21 @@ pub async fn handle_processors<D: Db, Pro: Processors, P: P2p>(
break;
}
Err(e) => {
// TODO: Check if this failed because the batch was already published by someone
// else
if let Ok(latest_block) = serai.get_latest_block().await {
if let Ok(Some(last)) =
serai.get_last_batch_for_network(latest_block.hash(), batch.batch.network).await
{
if last >= batch.batch.id {
log::info!(
"another coordinator executed batch {:?} {} (block {})",
batch.batch.network,
batch.batch.id,
hex::encode(batch.batch.block),
);
break;
}
}
}
log::error!("couldn't connect to Serai node to publish batch TX: {:?}", e);
tokio::time::sleep(Duration::from_secs(10)).await;
}

View file

@ -22,6 +22,14 @@ impl Serai {
self.storage(PALLET, "LatestNetworkBlock", Some(vec![scale_value(network)]), hash).await
}
pub async fn get_last_batch_for_network(
&self,
hash: [u8; 32],
network: NetworkId,
) -> Result<Option<u32>, SeraiError> {
self.storage(PALLET, "LastBatch", Some(vec![scale_value(network)]), hash).await
}
pub async fn get_batch_events(
&self,
block: [u8; 32],

View file

@ -52,10 +52,10 @@ pub mod pallet {
#[pallet::pallet]
pub struct Pallet<T>(PhantomData<T>);
// The amount of batches a network has issued, which is also the ID to use for the next batch
// The ID of the last executed Batch for a network.
#[pallet::storage]
#[pallet::getter(fn batches)]
pub(crate) type Batches<T: Config> = StorageMap<_, Blake2_256, NetworkId, u32, OptionQuery>;
pub(crate) type LastBatch<T: Config> = StorageMap<_, Blake2_256, NetworkId, u32, OptionQuery>;
// The last Serai block in which this validator set included a batch
#[pallet::storage]
@ -117,7 +117,7 @@ pub mod pallet {
// this to be safe
LastBatchBlock::<T>::insert(batch.network, frame_system::Pallet::<T>::block_number());
Batches::<T>::insert(batch.network, batch.id);
LastBatch::<T>::insert(batch.network, batch.id);
LatestNetworkBlock::<T>::insert(batch.network, batch.block);
Self::deposit_event(Event::Batch {
network: batch.network,
@ -174,9 +174,9 @@ pub mod pallet {
}
// Verify the batch is sequential
// Batches has the last ID set. The next ID should be it + 1
// LastBatch has the last ID set. The next ID should be it + 1
// If there's no ID, the next ID should be 0
let expected = Batches::<T>::get(network).map_or(0, |prev| prev + 1);
let expected = LastBatch::<T>::get(network).map_or(0, |prev| prev + 1);
if batch.batch.id < expected {
Err(InvalidTransaction::Stale)?;
}