mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-12 05:59:23 +00:00
Add DoS limits to tributary and require provided transactions be ordered
This commit is contained in:
@@ -1,7 +1,4 @@
|
||||
use std::{
|
||||
io,
|
||||
collections::{HashSet, HashMap},
|
||||
};
|
||||
use std::{io, collections::HashMap};
|
||||
|
||||
use zeroize::Zeroizing;
|
||||
use rand::{RngCore, CryptoRng};
|
||||
@@ -19,9 +16,6 @@ use crate::{ReadWrite, Signed, TransactionError, TransactionKind, Transaction, v
|
||||
#[cfg(test)]
|
||||
mod signed;
|
||||
|
||||
#[cfg(test)]
|
||||
mod provided;
|
||||
|
||||
pub fn random_signed<R: RngCore + CryptoRng>(rng: &mut R) -> Signed {
|
||||
Signed {
|
||||
signer: <Ristretto as Ciphersuite>::G::random(&mut *rng),
|
||||
@@ -127,7 +121,7 @@ pub fn signed_transaction<R: RngCore + CryptoRng>(
|
||||
);
|
||||
|
||||
let mut nonces = HashMap::from([(signer, nonce)]);
|
||||
verify_transaction(&tx, genesis, &mut HashSet::new(), &mut nonces).unwrap();
|
||||
verify_transaction(&tx, genesis, &mut nonces).unwrap();
|
||||
assert_eq!(nonces, HashMap::from([(tx.1.signer, tx.1.nonce.wrapping_add(1))]));
|
||||
|
||||
tx
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
use std::collections::{HashSet, HashMap};
|
||||
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use crate::{Transaction, verify_transaction, tests::random_provided_transaction};
|
||||
|
||||
#[test]
|
||||
fn provided_transaction() {
|
||||
let tx = random_provided_transaction(&mut OsRng);
|
||||
|
||||
// Make sure this works when provided
|
||||
let mut provided = HashSet::from([tx.hash()]);
|
||||
verify_transaction(&tx, [0x88; 32], &mut provided, &mut HashMap::new()).unwrap();
|
||||
assert_eq!(provided.len(), 0);
|
||||
|
||||
// Make sure this fails when not provided
|
||||
assert!(verify_transaction(&tx, [0x88; 32], &mut HashSet::new(), &mut HashMap::new()).is_err());
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::collections::{HashSet, HashMap};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
@@ -37,7 +37,6 @@ fn signed_transaction() {
|
||||
assert!(verify_transaction(
|
||||
&tx,
|
||||
Blake2s256::digest(genesis).into(),
|
||||
&mut HashSet::new(),
|
||||
&mut HashMap::from([(tx.1.signer, tx.1.nonce)]),
|
||||
)
|
||||
.is_err());
|
||||
@@ -46,26 +45,18 @@ fn signed_transaction() {
|
||||
{
|
||||
let mut tx = tx.clone();
|
||||
tx.0 = Blake2s256::digest(tx.0).to_vec();
|
||||
assert!(verify_transaction(
|
||||
&tx,
|
||||
genesis,
|
||||
&mut HashSet::new(),
|
||||
&mut HashMap::from([(tx.1.signer, tx.1.nonce)]),
|
||||
)
|
||||
.is_err());
|
||||
assert!(
|
||||
verify_transaction(&tx, genesis, &mut HashMap::from([(tx.1.signer, tx.1.nonce)]),).is_err()
|
||||
);
|
||||
}
|
||||
|
||||
// Different signer
|
||||
{
|
||||
let mut tx = tx.clone();
|
||||
tx.1.signer += Ristretto::generator();
|
||||
assert!(verify_transaction(
|
||||
&tx,
|
||||
genesis,
|
||||
&mut HashSet::new(),
|
||||
&mut HashMap::from([(tx.1.signer, tx.1.nonce)]),
|
||||
)
|
||||
.is_err());
|
||||
assert!(
|
||||
verify_transaction(&tx, genesis, &mut HashMap::from([(tx.1.signer, tx.1.nonce)]),).is_err()
|
||||
);
|
||||
}
|
||||
|
||||
// Different nonce
|
||||
@@ -73,42 +64,30 @@ fn signed_transaction() {
|
||||
#[allow(clippy::redundant_clone)] // False positive?
|
||||
let mut tx = tx.clone();
|
||||
tx.1.nonce = tx.1.nonce.wrapping_add(1);
|
||||
assert!(verify_transaction(
|
||||
&tx,
|
||||
genesis,
|
||||
&mut HashSet::new(),
|
||||
&mut HashMap::from([(tx.1.signer, tx.1.nonce)]),
|
||||
)
|
||||
.is_err());
|
||||
assert!(
|
||||
verify_transaction(&tx, genesis, &mut HashMap::from([(tx.1.signer, tx.1.nonce)]),).is_err()
|
||||
);
|
||||
}
|
||||
|
||||
// Different signature
|
||||
{
|
||||
let mut tx = tx.clone();
|
||||
tx.1.signature.R += Ristretto::generator();
|
||||
assert!(verify_transaction(
|
||||
&tx,
|
||||
genesis,
|
||||
&mut HashSet::new(),
|
||||
&mut HashMap::from([(tx.1.signer, tx.1.nonce)]),
|
||||
)
|
||||
.is_err());
|
||||
assert!(
|
||||
verify_transaction(&tx, genesis, &mut HashMap::from([(tx.1.signer, tx.1.nonce)]),).is_err()
|
||||
);
|
||||
}
|
||||
{
|
||||
let mut tx = tx.clone();
|
||||
tx.1.signature.s += <Ristretto as Ciphersuite>::F::ONE;
|
||||
assert!(verify_transaction(
|
||||
&tx,
|
||||
genesis,
|
||||
&mut HashSet::new(),
|
||||
&mut HashMap::from([(tx.1.signer, tx.1.nonce)]),
|
||||
)
|
||||
.is_err());
|
||||
assert!(
|
||||
verify_transaction(&tx, genesis, &mut HashMap::from([(tx.1.signer, tx.1.nonce)]),).is_err()
|
||||
);
|
||||
}
|
||||
|
||||
// Sanity check the original TX was never mutated and is valid
|
||||
let mut nonces = HashMap::from([(tx.1.signer, tx.1.nonce)]);
|
||||
verify_transaction(&tx, genesis, &mut HashSet::new(), &mut nonces).unwrap();
|
||||
verify_transaction(&tx, genesis, &mut nonces).unwrap();
|
||||
assert_eq!(nonces, HashMap::from([(tx.1.signer, tx.1.nonce.wrapping_add(1))]));
|
||||
}
|
||||
|
||||
@@ -119,7 +98,6 @@ fn invalid_nonce() {
|
||||
assert!(verify_transaction(
|
||||
&tx,
|
||||
genesis,
|
||||
&mut HashSet::new(),
|
||||
&mut HashMap::from([(tx.1.signer, tx.1.nonce.wrapping_add(1))]),
|
||||
)
|
||||
.is_err());
|
||||
|
||||
Reference in New Issue
Block a user