From c65bb707412bf67d3aad3f992f7b14beb5543747 Mon Sep 17 00:00:00 2001 From: Luke Parker Date: Mon, 21 Aug 2023 23:48:33 -0400 Subject: [PATCH] Remove SlashVote per #349 --- coordinator/src/tributary/scanner.rs | 14 -- coordinator/tributary/src/block.rs | 2 +- coordinator/tributary/src/mempool.rs | 2 +- coordinator/tributary/src/tendermint/mod.rs | 24 ++- coordinator/tributary/src/tendermint/tx.rs | 154 +----------------- coordinator/tributary/src/tests/blockchain.rs | 101 ++---------- coordinator/tributary/src/tests/mempool.rs | 28 +--- .../tributary/src/tests/transaction/mod.rs | 21 +-- .../src/tests/transaction/tendermint.rs | 82 +++------- 9 files changed, 59 insertions(+), 369 deletions(-) diff --git a/coordinator/src/tributary/scanner.rs b/coordinator/src/tributary/scanner.rs index 497300bf..7740f668 100644 --- a/coordinator/src/tributary/scanner.rs +++ b/coordinator/src/tributary/scanner.rs @@ -76,20 +76,6 @@ async fn handle_block< // TODO: disconnect the node from network/ban from further participation in Tributary } - TributaryTransaction::Tendermint(TendermintTx::SlashVote(vote)) => { - // TODO: make sure same signer doesn't vote twice - - // increment the counter for this vote - let vote_key = TributaryDb::::slash_vote_key(genesis, vote.id, vote.target); - let mut count = txn.get(&vote_key).map_or(0, |c| u32::from_le_bytes(c.try_into().unwrap())); - count += 1; // TODO: Increase by weight, not by 1 - txn.put(vote_key, count.to_le_bytes()); - - // TODO: Check if a supermajority of validators, by weight, voted, and increment slash - // points if so - // If a node has a certain number more than the median slash points, the node should be - // removed - } TributaryTransaction::Application(tx) => { handle_application_tx::( tx, diff --git a/coordinator/tributary/src/block.rs b/coordinator/tributary/src/block.rs index 4e0c5050..0a7a2f25 100644 --- a/coordinator/tributary/src/block.rs +++ b/coordinator/tributary/src/block.rs @@ -251,7 +251,7 @@ impl Block { // use this pattern of verifying tendermint Txs and app txs differently? match tx { Transaction::Tendermint(tx) => { - match verify_tendermint_tx::(tx, genesis, schema.clone(), &commit) { + match verify_tendermint_tx::(tx, schema.clone(), &commit) { Ok(()) => {} Err(e) => Err(BlockError::TransactionError(e))?, } diff --git a/coordinator/tributary/src/mempool.rs b/coordinator/tributary/src/mempool.rs index 7a7cdf37..4838fd51 100644 --- a/coordinator/tributary/src/mempool.rs +++ b/coordinator/tributary/src/mempool.rs @@ -112,7 +112,7 @@ impl Mempool { } // verify the tx - if verify_tendermint_tx::(tendermint_tx, self.genesis, schema, commit).is_err() { + if verify_tendermint_tx::(tendermint_tx, schema, commit).is_err() { return false; } } diff --git a/coordinator/tributary/src/tendermint/mod.rs b/coordinator/tributary/src/tendermint/mod.rs index a2147c9e..edfcb48e 100644 --- a/coordinator/tributary/src/tendermint/mod.rs +++ b/coordinator/tributary/src/tendermint/mod.rs @@ -6,7 +6,7 @@ use async_trait::async_trait; use subtle::ConstantTimeEq; use zeroize::{Zeroize, Zeroizing}; -use rand::{SeedableRng, seq::SliceRandom, rngs::OsRng}; +use rand::{SeedableRng, seq::SliceRandom}; use rand_chacha::ChaCha12Rng; use transcript::{Transcript, RecommendedTranscript}; @@ -43,11 +43,11 @@ use tokio::{ use crate::{ TENDERMINT_MESSAGE, TRANSACTION_MESSAGE, BLOCK_MESSAGE, ReadWrite, transaction::Transaction as TransactionTrait, Transaction, BlockHeader, Block, BlockError, - Blockchain, P2p, tendermint::tx::SlashVote, + Blockchain, P2p, }; pub mod tx; -use tx::{TendermintTx, VoteSignature}; +use tx::TendermintTx; const DST: &[u8] = b"Tributary Tendermint Commit Aggregator"; @@ -312,21 +312,17 @@ impl Network for TendermintNetwork ); let signer = self.signer(); - let tx = match slash_event { + let Some(tx) = (match slash_event { SlashEvent::WithEvidence(m1, m2) => { // create an unsigned evidence tx - TendermintTx::SlashEvidence((m1, m2).encode()) + Some(TendermintTx::SlashEvidence((m1, m2).encode())) } - SlashEvent::Id(reason, block, round) => { - // create a signed vote tx - let mut tx = TendermintTx::SlashVote(SlashVote { - id: (reason, block, round).encode().try_into().unwrap(), - target: validator.encode().try_into().unwrap(), - sig: VoteSignature::default(), - }); - tx.sign(&mut OsRng, signer.genesis, &signer.key); - tx + SlashEvent::Id(_reason, _block, _round) => { + // TODO: Increase locally observed slash points + None } + }) else { + return; }; // add tx to blockchain and broadcast to peers diff --git a/coordinator/tributary/src/tendermint/tx.rs b/coordinator/tributary/src/tendermint/tx.rs index ea7cac40..d6818382 100644 --- a/coordinator/tributary/src/tendermint/tx.rs +++ b/coordinator/tributary/src/tendermint/tx.rs @@ -1,19 +1,10 @@ -use core::ops::Deref; -use std::{io, vec, default::Default}; +use std::io; use scale::Decode; -use zeroize::Zeroizing; +use blake2::{Digest, Blake2s256}; -use blake2::{Digest, Blake2s256, Blake2b512}; - -use rand::{RngCore, CryptoRng}; - -use ciphersuite::{ - group::{GroupEncoding, ff::Field}, - Ciphersuite, Ristretto, -}; -use schnorr::SchnorrSignature; +use ciphersuite::{Ciphersuite, Ristretto}; use crate::{ transaction::{Transaction, TransactionKind, TransactionError}, @@ -28,72 +19,10 @@ use tendermint::{ ext::{Network, Commit, RoundNumber, SignatureScheme}, }; -/// Signing data for a slash vote. -/// -/// The traditional Signed uses a nonce, whereas votes aren't required/expected to be ordered. -/// Accordingly, a simple uniqueness check works instead. -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct VoteSignature { - pub signer: ::G, - pub signature: SchnorrSignature, -} - -impl ReadWrite for VoteSignature { - fn read(reader: &mut R) -> io::Result { - let signer = Ristretto::read_G(reader)?; - let signature = SchnorrSignature::::read(reader)?; - - Ok(VoteSignature { signer, signature }) - } - - fn write(&self, writer: &mut W) -> io::Result<()> { - writer.write_all(&self.signer.to_bytes())?; - self.signature.write(writer) - } -} - -impl Default for VoteSignature { - fn default() -> Self { - VoteSignature { - signer: Ristretto::generator(), - signature: SchnorrSignature::::read(&mut [0; 64].as_slice()).unwrap(), - } - } -} - -/// A vote to slash a malicious validator. -#[derive(Clone, PartialEq, Eq, Debug)] -pub struct SlashVote { - pub id: [u8; 13], // vote id(slash event id) - pub target: [u8; 32], // who to slash - pub sig: VoteSignature, // signature -} - -impl ReadWrite for SlashVote { - fn read(reader: &mut R) -> io::Result { - let mut id = [0; 13]; - let mut target = [0; 32]; - reader.read_exact(&mut id)?; - reader.read_exact(&mut target)?; - let sig = VoteSignature::read(reader)?; - - Ok(SlashVote { id, target, sig }) - } - - fn write(&self, writer: &mut W) -> io::Result<()> { - writer.write_all(&self.id)?; - writer.write_all(&self.target)?; - self.sig.write(writer) - } -} - #[allow(clippy::large_enum_variant)] #[derive(Clone, PartialEq, Eq, Debug)] pub enum TendermintTx { SlashEvidence(Vec), - // TODO: should the SlashVote.sig be directly in the enum - // like as in (SlashVote, sig) since the sig is sig of the tx. - SlashVote(SlashVote), } impl ReadWrite for TendermintTx { @@ -126,10 +55,6 @@ impl ReadWrite for TendermintTx { } Ok(TendermintTx::SlashEvidence(data)) } - 1 => { - let vote = SlashVote::read(reader)?; - Ok(TendermintTx::SlashVote(vote)) - } _ => Err(io::Error::new(io::ErrorKind::Other, "invalid transaction type")), } } @@ -141,10 +66,6 @@ impl ReadWrite for TendermintTx { writer.write_all(&u32::try_from(ev.len()).unwrap().to_le_bytes())?; writer.write_all(ev) } - TendermintTx::SlashVote(vote) => { - writer.write_all(&[1])?; - vote.write(writer) - } } } } @@ -157,32 +78,12 @@ impl Transaction for TendermintTx { } fn hash(&self) -> [u8; 32] { - let mut tx = self.serialize(); - if let TendermintTx::SlashVote(vote) = self { - // Make sure the part we're cutting off is the signature - assert_eq!(tx.drain((tx.len() - 64) ..).collect::>(), vote.sig.signature.serialize()); - } - Blake2s256::digest(tx).into() + Blake2s256::digest(self.serialize()).into() } - fn sig_hash(&self, genesis: [u8; 32]) -> ::F { + fn sig_hash(&self, _genesis: [u8; 32]) -> ::F { match self { TendermintTx::SlashEvidence(_) => panic!("sig_hash called on slash evidence transaction"), - TendermintTx::SlashVote(vote) => { - let signature = &vote.sig.signature; - ::F::from_bytes_mod_order_wide( - &Blake2b512::digest( - [ - b"Tributary Slash Vote", - genesis.as_ref(), - &self.hash(), - signature.R.to_bytes().as_ref(), - ] - .concat(), - ) - .into(), - ) - } } } @@ -191,34 +92,6 @@ impl Transaction for TendermintTx { } } -impl TendermintTx { - // Sign a transaction - pub fn sign( - &mut self, - rng: &mut R, - genesis: [u8; 32], - key: &Zeroizing<::F>, - ) { - fn signature(tx: &mut TendermintTx) -> Option<&mut VoteSignature> { - match tx { - TendermintTx::SlashVote(vote) => Some(&mut vote.sig), - _ => None, - } - } - - signature(self).unwrap().signer = Ristretto::generator() * key.deref(); - - let sig_nonce = Zeroizing::new(::F::random(rng)); - signature(self).unwrap().signature.R = - ::generator() * sig_nonce.deref(); - - let sig_hash = self.sig_hash(genesis); - - signature(self).unwrap().signature = - SchnorrSignature::::sign(key, sig_nonce, sig_hash); - } -} - pub fn decode_evidence( mut ev: &[u8], ) -> Result<(SignedMessageFor, Option>), TransactionError> { @@ -234,13 +107,13 @@ pub fn decode_evidence( // re-implements an entire foreign library's checks for malicious behavior). pub(crate) fn verify_tendermint_tx( tx: &TendermintTx, - genesis: [u8; 32], schema: N::SignatureScheme, commit: impl Fn(u32) -> Option>, ) -> Result<(), TransactionError> { tx.verify()?; match tx { + // TODO: Only allow one evidence per validator, since evidence is fatal TendermintTx::SlashEvidence(ev) => { let (first, second) = decode_evidence::(ev)?; @@ -332,21 +205,6 @@ pub(crate) fn verify_tendermint_tx( _ => Err(TransactionError::InvalidContent)?, } } - TendermintTx::SlashVote(vote) => { - // TODO: verify the target is actually one of our validators? - // this shouldn't be a problem because if the target isn't valid, no one else - // gonna vote on it. But we still have to think about spam votes. - - // TODO: we need to check signer is a participant - - // TODO: Move this into the standalone TendermintTx verify - let sig = &vote.sig; - // verify the tx signature - // TODO: Use Schnorr half-aggregation and a batch verification here - if !sig.signature.verify(sig.signer, tx.sig_hash(genesis)) { - Err(TransactionError::InvalidSignature)?; - } - } } Ok(()) diff --git a/coordinator/tributary/src/tests/blockchain.rs b/coordinator/tributary/src/tests/blockchain.rs index 31cdf178..0f58b599 100644 --- a/coordinator/tributary/src/tests/blockchain.rs +++ b/coordinator/tributary/src/tests/blockchain.rs @@ -19,10 +19,10 @@ use crate::{ transaction::Transaction as TransactionTrait, TransactionError, Transaction, ProvidedError, ProvidedTransactions, merkle, BlockError, Block, Blockchain, - tendermint::{TendermintNetwork, Validators, tx::TendermintTx, Signer, TendermintBlock}, + tendermint::{TendermintNetwork, Validators, Signer, TendermintBlock}, tests::{ ProvidedTransaction, SignedTransaction, random_provided_transaction, p2p::DummyP2p, - new_genesis, random_vote_tx, random_evidence_tx, + new_genesis, random_evidence_tx, }, }; @@ -149,34 +149,6 @@ fn invalid_block() { // signature (which it explicitly isn't allowed to anyways) assert_eq!(block.header.transactions, merkle(&[block.transactions[0].hash()])); } - - { - // Invalid vote signature - let mut blockchain = blockchain.clone(); - let vote_tx = random_vote_tx(&mut OsRng, genesis); - assert!(blockchain.add_transaction::( - true, - Transaction::Tendermint(vote_tx), - validators.clone() - )); - let mut block = blockchain.build_block::(validators.clone()); - blockchain.verify_block::(&block, validators.clone()).unwrap(); - match &mut block.transactions[0] { - Transaction::Tendermint(tx) => match tx { - TendermintTx::SlashVote(vote) => { - vote.sig.signature.s += ::F::ONE; - } - _ => panic!("non-vote tx found"), - }, - _ => panic!("non-tendermint tx found"), - } - - assert!(blockchain.verify_block::(&block, validators.clone()).is_err()); - - // Make sure this isn't because the merkle changed due to the transaction hash including the - // signature (which it explicitly isn't allowed to anyways) - assert_eq!(block.header.transactions, merkle(&[block.transactions[0].hash()])); - } } #[test] @@ -281,61 +253,6 @@ fn provided_transaction() { assert!(blockchain.add_block::(&block, vec![], validators.clone()).is_err()); } -#[test] -fn tendermint_vote_tx() { - let genesis = new_genesis(); - let validators = Arc::new(Validators::new(genesis, vec![]).unwrap()); - - let (_, mut blockchain) = new_blockchain::(genesis, &[]); - - let test = |blockchain: &mut Blockchain, - mempool: Vec>| { - let tip = blockchain.tip(); - for tx in mempool.clone() { - let Transaction::Tendermint(tx) = tx else { - panic!("non-tendermint tx found"); - }; - assert!(blockchain.add_transaction::( - true, - Transaction::Tendermint(tx), - validators.clone() - )); - } - let block = blockchain.build_block::(validators.clone()); - - assert_eq!(blockchain.tip(), tip); - assert_eq!(block.header.parent, tip); - - // Make sure all transactions were included - for bt in &block.transactions { - assert!(mempool.contains(bt)); - } - - // Make sure the merkle was correct - // Uses block.transactions instead of mempool as order may differ between the two - assert_eq!( - block.header.transactions, - merkle(&block.transactions.iter().map(Transaction::hash).collect::>()), - ); - - // Verify and add the block - blockchain.verify_block::(&block, validators.clone()).unwrap(); - assert!(blockchain.add_block::(&block, vec![], validators.clone()).is_ok()); - assert_eq!(blockchain.tip(), block.hash()); - }; - - // test with single tx - let tx = random_vote_tx(&mut OsRng, genesis); - test(&mut blockchain, vec![Transaction::Tendermint(tx)]); - - // test with multiple txs - let mut mempool: Vec> = vec![]; - for _ in 0 .. 5 { - mempool.push(Transaction::Tendermint(random_vote_tx(&mut OsRng, genesis))); - } - test(&mut blockchain, mempool); -} - #[tokio::test] async fn tendermint_evidence_tx() { let genesis = new_genesis(); @@ -397,8 +314,8 @@ async fn tendermint_evidence_tx() { test(&mut blockchain, mempool, validators); } -#[test] -fn block_tx_ordering() { +#[tokio::test] +async fn block_tx_ordering() { #[derive(Debug, PartialEq, Eq, Clone)] enum SignedTx { Signed(Box), @@ -451,10 +368,10 @@ fn block_tx_ordering() { let genesis = new_genesis(); let key = Zeroizing::new(::F::random(&mut OsRng)); - let validators = Arc::new(Validators::new(genesis, vec![]).unwrap()); // signer let signer = crate::tests::signed_transaction(&mut OsRng, genesis, &key, 0).1.signer; + let validators = Arc::new(Validators::new(genesis, vec![(signer, 1)]).unwrap()); let (_, mut blockchain) = new_blockchain::(genesis, &[signer]); let tip = blockchain.tip(); @@ -469,7 +386,13 @@ fn block_tx_ordering() { assert!(blockchain.add_transaction::(true, signed_tx.clone(), validators.clone())); mempool.push(signed_tx); - let unsigned_tx = Transaction::Tendermint(random_vote_tx(&mut OsRng, genesis)); + let unsigned_tx = Transaction::Tendermint( + random_evidence_tx::( + Signer::new(genesis, key.clone()).into(), + TendermintBlock(vec![u8::try_from(i).unwrap()]), + ) + .await, + ); assert!(blockchain.add_transaction::(true, unsigned_tx.clone(), validators.clone())); mempool.push(unsigned_tx); diff --git a/coordinator/tributary/src/tests/mempool.rs b/coordinator/tributary/src/tests/mempool.rs index b4e36ebf..20b69cc7 100644 --- a/coordinator/tributary/src/tests/mempool.rs +++ b/coordinator/tributary/src/tests/mempool.rs @@ -13,9 +13,7 @@ use crate::{ transaction::Transaction as TransactionTrait, tendermint::{TendermintBlock, Validators, Signer, TendermintNetwork}, ACCOUNT_MEMPOOL_LIMIT, Transaction, Mempool, - tests::{ - SignedTransaction, signed_transaction, p2p::DummyP2p, random_vote_tx, random_evidence_tx, - }, + tests::{SignedTransaction, signed_transaction, p2p::DummyP2p, random_evidence_tx}, }; type N = TendermintNetwork; @@ -55,17 +53,6 @@ async fn mempool_addition() { )); assert_eq!(mempool.next_nonce(&signer), Some(1)); - // add a tendermint vote tx - let vote_tx = random_vote_tx(&mut OsRng, genesis); - assert!(mempool.add::( - &blockchain_next_nonces, - true, - Transaction::Tendermint(vote_tx.clone()), - validators.clone(), - unsigned_in_chain, - commit, - )); - // add a tendermint evidence tx let evidence_tx = random_evidence_tx::(Signer::new(genesis, key.clone()).into(), TendermintBlock(vec![])) @@ -91,14 +78,6 @@ async fn mempool_addition() { unsigned_in_chain, commit, )); - assert!(!mempool.add::( - &blockchain_next_nonces, - true, - Transaction::Tendermint(vote_tx.clone()), - validators.clone(), - unsigned_in_chain, - commit, - )); assert!(!mempool.add::( &blockchain_next_nonces, true, @@ -146,18 +125,17 @@ async fn mempool_addition() { assert_eq!(mempool.next_nonce(&second_signer), Some(3)); // Getting a block should work - assert_eq!(mempool.block(&blockchain_next_nonces, unsigned_in_chain).len(), 5); + assert_eq!(mempool.block(&blockchain_next_nonces, unsigned_in_chain).len(), 4); // If the blockchain says an account had its nonce updated, it should cause a prune blockchain_next_nonces.insert(signer, 1); let mut block = mempool.block(&blockchain_next_nonces, unsigned_in_chain); - assert_eq!(block.len(), 4); + assert_eq!(block.len(), 3); assert!(!block.iter().any(|tx| tx.hash() == first_tx.hash())); assert_eq!(mempool.txs(), &block.drain(..).map(|tx| (tx.hash(), tx)).collect::>()); // Removing should also successfully prune mempool.remove(&tx.hash()); - mempool.remove(&vote_tx.hash()); assert_eq!( mempool.txs(), diff --git a/coordinator/tributary/src/tests/transaction/mod.rs b/coordinator/tributary/src/tests/transaction/mod.rs index bd213017..a7d3abcb 100644 --- a/coordinator/tributary/src/tests/transaction/mod.rs +++ b/coordinator/tributary/src/tests/transaction/mod.rs @@ -22,10 +22,7 @@ use ::tendermint::{ use crate::{ transaction::{Signed, TransactionError, TransactionKind, Transaction, verify_transaction}, ReadWrite, - tendermint::{ - tx::{SlashVote, VoteSignature, TendermintTx}, - Validators, Signer, - }, + tendermint::{tx::TendermintTx, Validators, Signer}, }; #[cfg(test)] @@ -205,19 +202,3 @@ pub async fn random_evidence_tx( let signed = signed_from_data::(signer, signer_id, 0, 0, data).await; TendermintTx::SlashEvidence((signed, None::>).encode()) } - -pub fn random_vote_tx(rng: &mut R, genesis: [u8; 32]) -> TendermintTx { - // private key - let key = Zeroizing::new(::F::random(&mut *rng)); - - // vote data - let mut id = [0u8; 13]; - let mut target = [0u8; 32]; - rng.fill_bytes(&mut id); - rng.fill_bytes(&mut target); - - let mut tx = TendermintTx::SlashVote(SlashVote { id, target, sig: VoteSignature::default() }); - tx.sign(rng, genesis, &key); - - tx -} diff --git a/coordinator/tributary/src/tests/transaction/tendermint.rs b/coordinator/tributary/src/tests/transaction/tendermint.rs index f36efd12..108121b5 100644 --- a/coordinator/tributary/src/tests/transaction/tendermint.rs +++ b/coordinator/tributary/src/tests/transaction/tendermint.rs @@ -4,7 +4,6 @@ use zeroize::Zeroizing; use rand::{RngCore, rngs::OsRng}; use ciphersuite::{Ristretto, Ciphersuite, group::ff::Field}; -use schnorr::SchnorrSignature; use scale::Encode; @@ -24,54 +23,25 @@ use crate::{ TendermintBlock, Signer, Validators, TendermintNetwork, }, tests::{ - p2p::DummyP2p, SignedTransaction, new_genesis, random_evidence_tx, random_vote_tx, - tendermint_meta, signed_from_data, + p2p::DummyP2p, SignedTransaction, random_evidence_tx, tendermint_meta, signed_from_data, }, }; type N = TendermintNetwork; -#[test] -fn vote_tx() { - let genesis = new_genesis(); - let mut tx = random_vote_tx(&mut OsRng, genesis); - - let commit = |_: u32| -> Option>> { - Some(Commit::> { end_time: 0, validators: vec![], signature: vec![] }) - }; - let validators = Arc::new(Validators::new(genesis, vec![]).unwrap()); - - // should pass - verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).unwrap(); - - if let TendermintTx::SlashVote(vote) = &mut tx { - vote.sig.signature = SchnorrSignature::read(&mut [0; 64].as_slice()).unwrap(); - } else { - panic!("SlashVote TX wasn't SlashVote"); - } - - // should fail - assert!(verify_tendermint_tx::(&tx, genesis, validators, commit).is_err()); -} - #[tokio::test] async fn serialize_tendermint() { // make a tendermint tx with random evidence - let (genesis, signer, _, _) = tendermint_meta().await; + let (_, signer, _, _) = tendermint_meta().await; let tx = random_evidence_tx::(signer.into(), TendermintBlock(vec![])).await; let res = TendermintTx::read::<&[u8]>(&mut tx.serialize().as_ref()).unwrap(); assert_eq!(res, tx); - - // with vote tx - let vote_tx = random_vote_tx(&mut OsRng, genesis); - let vote_res = TendermintTx::read::<&[u8]>(&mut vote_tx.serialize().as_ref()).unwrap(); - assert_eq!(vote_res, vote_tx); } #[tokio::test] async fn invalid_valid_round() { // signer - let (genesis, signer, signer_id, validators) = tendermint_meta().await; + let (_, signer, signer_id, validators) = tendermint_meta().await; let commit = |_: u32| -> Option>> { Some(Commit::> { end_time: 0, validators: vec![], signature: vec![] }) }; @@ -87,13 +57,13 @@ async fn invalid_valid_round() { // This should be invalid evidence if a valid valid round is specified let (_, tx) = valid_round_tx(None).await; - assert!(verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).is_err()); + assert!(verify_tendermint_tx::(&tx, validators.clone(), commit).is_err()); // If an invalid valid round is specified (>= current), this should be invalid evidence let (mut signed, tx) = valid_round_tx(Some(RoundNumber(0))).await; // should pass - verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).unwrap(); + verify_tendermint_tx::(&tx, validators.clone(), commit).unwrap(); // change the signature let mut random_sig = [0u8; 64]; @@ -102,12 +72,12 @@ async fn invalid_valid_round() { let tx = TendermintTx::SlashEvidence((signed.clone(), None::>).encode()); // should fail - assert!(verify_tendermint_tx::(&tx, genesis, validators, commit).is_err()); + assert!(verify_tendermint_tx::(&tx, validators, commit).is_err()); } #[tokio::test] async fn invalid_precommit_signature() { - let (genesis, signer, signer_id, validators) = tendermint_meta().await; + let (_, signer, signer_id, validators) = tendermint_meta().await; let commit = |i: u32| -> Option>> { assert_eq!(i, 0); Some(Commit::> { end_time: 0, validators: vec![], signature: vec![] }) @@ -124,8 +94,7 @@ async fn invalid_precommit_signature() { }; // Empty Precommit should fail. - assert!(verify_tendermint_tx::(&precommit(None).await.1, genesis, validators.clone(), commit) - .is_err()); + assert!(verify_tendermint_tx::(&precommit(None).await.1, validators.clone(), commit).is_err()); // valid precommit signature should fail. let block_id = [0x22u8; 32]; @@ -136,7 +105,6 @@ async fn invalid_precommit_signature() { assert!(verify_tendermint_tx::( &precommit(Some((block_id, signer.clone().sign(&commit_msg).await))).await.1, - genesis, validators.clone(), commit ) @@ -145,20 +113,20 @@ async fn invalid_precommit_signature() { // any other signature can be used as evidence. { let (mut signed, tx) = precommit(Some((block_id, signer.sign(&[]).await))).await; - verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).unwrap(); + verify_tendermint_tx::(&tx, validators.clone(), commit).unwrap(); // So long as we can authenticate where it came from let mut random_sig = [0u8; 64]; OsRng.fill_bytes(&mut random_sig); signed.sig = random_sig; let tx = TendermintTx::SlashEvidence((signed.clone(), None::>).encode()); - assert!(verify_tendermint_tx::(&tx, genesis, validators, commit).is_err()); + assert!(verify_tendermint_tx::(&tx, validators, commit).is_err()); } } #[tokio::test] async fn evidence_with_prevote() { - let (genesis, signer, signer_id, validators) = tendermint_meta().await; + let (_, signer, signer_id, validators) = tendermint_meta().await; let commit = |_: u32| -> Option>> { Some(Commit::> { end_time: 0, validators: vec![], signature: vec![] }) }; @@ -179,7 +147,7 @@ async fn evidence_with_prevote() { // No prevote message should be valid as slash evidence at this time for prevote in [prevote(None).await, prevote(Some([0x22u8; 32])).await] { - assert!(verify_tendermint_tx::(&prevote, genesis, validators.clone(), commit).is_err()); + assert!(verify_tendermint_tx::(&prevote, validators.clone(), commit).is_err()); } } @@ -202,23 +170,23 @@ async fn conflicting_msgs_evidence_tx() { // non-conflicting data should fail let signed_1 = signed_for_b_r(0, 0, Data::Proposal(None, TendermintBlock(vec![0x11]))).await; let tx = TendermintTx::SlashEvidence((&signed_1, Some(&signed_1)).encode()); - assert!(verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).is_err()); + assert!(verify_tendermint_tx::(&tx, validators.clone(), commit).is_err()); // conflicting data should pass let signed_2 = signed_for_b_r(0, 0, Data::Proposal(None, TendermintBlock(vec![0x22]))).await; let tx = TendermintTx::SlashEvidence((&signed_1, Some(signed_2)).encode()); - verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).unwrap(); + verify_tendermint_tx::(&tx, validators.clone(), commit).unwrap(); // Except if it has a distinct round number, as we don't check cross-round conflicts // (except for Precommit) let signed_2 = signed_for_b_r(0, 1, Data::Proposal(None, TendermintBlock(vec![0x22]))).await; let tx = TendermintTx::SlashEvidence((&signed_1, Some(signed_2)).encode()); - verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).unwrap_err(); + verify_tendermint_tx::(&tx, validators.clone(), commit).unwrap_err(); // Proposals for different block numbers should also fail as evidence let signed_2 = signed_for_b_r(1, 0, Data::Proposal(None, TendermintBlock(vec![0x22]))).await; let tx = TendermintTx::SlashEvidence((&signed_1, Some(signed_2)).encode()); - verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).unwrap_err(); + verify_tendermint_tx::(&tx, validators.clone(), commit).unwrap_err(); } // Prevote @@ -226,23 +194,23 @@ async fn conflicting_msgs_evidence_tx() { // non-conflicting data should fail let signed_1 = signed_for_b_r(0, 0, Data::Prevote(Some([0x11; 32]))).await; let tx = TendermintTx::SlashEvidence((&signed_1, Some(&signed_1)).encode()); - assert!(verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).is_err()); + assert!(verify_tendermint_tx::(&tx, validators.clone(), commit).is_err()); // conflicting data should pass let signed_2 = signed_for_b_r(0, 0, Data::Prevote(Some([0x22; 32]))).await; let tx = TendermintTx::SlashEvidence((&signed_1, Some(signed_2)).encode()); - verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).unwrap(); + verify_tendermint_tx::(&tx, validators.clone(), commit).unwrap(); // Except if it has a distinct round number, as we don't check cross-round conflicts // (except for Precommit) let signed_2 = signed_for_b_r(0, 1, Data::Prevote(Some([0x22; 32]))).await; let tx = TendermintTx::SlashEvidence((&signed_1, Some(signed_2)).encode()); - verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).unwrap_err(); + verify_tendermint_tx::(&tx, validators.clone(), commit).unwrap_err(); // Proposals for different block numbers should also fail as evidence let signed_2 = signed_for_b_r(1, 0, Data::Prevote(Some([0x22; 32]))).await; let tx = TendermintTx::SlashEvidence((&signed_1, Some(signed_2)).encode()); - verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).unwrap_err(); + verify_tendermint_tx::(&tx, validators.clone(), commit).unwrap_err(); } // Precommit @@ -251,17 +219,17 @@ async fn conflicting_msgs_evidence_tx() { let signed_1 = signed_for_b_r(0, 0, Data::Precommit(Some(([0x11; 32], sig)))).await; let tx = TendermintTx::SlashEvidence((&signed_1, Some(&signed_1)).encode()); - assert!(verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).is_err()); + assert!(verify_tendermint_tx::(&tx, validators.clone(), commit).is_err()); // For precommit, the round number is ignored let signed_2 = signed_for_b_r(0, 1, Data::Precommit(Some(([0x22; 32], sig)))).await; let tx = TendermintTx::SlashEvidence((&signed_1, Some(signed_2)).encode()); - verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).unwrap(); + verify_tendermint_tx::(&tx, validators.clone(), commit).unwrap(); // Yet the block number isn't let signed_2 = signed_for_b_r(1, 0, Data::Precommit(Some(([0x22; 32], sig)))).await; let tx = TendermintTx::SlashEvidence((&signed_1, Some(signed_2)).encode()); - assert!(verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).is_err()); + assert!(verify_tendermint_tx::(&tx, validators.clone(), commit).is_err()); } // msgs from different senders should fail @@ -290,7 +258,7 @@ async fn conflicting_msgs_evidence_tx() { let validators = Arc::new(Validators::new(genesis, vec![(signer_pub, 1), (signer_pub_2, 1)]).unwrap()); - assert!(verify_tendermint_tx::(&tx, genesis, validators, commit).is_err()); + assert!(verify_tendermint_tx::(&tx, validators, commit).is_err()); } // msgs with different steps should fail @@ -298,6 +266,6 @@ async fn conflicting_msgs_evidence_tx() { let signed_1 = signed_for_b_r(0, 0, Data::Proposal(None, TendermintBlock(vec![]))).await; let signed_2 = signed_for_b_r(0, 0, Data::Prevote(None)).await; let tx = TendermintTx::SlashEvidence((signed_1, Some(signed_2)).encode()); - assert!(verify_tendermint_tx::(&tx, genesis, validators.clone(), commit).is_err()); + assert!(verify_tendermint_tx::(&tx, validators.clone(), commit).is_err()); } }