perf(db): RawTable, decode/encode only if needed (#2081)

This commit is contained in:
rakita
2023-04-05 14:46:10 +02:00
committed by GitHub
parent 77a41e5edf
commit 7c18ba8ed3
5 changed files with 143 additions and 14 deletions

View File

@ -7,6 +7,7 @@ use reth_db::{
database::Database,
tables,
transaction::{DbTx, DbTxMut},
RawKey, RawTable,
};
use reth_primitives::{keccak256, AccountHashingCheckpoint};
use reth_provider::Transaction;
@ -197,14 +198,15 @@ impl<DB: Database> Stage<DB> for AccountHashingStage {
self.save_checkpoint(tx, checkpoint)?;
}
let start_address = checkpoint.address.take();
let start_address = checkpoint.address.take().map(RawKey::new);
let next_address = {
let mut accounts_cursor = tx.cursor_read::<tables::PlainAccountState>()?;
let mut accounts_cursor =
tx.cursor_read::<RawTable<tables::PlainAccountState>>()?;
// channels used to return result of account hashing
let mut channels = Vec::new();
for chunk in &accounts_cursor
.walk(start_address)?
.walk(start_address.clone())?
.take(self.commit_threshold as usize)
.chunks(self.commit_threshold as usize / rayon::current_num_threads())
{
@ -216,7 +218,8 @@ impl<DB: Database> Stage<DB> for AccountHashingStage {
// Spawn the hashing task onto the global rayon pool
rayon::spawn(move || {
for (address, account) in chunk.into_iter() {
let _ = tx.send((keccak256(address), account));
let address = address.key().unwrap();
let _ = tx.send((RawKey::new(keccak256(address)), account));
}
});
}
@ -228,11 +231,11 @@ impl<DB: Database> Stage<DB> for AccountHashingStage {
hashed_batch.push(hashed);
}
}
// sort it all in parallel
hashed_batch.par_sort_unstable_by(|a, b| a.0.cmp(&b.0));
let mut hashed_account_cursor = tx.cursor_write::<tables::HashedAccount>()?;
let mut hashed_account_cursor =
tx.cursor_write::<RawTable<tables::HashedAccount>>()?;
// iterate and put presorted hashed accounts
if start_address.is_none() {
@ -244,13 +247,12 @@ impl<DB: Database> Stage<DB> for AccountHashingStage {
.into_iter()
.try_for_each(|(k, v)| hashed_account_cursor.insert(k, v))?;
}
// next key of iterator
accounts_cursor.next()?
};
if let Some((next_address, _)) = &next_address {
checkpoint.address = Some(*next_address);
checkpoint.address = Some(next_address.key().unwrap());
checkpoint.from = from_transition;
checkpoint.to = to_transition;
}

View File

@ -8,6 +8,7 @@ use reth_db::{
database::Database,
tables,
transaction::{DbTx, DbTxMut},
RawKey, RawTable, RawValue,
};
use reth_primitives::{TransactionSigned, TxNumber, H160};
use reth_provider::Transaction;
@ -31,7 +32,7 @@ pub struct SenderRecoveryStage {
impl Default for SenderRecoveryStage {
fn default() -> Self {
Self { commit_threshold: 10000 }
Self { commit_threshold: 500_000 }
}
}
@ -72,9 +73,10 @@ impl<DB: Database> Stage<DB> for SenderRecoveryStage {
let mut senders_cursor = tx.cursor_write::<tables::TxSenders>()?;
// Acquire the cursor over the transactions
let mut tx_cursor = tx.cursor_read::<tables::Transactions>()?;
let mut tx_cursor = tx.cursor_read::<RawTable<tables::Transactions>>()?;
// Walk the transactions from start to end index (inclusive)
let tx_walker = tx_cursor.walk_range(first_tx_num..=last_tx_num)?;
let tx_walker =
tx_cursor.walk_range(RawKey::new(first_tx_num)..=RawKey::new(last_tx_num))?;
// Iterate over transactions in chunks
info!(target: "sync::stages::sender_recovery", first_tx_num, last_tx_num, "Recovering senders");
@ -98,8 +100,14 @@ impl<DB: Database> Stage<DB> for SenderRecoveryStage {
let chunk: Vec<_> = chunk.collect();
// closure that would recover signer. Used as utility to wrap result
let recover = |entry: Result<(TxNumber, TransactionSigned), reth_db::Error>| -> Result<(u64, H160), Box<StageError>> {
let recover = |entry: Result<
(RawKey<TxNumber>, RawValue<TransactionSigned>),
reth_db::Error,
>|
-> Result<(u64, H160), Box<StageError>> {
let (tx_id, transaction) = entry.map_err(|e| Box::new(e.into()))?;
let tx_id = tx_id.key().expect("key to be formated");
let transaction = transaction.value().expect("value to be formated");
let sender = transaction.recover_signer().ok_or(StageError::from(
SenderRecoveryStageError::SenderRecovery { tx: tx_id },
))?;
@ -115,7 +123,6 @@ impl<DB: Database> Stage<DB> for SenderRecoveryStage {
}
});
}
// Iterate over channels and append the sender in the order that they are received.
for mut channel in channels {
while let Some(recovered) = channel.recv().await {