Add DoS limits to tributary and require provided transactions be ordered

This commit is contained in:
Luke Parker
2023-04-13 20:35:55 -04:00
parent 8b1bce6abd
commit 72dd665ebf
13 changed files with 262 additions and 294 deletions

View File

@@ -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

View File

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

View File

@@ -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());