mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-09 12:49:23 +00:00
Improve provided handling (#381)
* fix typos * remove tributary sleeping * handle not locally provided txs * use topic number instead of waiting list * Clean-up, fixes 1) Uses a single TXN in provided 2) Doesn't continue on non-local provided inside verify_block, skipping further execution of checks 3) Upon local provision of already on-chain TX, compares --------- Co-authored-by: Luke Parker <lukeparker5132@gmail.com>
This commit is contained in:
@@ -33,7 +33,10 @@ pub enum BlockError {
|
||||
/// An unsigned transaction which was already added to the chain was present again.
|
||||
#[error("an unsigned transaction which was already added to the chain was present again")]
|
||||
UnsignedAlreadyIncluded,
|
||||
/// Transactions weren't ordered as expected (Provided, followed by Unsigned, folowed by Signed).
|
||||
/// A provided transaction which was already added to the chain was present again.
|
||||
#[error("an provided transaction which was already added to the chain was present again")]
|
||||
ProvidedAlreadyIncluded,
|
||||
/// Transactions weren't ordered as expected (Provided, followed by Unsigned, followed by Signed).
|
||||
#[error("transactions weren't ordered as expected (Provided, Unsigned, Signed)")]
|
||||
WrongTransactionOrder,
|
||||
/// The block had a provided transaction this validator has yet to be provided.
|
||||
@@ -175,6 +178,8 @@ impl<T: TransactionTrait> Block<T> {
|
||||
schema: N::SignatureScheme,
|
||||
commit: impl Fn(u32) -> Option<Commit<N::SignatureScheme>>,
|
||||
unsigned_in_chain: impl Fn([u8; 32]) -> bool,
|
||||
provided_in_chain: impl Fn([u8; 32]) -> bool, // TODO: merge this with unsigned_on_chain?
|
||||
allow_non_local_provided: bool,
|
||||
) -> Result<(), BlockError> {
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||
enum Order {
|
||||
@@ -209,18 +214,22 @@ impl<T: TransactionTrait> Block<T> {
|
||||
|
||||
let current_tx_order = match tx.kind() {
|
||||
TransactionKind::Provided(order) => {
|
||||
let Some(local) = locally_provided.get_mut(order).and_then(|deque| deque.pop_front())
|
||||
else {
|
||||
Err(BlockError::NonLocalProvided(txs.pop().unwrap()))?
|
||||
};
|
||||
// Since this was a provided TX, it must be an application TX
|
||||
let Transaction::Application(tx) = tx else {
|
||||
Err(BlockError::NonLocalProvided(txs.pop().unwrap()))?
|
||||
};
|
||||
if tx != &local {
|
||||
Err(BlockError::DistinctProvided)?;
|
||||
if provided_in_chain(tx_hash) {
|
||||
Err(BlockError::ProvidedAlreadyIncluded)?;
|
||||
}
|
||||
|
||||
if let Some(local) = locally_provided.get_mut(order).and_then(|deque| deque.pop_front()) {
|
||||
// Since this was a provided TX, it must be an application TX
|
||||
let Transaction::Application(tx) = tx else {
|
||||
Err(BlockError::NonLocalProvided(txs.pop().unwrap()))?
|
||||
};
|
||||
if tx != &local {
|
||||
Err(BlockError::DistinctProvided)?;
|
||||
}
|
||||
} else if !allow_non_local_provided {
|
||||
Err(BlockError::NonLocalProvided(txs.pop().unwrap()))?
|
||||
};
|
||||
|
||||
Order::Provided
|
||||
}
|
||||
TransactionKind::Unsigned => {
|
||||
@@ -241,12 +250,6 @@ impl<T: TransactionTrait> Block<T> {
|
||||
}
|
||||
last_tx_order = current_tx_order;
|
||||
|
||||
if current_tx_order == Order::Provided {
|
||||
// We don't need to call verify_transaction since we did when we locally provided this
|
||||
// transaction. Since it's identical, it must be valid
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: should we modify the verify_transaction to take `Transaction<T>` or
|
||||
// use this pattern of verifying tendermint Txs and app txs differently?
|
||||
match tx {
|
||||
|
||||
Reference in New Issue
Block a user