validator: improved uproposed txs retriaval logic

This commit is contained in:
skoupidi
2024-02-08 17:13:01 +02:00
parent 2094274851
commit 72526ed18c
3 changed files with 45 additions and 18 deletions

View File

@@ -465,6 +465,17 @@ impl BlockchainOverlay {
Ok(ret)
}
/// Retrieve [`Block`]s by given hashes and return their transactions hashes.
pub fn get_blocks_txs_hashes(&self, hashes: &[blake3::Hash]) -> Result<Vec<blake3::Hash>> {
let blocks = self.blocks.get(hashes, true)?;
let mut ret = vec![];
for block in blocks {
ret.extend_from_slice(&block.unwrap().txs);
}
Ok(ret)
}
/// Checkpoint overlay so we can revert to it, if needed.
pub fn checkpoint(&self) {
self.overlay.lock().unwrap().checkpoint();

View File

@@ -38,7 +38,7 @@ use crate::{
};
// Consensus configuration
/// Block/proposal maximum transactions
/// Block/proposal maximum transactions, exluding producer transaction
pub const TXS_CAP: usize = 50;
/// This struct represents the information required by the consensus algorithm
@@ -364,28 +364,44 @@ impl Fork {
blockchain: &Blockchain,
verifying_block_height: u64,
) -> Result<Vec<Transaction>> {
// Retrieve all mempool transactions
let mut unproposed_txs: Vec<Transaction> = blockchain
.pending_txs
.get(&self.mempool, true)?
.iter()
.map(|x| x.clone().unwrap())
.collect();
// Check if our mempool is not empty
if self.mempool.is_empty() {
return Ok(vec![])
}
// Iterate over fork proposals to find already proposed transactions
// and remove them from the unproposed_txs vector.
let proposals = self.overlay.lock().unwrap().get_blocks_by_hash(&self.proposals)?;
for proposal in proposals {
for tx in &proposal.txs {
unproposed_txs.retain(|x| x != tx);
// Grab all current proposals transactions hashes
let proposals_txs = self.overlay.lock().unwrap().get_blocks_txs_hashes(&self.proposals)?;
// Iterate through all pending transactions in the forks' mempool
let mut unproposed_txs = vec![];
for tx in &self.mempool {
// If the hash is contained in the proposals transactions vec, skip it
if proposals_txs.contains(tx) {
continue
}
// Push the tx hash into the unproposed transactions vector
unproposed_txs.push(*tx);
// Check limit
if unproposed_txs.len() == TXS_CAP {
break
}
}
// Check if transactions exceed configured cap
if unproposed_txs.len() > TXS_CAP {
unproposed_txs = unproposed_txs[0..TXS_CAP].to_vec()
// Check if we have any unproposed transactions
if unproposed_txs.is_empty() {
return Ok(vec![])
}
// Retrieve the actual unproposed transactions
let mut unproposed_txs: Vec<Transaction> = blockchain
.pending_txs
.get(&unproposed_txs, true)?
.iter()
.map(|x| x.clone().unwrap())
.collect();
// Clone forks' overlay
let overlay = self.overlay.lock().unwrap().full_clone()?;

View File

@@ -695,7 +695,7 @@ pub async fn verify_proposal(
}
// Check that proposal transactions don't exceed limit (2)
if proposal.block.txs.len() > TXS_CAP {
if proposal.block.txs.len() > TXS_CAP + 1 {
warn!(
target: "validator::verification::verify_pow_proposal", "Received proposal transactions exceed configured cap: {} - {}",
proposal.block.txs.len(),