feat(provider): implement BlockProvider::block (#1426)

This commit is contained in:
Roman Krasiuk
2023-02-17 13:13:49 +02:00
committed by GitHub
parent 94f759761a
commit 4203d7a9b7
5 changed files with 56 additions and 14 deletions

View File

@ -150,7 +150,7 @@ impl Command {
// TODO(mattsse): cleanup, add cli args
let _rpc_server = reth_rpc_builder::launch(
ShareableDatabase::new(db.clone()),
ShareableDatabase::new(db.clone(), self.chain.clone()),
reth_transaction_pool::test_utils::testing_pool(),
network.clone(),
TransportRpcModuleConfig::default()
@ -324,7 +324,7 @@ impl Command {
.network_config(config, self.chain.clone())
.with_task_executor(Box::new(executor))
.set_head(head)
.build(Arc::new(ShareableDatabase::new(db)))
.build(Arc::new(ShareableDatabase::new(db, self.chain.clone())))
}
async fn build_pipeline<H, B, U>(

View File

@ -107,7 +107,7 @@ impl Command {
network_config_builder = self.discovery.apply_to_builder(network_config_builder);
let network = network_config_builder
.build(Arc::new(ShareableDatabase::new(noop_db)))
.build(Arc::new(ShareableDatabase::new(noop_db, self.chain.clone())))
.start_network()
.await?;

View File

@ -136,7 +136,7 @@ impl Command {
let network = self
.network
.network_config(&config, self.chain.clone())
.build(Arc::new(ShareableDatabase::new(db.clone())))
.build(Arc::new(ShareableDatabase::new(db.clone(), self.chain.clone())))
.start_network()
.await?;
let fetch_client = Arc::new(network.fetch_client().await?);

View File

@ -5,7 +5,9 @@ use reth_db::{
transaction::DbTx,
};
use reth_interfaces::Result;
use reth_primitives::{rpc::BlockId, Block, BlockHash, BlockNumber, ChainInfo, Header, H256, U256};
use reth_primitives::{
rpc::BlockId, Block, BlockHash, BlockNumber, ChainInfo, ChainSpec, Hardfork, Header, H256, U256,
};
use std::ops::RangeBounds;
mod state;
@ -22,18 +24,20 @@ pub use state::{
pub struct ShareableDatabase<DB> {
/// Database
db: DB,
/// Chain spec
chain_spec: ChainSpec,
}
impl<DB> ShareableDatabase<DB> {
/// create new database provider
pub fn new(db: DB) -> Self {
Self { db }
pub fn new(db: DB, chain_spec: ChainSpec) -> Self {
Self { db, chain_spec }
}
}
impl<DB: Clone> Clone for ShareableDatabase<DB> {
fn clone(&self) -> Self {
Self { db: self.db.clone() }
Self { db: self.db.clone(), chain_spec: self.chain_spec.clone() }
}
}
@ -99,8 +103,42 @@ impl<DB: Database> BlockProvider for ShareableDatabase<DB> {
Ok(ChainInfo { best_hash, best_number, last_finalized: None, safe_finalized: None })
}
fn block(&self, _id: BlockId) -> Result<Option<Block>> {
// TODO
fn block(&self, id: BlockId) -> Result<Option<Block>> {
if let Some(number) = self.block_number_for_id(id)? {
if let Some(header) = self.header_by_number(number)? {
let tx = self.db.tx()?;
let body = tx
.get::<tables::BlockBodies>(header.number)?
.ok_or(Error::BlockBody { number })?;
let mut tx_cursor = tx.cursor_read::<tables::Transactions>()?;
let mut transactions = Vec::with_capacity(body.tx_count as usize);
for id in body.tx_id_range() {
let (_, transaction) =
tx_cursor.seek_exact(id)?.ok_or(Error::Transaction { id })?;
transactions.push(transaction);
}
let ommers = tx.get::<tables::BlockOmmers>(header.number)?.map(|o| o.ommers);
let header_timestamp = header.timestamp;
let mut block = Block {
header,
body: transactions,
ommers: ommers.unwrap_or_default(),
withdrawals: None,
};
if self.chain_spec.fork(Hardfork::Shanghai).active_at_timestamp(header_timestamp) {
let withdrawals =
tx.get::<tables::BlockWithdrawals>(number)?.map(|w| w.withdrawals);
block.withdrawals = Some(withdrawals.unwrap_or_default());
}
return Ok(Some(block))
}
}
Ok(None)
}
@ -149,19 +187,21 @@ mod tests {
use super::ShareableDatabase;
use reth_db::mdbx::{test_utils::create_test_db, EnvKind, WriteMap};
use reth_primitives::H256;
use reth_primitives::{ChainSpecBuilder, H256};
#[test]
fn common_history_provider() {
let chain_spec = ChainSpecBuilder::mainnet().build();
let db = create_test_db::<WriteMap>(EnvKind::RW);
let provider = ShareableDatabase::new(db);
let provider = ShareableDatabase::new(db, chain_spec);
let _ = provider.latest();
}
#[test]
fn default_chain_info() {
let chain_spec = ChainSpecBuilder::mainnet().build();
let db = create_test_db::<WriteMap>(EnvKind::RW);
let provider = ShareableDatabase::new(db);
let provider = ShareableDatabase::new(db, chain_spec);
let chain_info = provider.chain_info().expect("should be ok");
assert_eq!(chain_info.best_number, 0);

View File

@ -1,3 +1,5 @@
use crate::HeaderProvider;
use super::BlockHashProvider;
use reth_interfaces::Result;
use reth_primitives::{
@ -6,7 +8,7 @@ use reth_primitives::{
};
/// Api trait for fetching `Block` related data.
pub trait BlockProvider: BlockHashProvider + Send + Sync {
pub trait BlockProvider: BlockHashProvider + HeaderProvider + Send + Sync {
/// Returns the current info for the chain.
fn chain_info(&self) -> Result<ChainInfo>;