mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 20:29:23 +00:00
Clean the transaction definitions in the coordinator
Moves to borsh for serialization. No longer includes nonces anywhere in the TX.
This commit is contained in:
@@ -135,7 +135,7 @@ impl<T: TransactionTrait> Block<T> {
|
||||
// Check TXs are sorted by nonce.
|
||||
let nonce = |tx: &Transaction<T>| {
|
||||
if let TransactionKind::Signed(_, Signed { nonce, .. }) = tx.kind() {
|
||||
*nonce
|
||||
nonce
|
||||
} else {
|
||||
0
|
||||
}
|
||||
|
||||
@@ -323,7 +323,7 @@ impl<D: Db, T: TransactionTrait> Blockchain<D, T> {
|
||||
}
|
||||
TransactionKind::Signed(order, Signed { signer, nonce, .. }) => {
|
||||
let next_nonce = nonce + 1;
|
||||
txn.put(Self::next_nonce_key(&self.genesis, signer, &order), next_nonce.to_le_bytes());
|
||||
txn.put(Self::next_nonce_key(&self.genesis, &signer, &order), next_nonce.to_le_bytes());
|
||||
self.mempool.remove(&tx.hash());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ impl<T: TransactionTrait> Transaction<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> TransactionKind<'_> {
|
||||
pub fn kind(&self) -> TransactionKind {
|
||||
match self {
|
||||
Transaction::Tendermint(tx) => tx.kind(),
|
||||
Transaction::Application(tx) => tx.kind(),
|
||||
|
||||
@@ -81,11 +81,11 @@ impl<D: Db, T: TransactionTrait> Mempool<D, T> {
|
||||
}
|
||||
Transaction::Application(tx) => match tx.kind() {
|
||||
TransactionKind::Signed(order, Signed { signer, nonce, .. }) => {
|
||||
let amount = *res.txs_per_signer.get(signer).unwrap_or(&0) + 1;
|
||||
res.txs_per_signer.insert(*signer, amount);
|
||||
let amount = *res.txs_per_signer.get(&signer).unwrap_or(&0) + 1;
|
||||
res.txs_per_signer.insert(signer, amount);
|
||||
|
||||
if let Some(prior_nonce) =
|
||||
res.last_nonce_in_mempool.insert((*signer, order.clone()), *nonce)
|
||||
res.last_nonce_in_mempool.insert((signer, order.clone()), nonce)
|
||||
{
|
||||
assert_eq!(prior_nonce, nonce - 1);
|
||||
}
|
||||
@@ -133,14 +133,14 @@ impl<D: Db, T: TransactionTrait> Mempool<D, T> {
|
||||
match app_tx.kind() {
|
||||
TransactionKind::Signed(order, Signed { signer, .. }) => {
|
||||
// Get the nonce from the blockchain
|
||||
let Some(blockchain_next_nonce) = blockchain_next_nonce(*signer, order.clone()) else {
|
||||
let Some(blockchain_next_nonce) = blockchain_next_nonce(signer, order.clone()) else {
|
||||
// Not a participant
|
||||
Err(TransactionError::InvalidSigner)?
|
||||
};
|
||||
let mut next_nonce = blockchain_next_nonce;
|
||||
|
||||
if let Some(mempool_last_nonce) =
|
||||
self.last_nonce_in_mempool.get(&(*signer, order.clone()))
|
||||
self.last_nonce_in_mempool.get(&(signer, order.clone()))
|
||||
{
|
||||
assert!(*mempool_last_nonce >= blockchain_next_nonce);
|
||||
next_nonce = *mempool_last_nonce + 1;
|
||||
@@ -148,14 +148,14 @@ impl<D: Db, T: TransactionTrait> Mempool<D, T> {
|
||||
|
||||
// If we have too many transactions from this sender, don't add this yet UNLESS we are
|
||||
// this sender
|
||||
let amount_in_pool = *self.txs_per_signer.get(signer).unwrap_or(&0) + 1;
|
||||
let amount_in_pool = *self.txs_per_signer.get(&signer).unwrap_or(&0) + 1;
|
||||
if !internal && (amount_in_pool > ACCOUNT_MEMPOOL_LIMIT) {
|
||||
Err(TransactionError::TooManyInMempool)?;
|
||||
}
|
||||
|
||||
verify_transaction(app_tx, self.genesis, &mut |_, _| Some(next_nonce))?;
|
||||
self.last_nonce_in_mempool.insert((*signer, order.clone()), next_nonce);
|
||||
self.txs_per_signer.insert(*signer, amount_in_pool);
|
||||
self.last_nonce_in_mempool.insert((signer, order.clone()), next_nonce);
|
||||
self.txs_per_signer.insert(signer, amount_in_pool);
|
||||
}
|
||||
TransactionKind::Unsigned => {
|
||||
// check we have the tx in the pool/chain
|
||||
@@ -205,7 +205,7 @@ impl<D: Db, T: TransactionTrait> Mempool<D, T> {
|
||||
// Sort signed by nonce
|
||||
let nonce = |tx: &Transaction<T>| {
|
||||
if let TransactionKind::Signed(_, Signed { nonce, .. }) = tx.kind() {
|
||||
*nonce
|
||||
nonce
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
@@ -242,11 +242,11 @@ impl<D: Db, T: TransactionTrait> Mempool<D, T> {
|
||||
|
||||
if let Some(tx) = self.txs.remove(tx) {
|
||||
if let TransactionKind::Signed(order, Signed { signer, nonce, .. }) = tx.kind() {
|
||||
let amount = *self.txs_per_signer.get(signer).unwrap() - 1;
|
||||
self.txs_per_signer.insert(*signer, amount);
|
||||
let amount = *self.txs_per_signer.get(&signer).unwrap() - 1;
|
||||
self.txs_per_signer.insert(signer, amount);
|
||||
|
||||
if self.last_nonce_in_mempool.get(&(*signer, order.clone())) == Some(nonce) {
|
||||
self.last_nonce_in_mempool.remove(&(*signer, order));
|
||||
if self.last_nonce_in_mempool.get(&(signer, order.clone())) == Some(&nonce) {
|
||||
self.last_nonce_in_mempool.remove(&(signer, order));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ impl ReadWrite for TendermintTx {
|
||||
}
|
||||
|
||||
impl Transaction for TendermintTx {
|
||||
fn kind(&self) -> TransactionKind<'_> {
|
||||
fn kind(&self) -> TransactionKind {
|
||||
// There's an assert elsewhere in the codebase expecting this behavior
|
||||
// If we do want to add Provided/Signed TendermintTxs, review the implications carefully
|
||||
TransactionKind::Unsigned
|
||||
|
||||
@@ -60,8 +60,8 @@ impl ReadWrite for NonceTransaction {
|
||||
}
|
||||
|
||||
impl TransactionTrait for NonceTransaction {
|
||||
fn kind(&self) -> TransactionKind<'_> {
|
||||
TransactionKind::Signed(vec![], &self.2)
|
||||
fn kind(&self) -> TransactionKind {
|
||||
TransactionKind::Signed(vec![], self.2.clone())
|
||||
}
|
||||
|
||||
fn hash(&self) -> [u8; 32] {
|
||||
|
||||
@@ -425,7 +425,7 @@ async fn block_tx_ordering() {
|
||||
}
|
||||
|
||||
impl TransactionTrait for SignedTx {
|
||||
fn kind(&self) -> TransactionKind<'_> {
|
||||
fn kind(&self) -> TransactionKind {
|
||||
match self {
|
||||
SignedTx::Signed(signed) => signed.kind(),
|
||||
SignedTx::Provided(pro) => pro.kind(),
|
||||
|
||||
@@ -67,7 +67,7 @@ impl ReadWrite for ProvidedTransaction {
|
||||
}
|
||||
|
||||
impl Transaction for ProvidedTransaction {
|
||||
fn kind(&self) -> TransactionKind<'_> {
|
||||
fn kind(&self) -> TransactionKind {
|
||||
match self.0[0] {
|
||||
1 => TransactionKind::Provided("order1"),
|
||||
2 => TransactionKind::Provided("order2"),
|
||||
@@ -119,8 +119,8 @@ impl ReadWrite for SignedTransaction {
|
||||
}
|
||||
|
||||
impl Transaction for SignedTransaction {
|
||||
fn kind(&self) -> TransactionKind<'_> {
|
||||
TransactionKind::Signed(vec![], &self.1)
|
||||
fn kind(&self) -> TransactionKind {
|
||||
TransactionKind::Signed(vec![], self.1.clone())
|
||||
}
|
||||
|
||||
fn hash(&self) -> [u8; 32] {
|
||||
|
||||
@@ -109,7 +109,7 @@ impl Signed {
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
#[derive(Clone, PartialEq, Eq, Debug)]
|
||||
pub enum TransactionKind<'a> {
|
||||
pub enum TransactionKind {
|
||||
/// This transaction should be provided by every validator, in an exact order.
|
||||
///
|
||||
/// The contained static string names the orderer to use. This allows two distinct provided
|
||||
@@ -137,14 +137,14 @@ pub enum TransactionKind<'a> {
|
||||
Unsigned,
|
||||
|
||||
/// A signed transaction.
|
||||
Signed(Vec<u8>, &'a Signed),
|
||||
Signed(Vec<u8>, Signed),
|
||||
}
|
||||
|
||||
// TODO: Should this be renamed TransactionTrait now that a literal Transaction exists?
|
||||
// Or should the literal Transaction be renamed to Event?
|
||||
pub trait Transaction: 'static + Send + Sync + Clone + Eq + Debug + ReadWrite {
|
||||
/// Return what type of transaction this is.
|
||||
fn kind(&self) -> TransactionKind<'_>;
|
||||
fn kind(&self) -> TransactionKind;
|
||||
|
||||
/// Return the hash of this transaction.
|
||||
///
|
||||
@@ -198,8 +198,8 @@ pub(crate) fn verify_transaction<F: GAIN, T: Transaction>(
|
||||
match tx.kind() {
|
||||
TransactionKind::Provided(_) | TransactionKind::Unsigned => {}
|
||||
TransactionKind::Signed(order, Signed { signer, nonce, signature }) => {
|
||||
if let Some(next_nonce) = get_and_increment_nonce(signer, &order) {
|
||||
if *nonce != next_nonce {
|
||||
if let Some(next_nonce) = get_and_increment_nonce(&signer, &order) {
|
||||
if nonce != next_nonce {
|
||||
Err(TransactionError::InvalidNonce)?;
|
||||
}
|
||||
} else {
|
||||
@@ -208,7 +208,7 @@ pub(crate) fn verify_transaction<F: GAIN, T: Transaction>(
|
||||
}
|
||||
|
||||
// TODO: Use a batch verification here
|
||||
if !signature.verify(*signer, tx.sig_hash(genesis)) {
|
||||
if !signature.verify(signer, tx.sig_hash(genesis)) {
|
||||
Err(TransactionError::InvalidSignature)?;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user