Skip to content

Commit b5b75aa

Browse files
authored
db maintenance cleanup and tests (#23)
* wip: db maintenance cleanup and tests * tests: add a simple DB test * lint: clippy
1 parent 8a74a59 commit b5b75aa

File tree

8 files changed

+317
-45
lines changed

8 files changed

+317
-45
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ members = ["crates/*"]
33
resolver = "2"
44

55
[workspace.package]
6-
version = "0.9.3"
6+
version = "0.9.4"
77
edition = "2024"
88
rust-version = "1.88"
99
authors = ["init4"]

crates/db/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,9 @@ tracing.workspace = true
2929
futures-util = "0.3.31"
3030
tokio.workspace = true
3131
auto_impl = "1.3.0"
32+
33+
[dev-dependencies]
34+
serde_json.workspace = true
35+
reth-db = { workspace = true, features = ["test-utils"] }
36+
reth-exex-test-utils.workspace = true
37+
signet-constants = { workspace = true, features = ["test-utils"] }

crates/db/src/convert.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
//! Type conversion traits and implementations for converting between Reth, Alloy, and Signet types.
22
//!
3-
//! This module provides a set of conversion traits that enable seamless interoperability
4-
//! between different type systems used in the Ethereum ecosystem:
3+
//! This module provides a set of conversion traits that enable seamless
4+
//! interoperability between different type systems used in the Ethereum
5+
//! ecosystem:
56
//!
67
//! - **Reth types**: Core primitives from the Reth Ethereum client
78
//! - **Alloy types**: Modern Ethereum types from the Alloy framework

crates/db/src/provider.rs

Lines changed: 4 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,14 @@ use alloy::{
88
primitives::{Address, B256, BlockNumber, U256, map::HashSet},
99
};
1010
use reth::{
11-
primitives::{Account, StaticFileSegment},
11+
primitives::StaticFileSegment,
1212
providers::{
13-
AccountReader, BlockBodyIndicesProvider, BlockNumReader, BlockReader, BlockWriter, Chain,
14-
DBProvider, HistoryWriter, OriginalValuesKnown, ProviderError, ProviderResult,
15-
StageCheckpointWriter, StateWriter, StaticFileProviderFactory, StaticFileWriter,
16-
StorageLocation,
13+
BlockBodyIndicesProvider, BlockNumReader, BlockReader, BlockWriter, Chain, DBProvider,
14+
HistoryWriter, OriginalValuesKnown, ProviderError, ProviderResult, StageCheckpointWriter,
15+
StateWriter, StaticFileProviderFactory, StaticFileWriter, StorageLocation,
1716
},
1817
};
1918
use reth_db::{
20-
PlainAccountState,
2119
cursor::{DbCursorRO, DbCursorRW},
2220
models::{BlockNumberAddress, StoredBlockBodyIndices},
2321
tables,
@@ -104,31 +102,6 @@ where
104102
.map_err(Into::into)
105103
}
106104

107-
/// Increase the balance of an account.
108-
fn mint_eth(&self, address: Address, amount: U256) -> ProviderResult<Account> {
109-
let mut account = self.basic_account(&address)?.unwrap_or_default();
110-
account.balance = account.balance.saturating_add(amount);
111-
self.tx_ref().put::<PlainAccountState>(address, account)?;
112-
trace!(%address, balance = %account.balance, "minting ETH");
113-
Ok(account)
114-
}
115-
116-
/// Decrease the balance of an account.
117-
fn burn_eth(&self, address: Address, amount: U256) -> ProviderResult<Account> {
118-
let mut account = self.basic_account(&address)?.unwrap_or_default();
119-
if amount > account.balance {
120-
warn!(
121-
balance = %account.balance,
122-
amount = %amount,
123-
"burning more than balance"
124-
);
125-
}
126-
account.balance = account.balance.saturating_sub(amount);
127-
self.tx_ref().put::<PlainAccountState>(address, account)?;
128-
trace!(%address, balance = %account.balance, "burning ETH");
129-
Ok(account)
130-
}
131-
132105
fn insert_signet_header(
133106
&self,
134107
header: Zenith::BlockHeader,

crates/db/src/traits.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
use crate::{DbExtractionResults, DbSignetEvent, RuChain, SignetDbRw};
2-
use alloy::primitives::{Address, B256, BlockNumber, U256};
2+
use alloy::primitives::{B256, BlockNumber};
33
use itertools::Itertools;
4-
use reth::{
5-
primitives::Account,
6-
providers::{OriginalValuesKnown, ProviderResult, StorageLocation},
7-
};
4+
use reth::providers::{OriginalValuesKnown, ProviderResult, StorageLocation};
85
use reth_db::models::StoredBlockBodyIndices;
96
use signet_evm::BlockResult;
107
use signet_node_types::NodeTypesDbTrait;
@@ -31,12 +28,6 @@ pub trait RuWriter {
3128
/// Get the latest journal hash from the DB.
3229
fn latest_journal_hash(&self) -> ProviderResult<B256>;
3330

34-
/// Increase the balance of an account.
35-
fn mint_eth(&self, address: Address, amount: U256) -> ProviderResult<Account>;
36-
37-
/// Decrease the balance of an account.
38-
fn burn_eth(&self, address: Address, amount: U256) -> ProviderResult<Account>;
39-
4031
/// Store a zenith header in the DB
4132
fn insert_signet_header(
4233
&self,

crates/db/tests/common/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use alloy::genesis::Genesis;
2+
use reth::{
3+
chainspec::ChainSpec,
4+
providers::{ProviderFactory, providers::StaticFileProvider},
5+
};
6+
use reth_db::test_utils::{create_test_rw_db, create_test_static_files_dir};
7+
use reth_exex_test_utils::TmpDB as TmpDb;
8+
use signet_node_types::SignetNodeTypes;
9+
use std::sync::{Arc, OnceLock};
10+
11+
static GENESIS_JSON: &str = include_str!("../../../../tests/artifacts/local.genesis.json");
12+
13+
static SPEC: OnceLock<Arc<ChainSpec>> = OnceLock::new();
14+
15+
/// Returns a chain spec for tests.
16+
pub fn chain_spec() -> Arc<ChainSpec> {
17+
SPEC.get_or_init(|| {
18+
let genesis: Genesis = serde_json::from_str(GENESIS_JSON).expect("valid genesis json");
19+
Arc::new(genesis.into())
20+
})
21+
.clone()
22+
}
23+
24+
/// Create a provider factory with a chain spec
25+
pub fn create_test_provider_factory() -> ProviderFactory<SignetNodeTypes<TmpDb>> {
26+
let (static_dir, _) = create_test_static_files_dir();
27+
let db = create_test_rw_db();
28+
ProviderFactory::new(
29+
db,
30+
chain_spec(),
31+
StaticFileProvider::read_write(static_dir.keep()).expect("static file provider"),
32+
)
33+
}

crates/db/tests/db.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
#[path = "./common/mod.rs"]
2+
mod test_common;
3+
4+
use alloy::{
5+
consensus::{BlockBody, BlockHeader, Signed, TxEip1559, TxEnvelope},
6+
primitives::{Address, B256, U256},
7+
signers::Signature,
8+
};
9+
use reth::providers::{BlockNumReader, BlockReader};
10+
use signet_constants::test_utils::{DEPLOY_HEIGHT, RU_CHAIN_ID};
11+
use signet_db::RuWriter;
12+
use signet_types::primitives::{RecoveredBlock, SealedBlock, SealedHeader};
13+
use signet_zenith::Zenith;
14+
15+
#[test]
16+
fn test_ru_writer() {
17+
let factory = test_common::create_test_provider_factory();
18+
19+
let writer = factory.provider_rw().unwrap();
20+
21+
dbg!(writer.last_block_number().unwrap());
22+
}
23+
24+
#[test]
25+
fn test_insert_signet_block() {
26+
let factory = test_common::create_test_provider_factory();
27+
let writer = factory.provider_rw().unwrap();
28+
29+
let journal_hash = B256::repeat_byte(0x55);
30+
let header = Some(Zenith::BlockHeader {
31+
rollupChainId: U256::from(RU_CHAIN_ID),
32+
hostBlockNumber: U256::from(DEPLOY_HEIGHT),
33+
gasLimit: U256::from(30_000_000),
34+
rewardAddress: Address::repeat_byte(0x11),
35+
blockDataHash: B256::repeat_byte(0x22),
36+
});
37+
38+
let block = RecoveredBlock {
39+
block: SealedBlock {
40+
header: SealedHeader::new(alloy::consensus::Header::default()),
41+
body: BlockBody {
42+
transactions: std::iter::repeat_n(
43+
TxEnvelope::Eip1559(Signed::new_unhashed(
44+
TxEip1559::default(),
45+
Signature::test_signature(),
46+
))
47+
.into(),
48+
10,
49+
)
50+
.collect(),
51+
ommers: vec![],
52+
withdrawals: None,
53+
},
54+
},
55+
senders: std::iter::repeat_n(Address::repeat_byte(0x33), 10).collect(),
56+
};
57+
58+
writer
59+
.insert_signet_block(header, &block, journal_hash, reth::providers::StorageLocation::Both)
60+
.unwrap();
61+
62+
// Check basic updates
63+
assert_eq!(writer.last_block_number().unwrap(), block.number());
64+
assert_eq!(writer.latest_journal_hash().unwrap(), journal_hash);
65+
assert_eq!(writer.get_journal_hash(block.number()).unwrap(), Some(journal_hash));
66+
// This tests resolving `BlockId::Latest`
67+
assert_eq!(writer.best_block_number().unwrap(), block.number());
68+
69+
// Check that the block can be loaded back
70+
let loaded_block = writer
71+
.recovered_block_range(block.number()..=block.number())
72+
.unwrap()
73+
.first()
74+
.cloned()
75+
.unwrap();
76+
assert_eq!(loaded_block.header(), block.block.header.header());
77+
assert_eq!(loaded_block.body().transactions.len(), block.block.body.transactions.len());
78+
79+
// Check that the ZenithHeader can be loaded back
80+
let loaded_header = writer.get_signet_header(block.number()).unwrap();
81+
assert_eq!(loaded_header, header);
82+
}

tests/artifacts/local.genesis.json

Lines changed: 186 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)