Skip to content

Commit

Permalink
Add check to verify mempool state
Browse files Browse the repository at this point in the history
Added a check to verify that the mempool last processed block is in sync with the
blockchain state whenever a new block template is requested, as adding a block to
the db and processing the same block in the mempool happens asynchronously. If this
is not done, miners can get block templates with double spends.
  • Loading branch information
hansieodendaal committed May 2, 2024
1 parent ac8558e commit 4c4c486
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
13 changes: 13 additions & 0 deletions base_layer/core/src/base_node/comms_interface/inbound_handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,15 @@ where B: BlockchainBackend + 'static
},
NodeCommsRequest::GetNewBlockTemplate(request) => {
let best_block_header = self.blockchain_db.fetch_tip_header().await?;
let last_seen_hash = self.mempool.get_last_seen_hash().await?;
if best_block_header.hash() != &last_seen_hash {
warn!(
target: LOG_TARGET,
"Mempool out of sync - last seen hash '{}' does not match the tip hash '{}'.",
last_seen_hash, best_block_header.hash()
);
return Err(CommsInterfaceError::InternalError("Mempool out of sync".to_string()));
}
let mut header = BlockHeader::from_previous(best_block_header.header());
let constants = self.consensus_manager.consensus_constants(header.height);
header.version = constants.blockchain_version();
Expand Down Expand Up @@ -989,6 +998,10 @@ where B: BlockchainBackend + 'static
debug!(target: LOG_TARGET, "Target difficulty {} for PoW {}", target, pow_algo);
Ok(target)
}

pub async fn get_last_seen_hash(&self) -> Result<FixedHash, CommsInterfaceError> {
self.mempool.get_last_seen_hash().await.map_err(|e| e.into())
}
}

impl<B> Clone for InboundNodeCommsHandlers<B> {
Expand Down
6 changes: 5 additions & 1 deletion base_layer/core/src/mempool/mempool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
use std::sync::{Arc, RwLock};

use log::debug;
use tari_common_types::types::{PrivateKey, Signature};
use tari_common_types::types::{FixedHash, PrivateKey, Signature};
use tokio::task;

use crate::{
Expand Down Expand Up @@ -213,4 +213,8 @@ impl Mempool {
})
.await?
}

pub async fn get_last_seen_hash(&self) -> Result<FixedHash, MempoolError> {
self.with_read_access(|storage| Ok(storage.last_seen_hash)).await
}
}
5 changes: 4 additions & 1 deletion base_layer/core/src/mempool/mempool_storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
use std::{sync::Arc, time::Instant};

use log::*;
use tari_common_types::types::{PrivateKey, Signature};
use tari_common_types::types::{FixedHash, PrivateKey, Signature};
use tari_utilities::hex::Hex;

use crate::{
Expand Down Expand Up @@ -57,6 +57,7 @@ pub struct MempoolStorage {
validator: Box<dyn TransactionValidator>,
rules: ConsensusManager,
last_seen_height: u64,
pub(crate) last_seen_hash: FixedHash,
}

impl MempoolStorage {
Expand All @@ -68,6 +69,7 @@ impl MempoolStorage {
validator,
rules,
last_seen_height: 0,
last_seen_hash: Default::default(),
}
}

Expand Down Expand Up @@ -220,6 +222,7 @@ impl MempoolStorage {
self.reorg_pool.compact();

self.last_seen_height = published_block.header.height;
self.last_seen_hash = published_block.header.hash();
debug!(target: LOG_TARGET, "Compaction took {:.2?}", timer.elapsed());
match self.stats() {
Ok(stats) => debug!(target: LOG_TARGET, "{}", stats),
Expand Down

0 comments on commit 4c4c486

Please sign in to comment.