mirror of
https://github.com/serai-dex/serai.git
synced 2025-12-08 12:19:24 +00:00
Further expand clippy workspace lints
Achieves a notable amount of reduced async and clones.
This commit is contained in:
@@ -174,7 +174,7 @@ impl<T: TransactionTrait> Block<T> {
|
||||
last_block: [u8; 32],
|
||||
mut locally_provided: HashMap<&'static str, VecDeque<T>>,
|
||||
get_and_increment_nonce: &mut G,
|
||||
schema: N::SignatureScheme,
|
||||
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?
|
||||
@@ -217,7 +217,7 @@ impl<T: TransactionTrait> Block<T> {
|
||||
Err(BlockError::ProvidedAlreadyIncluded)?;
|
||||
}
|
||||
|
||||
if let Some(local) = locally_provided.get_mut(order).and_then(|deque| deque.pop_front()) {
|
||||
if let Some(local) = locally_provided.get_mut(order).and_then(VecDeque::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()))?
|
||||
@@ -250,12 +250,10 @@ impl<T: TransactionTrait> Block<T> {
|
||||
last_tx_order = current_tx_order;
|
||||
|
||||
match tx {
|
||||
Transaction::Tendermint(tx) => {
|
||||
match verify_tendermint_tx::<N>(tx, schema.clone(), &commit) {
|
||||
Ok(()) => {}
|
||||
Err(e) => Err(BlockError::TransactionError(e))?,
|
||||
}
|
||||
}
|
||||
Transaction::Tendermint(tx) => match verify_tendermint_tx::<N>(tx, schema, &commit) {
|
||||
Ok(()) => {}
|
||||
Err(e) => Err(BlockError::TransactionError(e))?,
|
||||
},
|
||||
Transaction::Application(tx) => {
|
||||
match verify_transaction(tx, genesis, get_and_increment_nonce) {
|
||||
Ok(()) => {}
|
||||
|
||||
@@ -139,25 +139,23 @@ impl<D: Db, T: TransactionTrait> Blockchain<D, T> {
|
||||
order: &str,
|
||||
) -> bool {
|
||||
let local_key = ProvidedTransactions::<D, T>::locally_provided_quantity_key(genesis, order);
|
||||
let local =
|
||||
db.get(local_key).map(|bytes| u32::from_le_bytes(bytes.try_into().unwrap())).unwrap_or(0);
|
||||
let local = db.get(local_key).map_or(0, |bytes| u32::from_le_bytes(bytes.try_into().unwrap()));
|
||||
let block_key =
|
||||
ProvidedTransactions::<D, T>::block_provided_quantity_key(genesis, block, order);
|
||||
let block =
|
||||
db.get(block_key).map(|bytes| u32::from_le_bytes(bytes.try_into().unwrap())).unwrap_or(0);
|
||||
let block = db.get(block_key).map_or(0, |bytes| u32::from_le_bytes(bytes.try_into().unwrap()));
|
||||
|
||||
local >= block
|
||||
}
|
||||
|
||||
pub(crate) fn tip_from_db(db: &D, genesis: [u8; 32]) -> [u8; 32] {
|
||||
db.get(Self::tip_key(genesis)).map(|bytes| bytes.try_into().unwrap()).unwrap_or(genesis)
|
||||
db.get(Self::tip_key(genesis)).map_or(genesis, |bytes| bytes.try_into().unwrap())
|
||||
}
|
||||
|
||||
pub(crate) fn add_transaction<N: Network>(
|
||||
&mut self,
|
||||
internal: bool,
|
||||
tx: Transaction<T>,
|
||||
schema: N::SignatureScheme,
|
||||
schema: &N::SignatureScheme,
|
||||
) -> Result<bool, TransactionError> {
|
||||
let db = self.db.as_ref().unwrap();
|
||||
let genesis = self.genesis;
|
||||
@@ -177,8 +175,7 @@ impl<D: Db, T: TransactionTrait> Blockchain<D, T> {
|
||||
if self.participants.contains(&signer) {
|
||||
Some(
|
||||
db.get(Self::next_nonce_key(&self.genesis, &signer, &order))
|
||||
.map(|bytes| u32::from_le_bytes(bytes.try_into().unwrap()))
|
||||
.unwrap_or(0),
|
||||
.map_or(0, |bytes| u32::from_le_bytes(bytes.try_into().unwrap())),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
@@ -211,15 +208,14 @@ impl<D: Db, T: TransactionTrait> Blockchain<D, T> {
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.get(Self::next_nonce_key(&self.genesis, signer, order))
|
||||
.map(|bytes| u32::from_le_bytes(bytes.try_into().unwrap()))
|
||||
.unwrap_or(0),
|
||||
.map_or(0, |bytes| u32::from_le_bytes(bytes.try_into().unwrap())),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn build_block<N: Network>(&mut self, schema: N::SignatureScheme) -> Block<T> {
|
||||
pub(crate) fn build_block<N: Network>(&mut self, schema: &N::SignatureScheme) -> Block<T> {
|
||||
let block = Block::new(
|
||||
self.tip,
|
||||
self.provided.transactions.values().flatten().cloned().collect(),
|
||||
@@ -233,7 +229,7 @@ impl<D: Db, T: TransactionTrait> Blockchain<D, T> {
|
||||
pub(crate) fn verify_block<N: Network>(
|
||||
&self,
|
||||
block: &Block<T>,
|
||||
schema: N::SignatureScheme,
|
||||
schema: &N::SignatureScheme,
|
||||
allow_non_local_provided: bool,
|
||||
) -> Result<(), BlockError> {
|
||||
let db = self.db.as_ref().unwrap();
|
||||
@@ -258,8 +254,7 @@ impl<D: Db, T: TransactionTrait> Blockchain<D, T> {
|
||||
let key = Self::next_nonce_key(&self.genesis, signer, order);
|
||||
let next = txn
|
||||
.get(&key)
|
||||
.map(|next_nonce| u32::from_le_bytes(next_nonce.try_into().unwrap()))
|
||||
.unwrap_or(0);
|
||||
.map_or(0, |next_nonce| u32::from_le_bytes(next_nonce.try_into().unwrap()));
|
||||
txn.put(key, (next + 1).to_le_bytes());
|
||||
Some(next)
|
||||
} else {
|
||||
@@ -282,7 +277,7 @@ impl<D: Db, T: TransactionTrait> Blockchain<D, T> {
|
||||
&mut self,
|
||||
block: &Block<T>,
|
||||
commit: Vec<u8>,
|
||||
schema: N::SignatureScheme,
|
||||
schema: &N::SignatureScheme,
|
||||
) -> Result<(), BlockError> {
|
||||
self.verify_block::<N>(block, schema, true)?;
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ impl<D: Db, T: TransactionTrait, P: P2p> Tributary<D, T, P> {
|
||||
start_time
|
||||
};
|
||||
let proposal = TendermintBlock(
|
||||
blockchain.build_block::<TendermintNetwork<D, T, P>>(validators.clone()).serialize(),
|
||||
blockchain.build_block::<TendermintNetwork<D, T, P>>(&validators).serialize(),
|
||||
);
|
||||
let blockchain = Arc::new(RwLock::new(blockchain));
|
||||
|
||||
@@ -273,7 +273,7 @@ impl<D: Db, T: TransactionTrait, P: P2p> Tributary<D, T, P> {
|
||||
let res = self.network.blockchain.write().await.add_transaction::<TendermintNetwork<D, T, P>>(
|
||||
true,
|
||||
tx,
|
||||
self.network.signature_scheme(),
|
||||
&self.network.signature_scheme(),
|
||||
);
|
||||
if res == Ok(true) {
|
||||
self.network.p2p.broadcast(self.genesis, to_broadcast).await;
|
||||
@@ -344,7 +344,7 @@ impl<D: Db, T: TransactionTrait, P: P2p> Tributary<D, T, P> {
|
||||
self.network.blockchain.write().await.add_transaction::<TendermintNetwork<D, T, P>>(
|
||||
false,
|
||||
tx,
|
||||
self.network.signature_scheme(),
|
||||
&self.network.signature_scheme(),
|
||||
);
|
||||
log::debug!("received transaction message. valid new transaction: {res:?}");
|
||||
res == Ok(true)
|
||||
|
||||
@@ -112,7 +112,7 @@ impl<D: Db, T: TransactionTrait> Mempool<D, T> {
|
||||
blockchain_next_nonce: F,
|
||||
internal: bool,
|
||||
tx: Transaction<T>,
|
||||
schema: N::SignatureScheme,
|
||||
schema: &N::SignatureScheme,
|
||||
unsigned_in_chain: impl Fn([u8; 32]) -> bool,
|
||||
commit: impl Fn(u32) -> Option<Commit<N::SignatureScheme>>,
|
||||
) -> Result<bool, TransactionError> {
|
||||
|
||||
@@ -17,13 +17,7 @@ pub(crate) fn merkle(hash_args: &[[u8; 32]]) -> [u8; 32] {
|
||||
[
|
||||
b"branch_hash".as_ref(),
|
||||
hashes[i].as_ref(),
|
||||
hashes
|
||||
.get(i + 1)
|
||||
.map(|hash| {
|
||||
let res: &[u8] = hash.as_ref();
|
||||
res
|
||||
})
|
||||
.unwrap_or(zero.as_ref()),
|
||||
hashes.get(i + 1).map_or(zero.as_ref(), AsRef::as_ref),
|
||||
]
|
||||
.concat(),
|
||||
));
|
||||
@@ -33,5 +27,5 @@ pub(crate) fn merkle(hash_args: &[[u8; 32]]) -> [u8; 32] {
|
||||
hashes = interim;
|
||||
}
|
||||
|
||||
hashes.first().copied().map(Into::into).unwrap_or(zero)
|
||||
hashes.first().copied().map_or(zero, Into::into)
|
||||
}
|
||||
|
||||
@@ -103,17 +103,11 @@ impl<D: Db, T: Transaction> ProvidedTransactions<D, T> {
|
||||
|
||||
// get local and on-chain tx numbers
|
||||
let local_key = Self::locally_provided_quantity_key(&self.genesis, order);
|
||||
let mut local_quantity = self
|
||||
.db
|
||||
.get(&local_key)
|
||||
.map(|bytes| u32::from_le_bytes(bytes.try_into().unwrap()))
|
||||
.unwrap_or(0);
|
||||
let mut local_quantity =
|
||||
self.db.get(&local_key).map_or(0, |bytes| u32::from_le_bytes(bytes.try_into().unwrap()));
|
||||
let on_chain_key = Self::on_chain_provided_quantity_key(&self.genesis, order);
|
||||
let on_chain_quantity = self
|
||||
.db
|
||||
.get(on_chain_key)
|
||||
.map(|bytes| u32::from_le_bytes(bytes.try_into().unwrap()))
|
||||
.unwrap_or(0);
|
||||
let on_chain_quantity =
|
||||
self.db.get(on_chain_key).map_or(0, |bytes| u32::from_le_bytes(bytes.try_into().unwrap()));
|
||||
|
||||
let current_provided_key = self.current_provided_key();
|
||||
|
||||
@@ -158,7 +152,7 @@ impl<D: Db, T: Transaction> ProvidedTransactions<D, T> {
|
||||
block: [u8; 32],
|
||||
tx: [u8; 32],
|
||||
) {
|
||||
if let Some(next_tx) = self.transactions.get_mut(order).and_then(|queue| queue.pop_front()) {
|
||||
if let Some(next_tx) = self.transactions.get_mut(order).and_then(VecDeque::pop_front) {
|
||||
assert_eq!(next_tx.hash(), tx);
|
||||
|
||||
let current_provided_key = self.current_provided_key();
|
||||
@@ -184,11 +178,8 @@ impl<D: Db, T: Transaction> ProvidedTransactions<D, T> {
|
||||
// bump the on-chain tx number.
|
||||
let on_chain_key = Self::on_chain_provided_quantity_key(&self.genesis, order);
|
||||
let block_order_key = Self::block_provided_quantity_key(&self.genesis, &block, order);
|
||||
let mut on_chain_quantity = self
|
||||
.db
|
||||
.get(&on_chain_key)
|
||||
.map(|bytes| u32::from_le_bytes(bytes.try_into().unwrap()))
|
||||
.unwrap_or(0);
|
||||
let mut on_chain_quantity =
|
||||
self.db.get(&on_chain_key).map_or(0, |bytes| u32::from_le_bytes(bytes.try_into().unwrap()));
|
||||
|
||||
let this_provided_id = on_chain_quantity;
|
||||
txn.put(Self::on_chain_provided_key(&self.genesis, order, this_provided_id), tx);
|
||||
|
||||
@@ -348,7 +348,7 @@ impl<D: Db, T: TransactionTrait, P: P2p> Network for TendermintNetwork<D, T, P>
|
||||
if self.blockchain.write().await.add_transaction::<Self>(
|
||||
true,
|
||||
Transaction::Tendermint(tx),
|
||||
self.signature_scheme(),
|
||||
&self.signature_scheme(),
|
||||
) == Ok(true)
|
||||
{
|
||||
self.p2p.broadcast(signer.genesis, to_broadcast).await;
|
||||
@@ -362,7 +362,7 @@ impl<D: Db, T: TransactionTrait, P: P2p> Network for TendermintNetwork<D, T, P>
|
||||
.blockchain
|
||||
.read()
|
||||
.await
|
||||
.verify_block::<Self>(&block, self.signature_scheme(), false)
|
||||
.verify_block::<Self>(&block, &self.signature_scheme(), false)
|
||||
.map_err(|e| match e {
|
||||
BlockError::NonLocalProvided(_) => TendermintBlockError::Temporal,
|
||||
_ => {
|
||||
@@ -398,7 +398,7 @@ impl<D: Db, T: TransactionTrait, P: P2p> Network for TendermintNetwork<D, T, P>
|
||||
let block_res = self.blockchain.write().await.add_block::<Self>(
|
||||
&block,
|
||||
encoded_commit.clone(),
|
||||
self.signature_scheme(),
|
||||
&self.signature_scheme(),
|
||||
);
|
||||
match block_res {
|
||||
Ok(()) => {
|
||||
@@ -425,7 +425,7 @@ impl<D: Db, T: TransactionTrait, P: P2p> Network for TendermintNetwork<D, T, P>
|
||||
*self.to_rebroadcast.write().await = vec![];
|
||||
|
||||
Some(TendermintBlock(
|
||||
self.blockchain.write().await.build_block::<Self>(self.signature_scheme()).serialize(),
|
||||
self.blockchain.write().await.build_block::<Self>(&self.signature_scheme()).serialize(),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ fn decode_and_verify_signed_message<N: Network>(
|
||||
// re-implements an entire foreign library's checks for malicious behavior).
|
||||
pub(crate) fn verify_tendermint_tx<N: Network>(
|
||||
tx: &TendermintTx,
|
||||
schema: N::SignatureScheme,
|
||||
schema: &N::SignatureScheme,
|
||||
commit: impl Fn(u32) -> Option<Commit<N::SignatureScheme>>,
|
||||
) -> Result<(), TransactionError> {
|
||||
tx.verify()?;
|
||||
@@ -98,8 +98,8 @@ pub(crate) fn verify_tendermint_tx<N: Network>(
|
||||
TendermintTx::SlashEvidence(ev) => {
|
||||
match ev {
|
||||
Evidence::ConflictingMessages(first, second) => {
|
||||
let first = decode_and_verify_signed_message::<N>(first, &schema)?.msg;
|
||||
let second = decode_and_verify_signed_message::<N>(second, &schema)?.msg;
|
||||
let first = decode_and_verify_signed_message::<N>(first, schema)?.msg;
|
||||
let second = decode_and_verify_signed_message::<N>(second, schema)?.msg;
|
||||
|
||||
// Make sure they're distinct messages, from the same sender, within the same block
|
||||
if (first == second) || (first.sender != second.sender) || (first.block != second.block) {
|
||||
@@ -112,8 +112,8 @@ pub(crate) fn verify_tendermint_tx<N: Network>(
|
||||
}
|
||||
}
|
||||
Evidence::ConflictingPrecommit(first, second) => {
|
||||
let first = decode_and_verify_signed_message::<N>(first, &schema)?.msg;
|
||||
let second = decode_and_verify_signed_message::<N>(second, &schema)?.msg;
|
||||
let first = decode_and_verify_signed_message::<N>(first, schema)?.msg;
|
||||
let second = decode_and_verify_signed_message::<N>(second, schema)?.msg;
|
||||
|
||||
if (first.sender != second.sender) || (first.block != second.block) {
|
||||
Err(TransactionError::InvalidContent)?;
|
||||
@@ -136,7 +136,7 @@ pub(crate) fn verify_tendermint_tx<N: Network>(
|
||||
Err(TransactionError::InvalidContent)?
|
||||
}
|
||||
Evidence::InvalidPrecommit(msg) => {
|
||||
let msg = decode_and_verify_signed_message::<N>(msg, &schema)?.msg;
|
||||
let msg = decode_and_verify_signed_message::<N>(msg, schema)?.msg;
|
||||
|
||||
let Data::Precommit(Some((id, sig))) = &msg.data else {
|
||||
Err(TransactionError::InvalidContent)?
|
||||
@@ -173,7 +173,7 @@ pub(crate) fn verify_tendermint_tx<N: Network>(
|
||||
}
|
||||
}
|
||||
Evidence::InvalidValidRound(msg) => {
|
||||
let msg = decode_and_verify_signed_message::<N>(msg, &schema)?.msg;
|
||||
let msg = decode_and_verify_signed_message::<N>(msg, schema)?.msg;
|
||||
|
||||
let Data::Proposal(Some(vr), _) = &msg.data else {
|
||||
Err(TransactionError::InvalidContent)?
|
||||
|
||||
@@ -89,7 +89,7 @@ fn empty_block() {
|
||||
LAST,
|
||||
HashMap::new(),
|
||||
&mut |_, _| None,
|
||||
validators,
|
||||
&validators,
|
||||
commit,
|
||||
unsigned_in_chain,
|
||||
provided_in_chain,
|
||||
@@ -129,7 +129,7 @@ fn duplicate_nonces() {
|
||||
last_nonce += 1;
|
||||
Some(res)
|
||||
},
|
||||
validators.clone(),
|
||||
&validators,
|
||||
commit,
|
||||
unsigned_in_chain,
|
||||
provided_in_chain,
|
||||
|
||||
@@ -44,12 +44,12 @@ fn block_addition() {
|
||||
let genesis = new_genesis();
|
||||
let validators = Arc::new(Validators::new(genesis, vec![]).unwrap());
|
||||
let (db, mut blockchain) = new_blockchain::<SignedTransaction>(genesis, &[]);
|
||||
let block = blockchain.build_block::<N>(validators.clone());
|
||||
let block = blockchain.build_block::<N>(&validators);
|
||||
|
||||
assert_eq!(block.header.parent, genesis);
|
||||
assert_eq!(block.header.transactions, [0; 32]);
|
||||
blockchain.verify_block::<N>(&block, validators.clone(), false).unwrap();
|
||||
assert!(blockchain.add_block::<N>(&block, vec![], validators).is_ok());
|
||||
blockchain.verify_block::<N>(&block, &validators, false).unwrap();
|
||||
assert!(blockchain.add_block::<N>(&block, vec![], &validators).is_ok());
|
||||
assert_eq!(blockchain.tip(), block.hash());
|
||||
assert_eq!(blockchain.block_number(), 1);
|
||||
assert_eq!(
|
||||
@@ -64,21 +64,21 @@ fn invalid_block() {
|
||||
let validators = Arc::new(Validators::new(genesis, vec![]).unwrap());
|
||||
let (_, mut blockchain) = new_blockchain::<SignedTransaction>(genesis, &[]);
|
||||
|
||||
let block = blockchain.build_block::<N>(validators.clone());
|
||||
let block = blockchain.build_block::<N>(&validators);
|
||||
|
||||
// Mutate parent
|
||||
{
|
||||
#[allow(clippy::redundant_clone)] // False positive
|
||||
let mut block = block.clone();
|
||||
block.header.parent = Blake2s256::digest(block.header.parent).into();
|
||||
assert!(blockchain.verify_block::<N>(&block, validators.clone(), false).is_err());
|
||||
assert!(blockchain.verify_block::<N>(&block, &validators, false).is_err());
|
||||
}
|
||||
|
||||
// Mutate tranactions merkle
|
||||
{
|
||||
let mut block = block;
|
||||
block.header.transactions = Blake2s256::digest(block.header.transactions).into();
|
||||
assert!(blockchain.verify_block::<N>(&block, validators.clone(), false).is_err());
|
||||
assert!(blockchain.verify_block::<N>(&block, &validators, false).is_err());
|
||||
}
|
||||
|
||||
let key = Zeroizing::new(<Ristretto as Ciphersuite>::F::random(&mut OsRng));
|
||||
@@ -89,7 +89,7 @@ fn invalid_block() {
|
||||
// Manually create the block to bypass build_block's checks
|
||||
let block = Block::new(blockchain.tip(), vec![], vec![Transaction::Application(tx.clone())]);
|
||||
assert_eq!(block.header.transactions, merkle(&[tx.hash()]));
|
||||
assert!(blockchain.verify_block::<N>(&block, validators.clone(), false).is_err());
|
||||
assert!(blockchain.verify_block::<N>(&block, &validators, false).is_err());
|
||||
}
|
||||
|
||||
// Run the rest of the tests with them as a participant
|
||||
@@ -99,22 +99,22 @@ fn invalid_block() {
|
||||
{
|
||||
let block = Block::new(blockchain.tip(), vec![], vec![Transaction::Application(tx.clone())]);
|
||||
assert_eq!(block.header.transactions, merkle(&[tx.hash()]));
|
||||
blockchain.verify_block::<N>(&block, validators.clone(), false).unwrap();
|
||||
blockchain.verify_block::<N>(&block, &validators, false).unwrap();
|
||||
}
|
||||
|
||||
{
|
||||
// Add a valid transaction
|
||||
let (_, mut blockchain) = new_blockchain(genesis, &[tx.1.signer]);
|
||||
blockchain
|
||||
.add_transaction::<N>(true, Transaction::Application(tx.clone()), validators.clone())
|
||||
.add_transaction::<N>(true, Transaction::Application(tx.clone()), &validators)
|
||||
.unwrap();
|
||||
let mut block = blockchain.build_block::<N>(validators.clone());
|
||||
let mut block = blockchain.build_block::<N>(&validators);
|
||||
assert_eq!(block.header.transactions, merkle(&[tx.hash()]));
|
||||
blockchain.verify_block::<N>(&block, validators.clone(), false).unwrap();
|
||||
blockchain.verify_block::<N>(&block, &validators, false).unwrap();
|
||||
|
||||
// And verify mutating the transactions merkle now causes a failure
|
||||
block.header.transactions = merkle(&[]);
|
||||
assert!(blockchain.verify_block::<N>(&block, validators.clone(), false).is_err());
|
||||
assert!(blockchain.verify_block::<N>(&block, &validators, false).is_err());
|
||||
}
|
||||
|
||||
{
|
||||
@@ -122,24 +122,22 @@ fn invalid_block() {
|
||||
let tx = crate::tests::signed_transaction(&mut OsRng, genesis, &key, 5);
|
||||
// Manually create the block to bypass build_block's checks
|
||||
let block = Block::new(blockchain.tip(), vec![], vec![Transaction::Application(tx)]);
|
||||
assert!(blockchain.verify_block::<N>(&block, validators.clone(), false).is_err());
|
||||
assert!(blockchain.verify_block::<N>(&block, &validators, false).is_err());
|
||||
}
|
||||
|
||||
{
|
||||
// Invalid signature
|
||||
let (_, mut blockchain) = new_blockchain(genesis, &[tx.1.signer]);
|
||||
blockchain
|
||||
.add_transaction::<N>(true, Transaction::Application(tx), validators.clone())
|
||||
.unwrap();
|
||||
let mut block = blockchain.build_block::<N>(validators.clone());
|
||||
blockchain.verify_block::<N>(&block, validators.clone(), false).unwrap();
|
||||
blockchain.add_transaction::<N>(true, Transaction::Application(tx), &validators).unwrap();
|
||||
let mut block = blockchain.build_block::<N>(&validators);
|
||||
blockchain.verify_block::<N>(&block, &validators, false).unwrap();
|
||||
match &mut block.transactions[0] {
|
||||
Transaction::Application(tx) => {
|
||||
tx.1.signature.s += <Ristretto as Ciphersuite>::F::ONE;
|
||||
}
|
||||
_ => panic!("non-signed tx found"),
|
||||
}
|
||||
assert!(blockchain.verify_block::<N>(&block, validators.clone(), false).is_err());
|
||||
assert!(blockchain.verify_block::<N>(&block, &validators, false).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)
|
||||
@@ -166,12 +164,10 @@ fn signed_transaction() {
|
||||
panic!("tendermint tx found");
|
||||
};
|
||||
let next_nonce = blockchain.next_nonce(&signer, &[]).unwrap();
|
||||
blockchain
|
||||
.add_transaction::<N>(true, Transaction::Application(tx), validators.clone())
|
||||
.unwrap();
|
||||
blockchain.add_transaction::<N>(true, Transaction::Application(tx), &validators).unwrap();
|
||||
assert_eq!(next_nonce + 1, blockchain.next_nonce(&signer, &[]).unwrap());
|
||||
}
|
||||
let block = blockchain.build_block::<N>(validators.clone());
|
||||
let block = blockchain.build_block::<N>(&validators);
|
||||
assert_eq!(block, Block::new(blockchain.tip(), vec![], mempool.clone()));
|
||||
assert_eq!(blockchain.tip(), tip);
|
||||
assert_eq!(block.header.parent, tip);
|
||||
@@ -185,8 +181,8 @@ fn signed_transaction() {
|
||||
);
|
||||
|
||||
// Verify and add the block
|
||||
blockchain.verify_block::<N>(&block, validators.clone(), false).unwrap();
|
||||
assert!(blockchain.add_block::<N>(&block, vec![], validators.clone()).is_ok());
|
||||
blockchain.verify_block::<N>(&block, &validators, false).unwrap();
|
||||
assert!(blockchain.add_block::<N>(&block, vec![], &validators).is_ok());
|
||||
assert_eq!(blockchain.tip(), block.hash());
|
||||
};
|
||||
|
||||
@@ -233,21 +229,21 @@ fn provided_transaction() {
|
||||
{
|
||||
// Non-provided transactions should fail verification because we don't have them locally.
|
||||
let block = Block::new(blockchain.tip(), vec![tx.clone()], vec![]);
|
||||
assert!(blockchain.verify_block::<N>(&block, validators.clone(), false).is_err());
|
||||
assert!(blockchain.verify_block::<N>(&block, &validators, false).is_err());
|
||||
|
||||
// Provided transactions should pass verification
|
||||
blockchain.provide_transaction(tx.clone()).unwrap();
|
||||
blockchain.verify_block::<N>(&block, validators.clone(), false).unwrap();
|
||||
blockchain.verify_block::<N>(&block, &validators, false).unwrap();
|
||||
|
||||
// add_block should work for verified blocks
|
||||
assert!(blockchain.add_block::<N>(&block, vec![], validators.clone()).is_ok());
|
||||
assert!(blockchain.add_block::<N>(&block, vec![], &validators).is_ok());
|
||||
|
||||
let block = Block::new(blockchain.tip(), vec![tx.clone()], vec![]);
|
||||
|
||||
// The provided transaction should no longer considered provided but added to chain,
|
||||
// causing this error
|
||||
assert_eq!(
|
||||
blockchain.verify_block::<N>(&block, validators.clone(), false),
|
||||
blockchain.verify_block::<N>(&block, &validators, false),
|
||||
Err(BlockError::ProvidedAlreadyIncluded)
|
||||
);
|
||||
}
|
||||
@@ -262,11 +258,11 @@ fn provided_transaction() {
|
||||
// add_block DOES NOT fail for unverified provided transactions if told to add them,
|
||||
// since now we can have them later.
|
||||
let block1 = Block::new(blockchain.tip(), vec![tx1.clone(), tx3.clone()], vec![]);
|
||||
assert!(blockchain.add_block::<N>(&block1, vec![], validators.clone()).is_ok());
|
||||
assert!(blockchain.add_block::<N>(&block1, vec![], &validators).is_ok());
|
||||
|
||||
// in fact, we can have many blocks that have provided txs that we don't have locally.
|
||||
let block2 = Block::new(blockchain.tip(), vec![tx2.clone(), tx4.clone()], vec![]);
|
||||
assert!(blockchain.add_block::<N>(&block2, vec![], validators.clone()).is_ok());
|
||||
assert!(blockchain.add_block::<N>(&block2, vec![], &validators).is_ok());
|
||||
|
||||
// make sure we won't return ok for the block before we actually got the txs
|
||||
let TransactionKind::Provided(order) = tx1.kind() else { panic!("tx wasn't provided") };
|
||||
@@ -357,11 +353,9 @@ async fn tendermint_evidence_tx() {
|
||||
let Transaction::Tendermint(tx) = tx else {
|
||||
panic!("non-tendermint tx found");
|
||||
};
|
||||
blockchain
|
||||
.add_transaction::<N>(true, Transaction::Tendermint(tx), validators.clone())
|
||||
.unwrap();
|
||||
blockchain.add_transaction::<N>(true, Transaction::Tendermint(tx), &validators).unwrap();
|
||||
}
|
||||
let block = blockchain.build_block::<N>(validators.clone());
|
||||
let block = blockchain.build_block::<N>(&validators);
|
||||
assert_eq!(blockchain.tip(), tip);
|
||||
assert_eq!(block.header.parent, tip);
|
||||
|
||||
@@ -371,8 +365,8 @@ async fn tendermint_evidence_tx() {
|
||||
}
|
||||
|
||||
// Verify and add the block
|
||||
blockchain.verify_block::<N>(&block, validators.clone(), false).unwrap();
|
||||
assert!(blockchain.add_block::<N>(&block, vec![], validators.clone()).is_ok());
|
||||
blockchain.verify_block::<N>(&block, &validators, false).unwrap();
|
||||
assert!(blockchain.add_block::<N>(&block, vec![], &validators).is_ok());
|
||||
assert_eq!(blockchain.tip(), block.hash());
|
||||
};
|
||||
|
||||
@@ -467,7 +461,7 @@ async fn block_tx_ordering() {
|
||||
let signed_tx = Transaction::Application(SignedTx::Signed(Box::new(
|
||||
crate::tests::signed_transaction(&mut OsRng, genesis, &key, i),
|
||||
)));
|
||||
blockchain.add_transaction::<N>(true, signed_tx.clone(), validators.clone()).unwrap();
|
||||
blockchain.add_transaction::<N>(true, signed_tx.clone(), &validators).unwrap();
|
||||
mempool.push(signed_tx);
|
||||
|
||||
let unsigned_tx = Transaction::Tendermint(
|
||||
@@ -477,7 +471,7 @@ async fn block_tx_ordering() {
|
||||
)
|
||||
.await,
|
||||
);
|
||||
blockchain.add_transaction::<N>(true, unsigned_tx.clone(), validators.clone()).unwrap();
|
||||
blockchain.add_transaction::<N>(true, unsigned_tx.clone(), &validators).unwrap();
|
||||
mempool.push(unsigned_tx);
|
||||
|
||||
let provided_tx =
|
||||
@@ -485,7 +479,7 @@ async fn block_tx_ordering() {
|
||||
blockchain.provide_transaction(provided_tx.clone()).unwrap();
|
||||
provided_txs.push(provided_tx);
|
||||
}
|
||||
let block = blockchain.build_block::<N>(validators.clone());
|
||||
let block = blockchain.build_block::<N>(&validators);
|
||||
|
||||
assert_eq!(blockchain.tip(), tip);
|
||||
assert_eq!(block.header.parent, tip);
|
||||
@@ -509,7 +503,7 @@ async fn block_tx_ordering() {
|
||||
}
|
||||
|
||||
// should be a valid block
|
||||
blockchain.verify_block::<N>(&block, validators.clone(), false).unwrap();
|
||||
blockchain.verify_block::<N>(&block, &validators, false).unwrap();
|
||||
|
||||
// Unsigned before Provided
|
||||
{
|
||||
@@ -518,7 +512,7 @@ async fn block_tx_ordering() {
|
||||
let unsigned = block.transactions.remove(128);
|
||||
block.transactions.insert(0, unsigned);
|
||||
assert_eq!(
|
||||
blockchain.verify_block::<N>(&block, validators.clone(), false).unwrap_err(),
|
||||
blockchain.verify_block::<N>(&block, &validators, false).unwrap_err(),
|
||||
BlockError::WrongTransactionOrder
|
||||
);
|
||||
}
|
||||
@@ -529,7 +523,7 @@ async fn block_tx_ordering() {
|
||||
let signed = block.transactions.remove(256);
|
||||
block.transactions.insert(0, signed);
|
||||
assert_eq!(
|
||||
blockchain.verify_block::<N>(&block, validators.clone(), false).unwrap_err(),
|
||||
blockchain.verify_block::<N>(&block, &validators, false).unwrap_err(),
|
||||
BlockError::WrongTransactionOrder
|
||||
);
|
||||
}
|
||||
@@ -539,7 +533,7 @@ async fn block_tx_ordering() {
|
||||
let mut block = block;
|
||||
block.transactions.swap(128, 256);
|
||||
assert_eq!(
|
||||
blockchain.verify_block::<N>(&block, validators.clone(), false).unwrap_err(),
|
||||
blockchain.verify_block::<N>(&block, &validators, false).unwrap_err(),
|
||||
BlockError::WrongTransactionOrder
|
||||
);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ async fn mempool_addition() {
|
||||
&|_, _| Some(0),
|
||||
true,
|
||||
Transaction::Application(first_tx.clone()),
|
||||
validators.clone(),
|
||||
&validators,
|
||||
unsigned_in_chain,
|
||||
commit,
|
||||
)
|
||||
@@ -63,7 +63,7 @@ async fn mempool_addition() {
|
||||
&|_, _| None,
|
||||
true,
|
||||
Transaction::Tendermint(evidence_tx.clone()),
|
||||
validators.clone(),
|
||||
&validators,
|
||||
unsigned_in_chain,
|
||||
commit,
|
||||
)
|
||||
@@ -78,7 +78,7 @@ async fn mempool_addition() {
|
||||
&|_, _| Some(0),
|
||||
true,
|
||||
Transaction::Application(first_tx.clone()),
|
||||
validators.clone(),
|
||||
&validators,
|
||||
unsigned_in_chain,
|
||||
commit,
|
||||
),
|
||||
@@ -89,7 +89,7 @@ async fn mempool_addition() {
|
||||
&|_, _| None,
|
||||
true,
|
||||
Transaction::Tendermint(evidence_tx.clone()),
|
||||
validators.clone(),
|
||||
&validators,
|
||||
unsigned_in_chain,
|
||||
commit,
|
||||
),
|
||||
@@ -103,7 +103,7 @@ async fn mempool_addition() {
|
||||
&|_, _| Some(0),
|
||||
true,
|
||||
Transaction::Application(second_tx.clone()),
|
||||
validators.clone(),
|
||||
&validators,
|
||||
unsigned_in_chain,
|
||||
commit,
|
||||
),
|
||||
@@ -115,7 +115,7 @@ async fn mempool_addition() {
|
||||
&|_, _| Some(0),
|
||||
true,
|
||||
Transaction::Application(second_tx.clone()),
|
||||
validators.clone(),
|
||||
&validators,
|
||||
unsigned_in_chain,
|
||||
commit,
|
||||
),
|
||||
@@ -133,7 +133,7 @@ async fn mempool_addition() {
|
||||
&|_, _| Some(2),
|
||||
true,
|
||||
Transaction::Application(tx.clone()),
|
||||
validators.clone(),
|
||||
&validators,
|
||||
unsigned_in_chain,
|
||||
commit
|
||||
)
|
||||
@@ -173,7 +173,7 @@ fn too_many_mempool() {
|
||||
&|_, _| Some(0),
|
||||
false,
|
||||
Transaction::Application(signed_transaction(&mut OsRng, genesis, &key, i)),
|
||||
validators.clone(),
|
||||
&validators,
|
||||
unsigned_in_chain,
|
||||
commit,
|
||||
)
|
||||
@@ -190,7 +190,7 @@ fn too_many_mempool() {
|
||||
&key,
|
||||
ACCOUNT_MEMPOOL_LIMIT
|
||||
)),
|
||||
validators.clone(),
|
||||
&validators,
|
||||
unsigned_in_chain,
|
||||
commit,
|
||||
),
|
||||
|
||||
@@ -57,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::<N>(&tx, validators.clone(), commit).is_err());
|
||||
assert!(verify_tendermint_tx::<N>(&tx, &validators, 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::<N>(&tx, validators.clone(), commit).unwrap();
|
||||
verify_tendermint_tx::<N>(&tx, &validators, commit).unwrap();
|
||||
|
||||
// change the signature
|
||||
let mut random_sig = [0u8; 64];
|
||||
@@ -72,7 +72,7 @@ async fn invalid_valid_round() {
|
||||
let tx = TendermintTx::SlashEvidence(Evidence::InvalidValidRound(signed.encode()));
|
||||
|
||||
// should fail
|
||||
assert!(verify_tendermint_tx::<N>(&tx, validators, commit).is_err());
|
||||
assert!(verify_tendermint_tx::<N>(&tx, &validators, commit).is_err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@@ -94,7 +94,7 @@ async fn invalid_precommit_signature() {
|
||||
};
|
||||
|
||||
// Empty Precommit should fail.
|
||||
assert!(verify_tendermint_tx::<N>(&precommit(None).await.1, validators.clone(), commit).is_err());
|
||||
assert!(verify_tendermint_tx::<N>(&precommit(None).await.1, &validators, commit).is_err());
|
||||
|
||||
// valid precommit signature should fail.
|
||||
let block_id = [0x22u8; 32];
|
||||
@@ -105,7 +105,7 @@ async fn invalid_precommit_signature() {
|
||||
|
||||
assert!(verify_tendermint_tx::<N>(
|
||||
&precommit(Some((block_id, signer.clone().sign(&commit_msg).await))).await.1,
|
||||
validators.clone(),
|
||||
&validators,
|
||||
commit
|
||||
)
|
||||
.is_err());
|
||||
@@ -113,14 +113,14 @@ 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::<N>(&tx, validators.clone(), commit).unwrap();
|
||||
verify_tendermint_tx::<N>(&tx, &validators, 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(Evidence::InvalidPrecommit(signed.encode()));
|
||||
assert!(verify_tendermint_tx::<N>(&tx, validators, commit).is_err());
|
||||
assert!(verify_tendermint_tx::<N>(&tx, &validators, commit).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,10 +170,10 @@ async fn evidence_with_prevote() {
|
||||
|
||||
// No prevote message alone should be valid as slash evidence at this time
|
||||
for prevote in prevote(None).await {
|
||||
assert!(verify_tendermint_tx::<N>(&prevote, validators.clone(), commit).is_err());
|
||||
assert!(verify_tendermint_tx::<N>(&prevote, &validators, commit).is_err());
|
||||
}
|
||||
for prevote in prevote(Some([0x22u8; 32])).await {
|
||||
assert!(verify_tendermint_tx::<N>(&prevote, validators.clone(), commit).is_err());
|
||||
assert!(verify_tendermint_tx::<N>(&prevote, &validators, commit).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ async fn conflicting_msgs_evidence_tx() {
|
||||
signed_1.encode(),
|
||||
signed_1.encode(),
|
||||
));
|
||||
assert!(verify_tendermint_tx::<N>(&tx, validators.clone(), commit).is_err());
|
||||
assert!(verify_tendermint_tx::<N>(&tx, &validators, commit).is_err());
|
||||
|
||||
// conflicting data should pass
|
||||
let signed_2 = signed_for_b_r(0, 0, Data::Proposal(None, TendermintBlock(vec![0x22]))).await;
|
||||
@@ -207,7 +207,7 @@ async fn conflicting_msgs_evidence_tx() {
|
||||
signed_1.encode(),
|
||||
signed_2.encode(),
|
||||
));
|
||||
verify_tendermint_tx::<N>(&tx, validators.clone(), commit).unwrap();
|
||||
verify_tendermint_tx::<N>(&tx, &validators, commit).unwrap();
|
||||
|
||||
// Except if it has a distinct round number, as we don't check cross-round conflicts
|
||||
// (except for Precommit)
|
||||
@@ -216,7 +216,7 @@ async fn conflicting_msgs_evidence_tx() {
|
||||
signed_1.encode(),
|
||||
signed_2.encode(),
|
||||
));
|
||||
verify_tendermint_tx::<N>(&tx, validators.clone(), commit).unwrap_err();
|
||||
verify_tendermint_tx::<N>(&tx, &validators, 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;
|
||||
@@ -224,7 +224,7 @@ async fn conflicting_msgs_evidence_tx() {
|
||||
signed_1.encode(),
|
||||
signed_2.encode(),
|
||||
));
|
||||
verify_tendermint_tx::<N>(&tx, validators.clone(), commit).unwrap_err();
|
||||
verify_tendermint_tx::<N>(&tx, &validators, commit).unwrap_err();
|
||||
}
|
||||
|
||||
// Prevote
|
||||
@@ -235,7 +235,7 @@ async fn conflicting_msgs_evidence_tx() {
|
||||
signed_1.encode(),
|
||||
signed_1.encode(),
|
||||
));
|
||||
assert!(verify_tendermint_tx::<N>(&tx, validators.clone(), commit).is_err());
|
||||
assert!(verify_tendermint_tx::<N>(&tx, &validators, commit).is_err());
|
||||
|
||||
// conflicting data should pass
|
||||
let signed_2 = signed_for_b_r(0, 0, Data::Prevote(Some([0x22; 32]))).await;
|
||||
@@ -243,7 +243,7 @@ async fn conflicting_msgs_evidence_tx() {
|
||||
signed_1.encode(),
|
||||
signed_2.encode(),
|
||||
));
|
||||
verify_tendermint_tx::<N>(&tx, validators.clone(), commit).unwrap();
|
||||
verify_tendermint_tx::<N>(&tx, &validators, commit).unwrap();
|
||||
|
||||
// Except if it has a distinct round number, as we don't check cross-round conflicts
|
||||
// (except for Precommit)
|
||||
@@ -252,7 +252,7 @@ async fn conflicting_msgs_evidence_tx() {
|
||||
signed_1.encode(),
|
||||
signed_2.encode(),
|
||||
));
|
||||
verify_tendermint_tx::<N>(&tx, validators.clone(), commit).unwrap_err();
|
||||
verify_tendermint_tx::<N>(&tx, &validators, 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;
|
||||
@@ -260,7 +260,7 @@ async fn conflicting_msgs_evidence_tx() {
|
||||
signed_1.encode(),
|
||||
signed_2.encode(),
|
||||
));
|
||||
verify_tendermint_tx::<N>(&tx, validators.clone(), commit).unwrap_err();
|
||||
verify_tendermint_tx::<N>(&tx, &validators, commit).unwrap_err();
|
||||
}
|
||||
|
||||
// Precommit
|
||||
@@ -272,7 +272,7 @@ async fn conflicting_msgs_evidence_tx() {
|
||||
signed_1.encode(),
|
||||
signed_1.encode(),
|
||||
));
|
||||
assert!(verify_tendermint_tx::<N>(&tx, validators.clone(), commit).is_err());
|
||||
assert!(verify_tendermint_tx::<N>(&tx, &validators, 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;
|
||||
@@ -280,7 +280,7 @@ async fn conflicting_msgs_evidence_tx() {
|
||||
signed_1.encode(),
|
||||
signed_2.encode(),
|
||||
));
|
||||
verify_tendermint_tx::<N>(&tx, validators.clone(), commit).unwrap();
|
||||
verify_tendermint_tx::<N>(&tx, &validators, commit).unwrap();
|
||||
|
||||
// Yet the block number isn't
|
||||
let signed_2 = signed_for_b_r(1, 0, Data::Precommit(Some(([0x22; 32], sig)))).await;
|
||||
@@ -288,7 +288,7 @@ async fn conflicting_msgs_evidence_tx() {
|
||||
signed_1.encode(),
|
||||
signed_2.encode(),
|
||||
));
|
||||
assert!(verify_tendermint_tx::<N>(&tx, validators.clone(), commit).is_err());
|
||||
assert!(verify_tendermint_tx::<N>(&tx, &validators, commit).is_err());
|
||||
}
|
||||
|
||||
// msgs from different senders should fail
|
||||
@@ -320,7 +320,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::<N>(&tx, validators, commit).is_err());
|
||||
assert!(verify_tendermint_tx::<N>(&tx, &validators, commit).is_err());
|
||||
}
|
||||
|
||||
// msgs with different steps should fail
|
||||
@@ -331,6 +331,6 @@ async fn conflicting_msgs_evidence_tx() {
|
||||
signed_1.encode(),
|
||||
signed_2.encode(),
|
||||
));
|
||||
assert!(verify_tendermint_tx::<N>(&tx, validators.clone(), commit).is_err());
|
||||
assert!(verify_tendermint_tx::<N>(&tx, &validators, commit).is_err());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,8 +191,7 @@ pub(crate) fn verify_transaction<F: GAIN, T: Transaction>(
|
||||
tx.verify()?;
|
||||
|
||||
match tx.kind() {
|
||||
TransactionKind::Provided(_) => {}
|
||||
TransactionKind::Unsigned => {}
|
||||
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 {
|
||||
|
||||
@@ -543,8 +543,7 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
||||
|
||||
self.slash(sender, slash).await
|
||||
}
|
||||
Err(TendermintError::Temporal) => (),
|
||||
Err(TendermintError::AlreadyHandled) => (),
|
||||
Err(TendermintError::Temporal | TendermintError::AlreadyHandled) => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -627,7 +626,7 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
||||
// Uses a junk signature since message equality disregards the signature
|
||||
if self.block.log.has_consensus(
|
||||
msg.round,
|
||||
Data::Precommit(Some((block.id(), self.signer.sign(&[]).await))),
|
||||
&Data::Precommit(Some((block.id(), self.signer.sign(&[]).await))),
|
||||
) {
|
||||
// If msg.round is in the future, these Precommits won't have their inner signatures
|
||||
// verified
|
||||
@@ -714,7 +713,7 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
||||
// of the round map
|
||||
if (self.block.round().step == Step::Prevote) && matches!(msg.data, Data::Prevote(_)) {
|
||||
let (participation, weight) =
|
||||
self.block.log.message_instances(self.block.round().number, Data::Prevote(None));
|
||||
self.block.log.message_instances(self.block.round().number, &Data::Prevote(None));
|
||||
// 34-35
|
||||
if participation >= self.weights.threshold() {
|
||||
self.block.round_mut().set_timeout(Step::Prevote);
|
||||
@@ -767,7 +766,7 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
||||
// 23 and 29. If it's some, both are satisfied if they're for the same ID. If it's some
|
||||
// with different IDs, the function on 22 rejects yet the function on 28 has one other
|
||||
// condition
|
||||
let locked = self.block.locked.as_ref().map(|(_, id)| id == &block.id()).unwrap_or(true);
|
||||
let locked = self.block.locked.as_ref().map_or(true, |(_, id)| id == &block.id());
|
||||
let mut vote = raw_vote.filter(|_| locked);
|
||||
|
||||
if let Some(vr) = vr {
|
||||
@@ -780,7 +779,7 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
||||
))?;
|
||||
}
|
||||
|
||||
if self.block.log.has_consensus(*vr, Data::Prevote(Some(block.id()))) {
|
||||
if self.block.log.has_consensus(*vr, &Data::Prevote(Some(block.id()))) {
|
||||
// Allow differing locked values if the proposal has a newer valid round
|
||||
// This is the other condition described above
|
||||
if let Some((locked_round, _)) = self.block.locked.as_ref() {
|
||||
@@ -798,25 +797,18 @@ impl<N: Network + 'static> TendermintMachine<N> {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
if self
|
||||
.block
|
||||
.valid
|
||||
.as_ref()
|
||||
.map(|(round, _)| round != &self.block.round().number)
|
||||
.unwrap_or(true)
|
||||
{
|
||||
if self.block.valid.as_ref().map_or(true, |(round, _)| round != &self.block.round().number) {
|
||||
// 36-43
|
||||
|
||||
// The run once condition is implemented above. Since valid will always be set by this, it
|
||||
// not being set, or only being set historically, means this has yet to be run
|
||||
|
||||
if self.block.log.has_consensus(self.block.round().number, Data::Prevote(Some(block.id()))) {
|
||||
if self.block.log.has_consensus(self.block.round().number, &Data::Prevote(Some(block.id()))) {
|
||||
match self.network.validate(block).await {
|
||||
Ok(()) => (),
|
||||
// BlockError::Temporal is due to a temporal error we have, yet a supermajority of the
|
||||
// network does not, Because we do not believe this block to be fatally invalid, and
|
||||
// because a supermajority deems it valid, accept it.
|
||||
Err(BlockError::Temporal) => (),
|
||||
Ok(()) | Err(BlockError::Temporal) => (),
|
||||
Err(BlockError::Fatal) => {
|
||||
log::warn!(target: "tendermint", "Validator proposed a fatally invalid block");
|
||||
// TODO: Produce evidence of this for the higher level code to decide what to do with
|
||||
|
||||
@@ -64,14 +64,14 @@ impl<N: Network> MessageLog<N> {
|
||||
|
||||
// For a given round, return the participating weight for this step, and the weight agreeing with
|
||||
// the data.
|
||||
pub(crate) fn message_instances(&self, round: RoundNumber, data: DataFor<N>) -> (u64, u64) {
|
||||
pub(crate) fn message_instances(&self, round: RoundNumber, data: &DataFor<N>) -> (u64, u64) {
|
||||
let mut participating = 0;
|
||||
let mut weight = 0;
|
||||
for (participant, msgs) in &self.log[&round] {
|
||||
if let Some(msg) = msgs.get(&data.step()) {
|
||||
let validator_weight = self.weights.weight(*participant);
|
||||
participating += validator_weight;
|
||||
if data == msg.msg.data {
|
||||
if data == &msg.msg.data {
|
||||
weight += validator_weight;
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,7 @@ impl<N: Network> MessageLog<N> {
|
||||
}
|
||||
|
||||
// Check if consensus has been reached on a specific piece of data
|
||||
pub(crate) fn has_consensus(&self, round: RoundNumber, data: DataFor<N>) -> bool {
|
||||
pub(crate) fn has_consensus(&self, round: RoundNumber, data: &DataFor<N>) -> bool {
|
||||
let (_, weight) = self.message_instances(round, data);
|
||||
weight >= self.weights.threshold()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user