use crate::node::mempool::MempoolManager;
use crate::storage::{blockstore::BlockStore, txindex::TxIndex};
use anyhow::Result;
use blvm_protocol::network::{ChainObject, ChainStateAccess};
use blvm_protocol::{BlockHeader, Hash, Transaction};
use std::sync::Arc;
pub struct NodeChainAccess {
blockstore: Arc<BlockStore>,
txindex: Arc<TxIndex>,
mempool: Arc<MempoolManager>,
}
impl NodeChainAccess {
pub fn new(
blockstore: Arc<BlockStore>,
txindex: Arc<TxIndex>,
mempool: Arc<MempoolManager>,
) -> Self {
Self {
blockstore,
txindex,
mempool,
}
}
}
impl ChainStateAccess for NodeChainAccess {
fn has_object(&self, hash: &Hash) -> bool {
if let Ok(true) = self.blockstore.has_block(hash) {
return true;
}
if let Ok(Some(_)) = self.txindex.get_transaction(hash) {
return true;
}
self.mempool.get_transaction(hash).is_some()
}
fn get_object(&self, hash: &Hash) -> Option<ChainObject> {
if let Ok(Some(block)) = self.blockstore.get_block(hash) {
return Some(ChainObject::Block(Arc::new(block)));
}
if let Ok(Some(tx)) = self.txindex.get_transaction(hash) {
return Some(ChainObject::Transaction(Arc::new(tx)));
}
if let Some(tx) = self.mempool.get_transaction(hash) {
return Some(ChainObject::Transaction(Arc::new(tx)));
}
None
}
fn get_headers_for_locator(&self, locator: &[Hash], stop: &Hash) -> Vec<BlockHeader> {
const MAX_HEADERS: usize = 2000;
self.blockstore
.build_headers_response(locator, stop, MAX_HEADERS)
.unwrap_or_default()
}
fn get_mempool_transactions(&self) -> Vec<Transaction> {
self.mempool.get_transactions()
}
}
pub fn process_protocol_message(
engine: &blvm_protocol::BitcoinProtocolEngine,
message: &blvm_protocol::network::NetworkMessage,
peer_state: &mut blvm_protocol::network::PeerState,
chain_access: &NodeChainAccess,
utxo_set: Option<&blvm_protocol::UtxoSet>,
height: Option<u64>,
) -> Result<blvm_protocol::network::NetworkResponse> {
use blvm_protocol::network::{process_network_message, ChainStateAccess};
process_network_message(
engine,
message,
peer_state,
Some(chain_access as &dyn ChainStateAccess),
utxo_set,
height,
)
.map_err(|e| anyhow::anyhow!("Network message processing error: {}", e))
}