Skip to content

Commit 57e48ed

Browse files
committed
fix: fee history filterer behavior and arc management
1 parent 644abab commit 57e48ed

File tree

1 file changed

+111
-16
lines changed

1 file changed

+111
-16
lines changed

crates/rpc/src/ctx/fee_hist.rs

Lines changed: 111 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,49 +8,144 @@ use std::sync::Arc;
88

99
/// Removes Signet system transactions from the block.
1010
fn strip_block(block: RecoveredBlock<Block>) -> RecoveredBlock<Block> {
11-
let (sealed, senders) = block.split_sealed();
11+
let (sealed, mut senders) = block.split_sealed();
1212
let (header, mut body) = sealed.split_sealed_header_body();
1313

1414
// This is the index of the first transaction that has a system magic
1515
// signature.
1616
let sys_index = body
1717
.transactions
18-
.partition_point(|tx| MagicSig::try_from_signature(tx.signature()).is_some());
18+
.partition_point(|tx| MagicSig::try_from_signature(tx.signature()).is_none());
1919

2020
body.transactions.truncate(sys_index);
21+
senders.truncate(sys_index);
2122

2223
let sealed = SealedBlock::from_sealed_parts(header, body);
24+
2325
RecoveredBlock::new_sealed(sealed, senders)
2426
}
2527

2628
/// Removes Signet system transactions from the chain. This function uses
2729
/// `Arc::make_mut` to clone the contents of the Arc and modify the new
2830
/// instance.
29-
fn strip_chain(chain: &mut Arc<Chain>) {
30-
let chain = Arc::make_mut(chain);
31+
fn strip_chain(chain: &Chain) -> Arc<Chain> {
32+
// Takes the contents out, replacing with default
33+
let (blocks, outcome, trie) = chain.clone().into_inner();
3134

32-
let (blocks, outcome, trie) = std::mem::take(chain).into_inner();
33-
let blocks = blocks.into_blocks().map(strip_block);
35+
// Strip each block
36+
let blocks: Vec<RecoveredBlock<Block>> = blocks.into_blocks().map(strip_block).collect();
3437

35-
*chain = Chain::new(blocks, outcome, trie);
38+
// Replace the original chain with the stripped version
39+
Arc::new(Chain::new(blocks, outcome, trie))
3640
}
3741

3842
/// Strips Signet system transactions from the `CanonStateNotification`.
3943
pub(crate) fn strip_signet_system_txns(notif: CanonStateNotification) -> CanonStateNotification {
40-
// Cloning here ensures that the `make_mut` invocations in
41-
// `strip_chain` do not ever modify the original `notif` object.
42-
let _c = notif.clone();
43-
4444
match notif {
45-
CanonStateNotification::Commit { mut new } => {
46-
strip_chain(&mut new);
47-
CanonStateNotification::Commit { new }
45+
CanonStateNotification::Commit { new } => {
46+
CanonStateNotification::Commit { new: strip_chain(&new) }
4847
}
4948
CanonStateNotification::Reorg { mut old, mut new } => {
50-
strip_chain(&mut old);
51-
strip_chain(&mut new);
49+
old = strip_chain(&old);
50+
new = strip_chain(&new);
5251

5352
CanonStateNotification::Reorg { old, new }
5453
}
5554
}
5655
}
56+
57+
#[cfg(test)]
58+
mod test {
59+
use alloy::{
60+
consensus::{TxEip1559, TxEnvelope},
61+
primitives::{Address, B256},
62+
signers::Signature,
63+
};
64+
use reth::primitives::{BlockBody, SealedHeader};
65+
66+
use super::*;
67+
68+
fn test_magic_sig_tx() -> TxEnvelope {
69+
let sig = MagicSig::enter(B256::repeat_byte(0x22), 3);
70+
71+
let sig = sig.into();
72+
73+
dbg!(MagicSig::try_from_signature(&sig).is_some());
74+
75+
TxEnvelope::new_unchecked(TxEip1559::default().into(), sig, B256::repeat_byte(0x33))
76+
}
77+
78+
fn test_non_magic_sig_tx() -> TxEnvelope {
79+
let sig = Signature::test_signature();
80+
TxEnvelope::new_unchecked(TxEip1559::default().into(), sig.into(), B256::repeat_byte(0x44))
81+
}
82+
83+
fn test_block_body() -> BlockBody {
84+
BlockBody {
85+
transactions: vec![
86+
test_non_magic_sig_tx().into(),
87+
test_non_magic_sig_tx().into(),
88+
test_magic_sig_tx().into(),
89+
test_magic_sig_tx().into(),
90+
],
91+
..Default::default()
92+
}
93+
}
94+
95+
fn test_sealed_header(block_num: u64) -> SealedHeader {
96+
let mut header: reth::primitives::Header = Default::default();
97+
header.number = block_num;
98+
SealedHeader::new_unhashed(header)
99+
}
100+
101+
fn test_sealed_block(block_num: u64) -> SealedBlock<Block> {
102+
SealedBlock::from_sealed_parts(test_sealed_header(block_num), test_block_body())
103+
}
104+
105+
fn test_block(block_num: u64) -> RecoveredBlock<Block> {
106+
RecoveredBlock::new_sealed(
107+
test_sealed_block(block_num),
108+
vec![Address::repeat_byte(0x11); 4],
109+
)
110+
}
111+
112+
fn test_chain(count: u64) -> Arc<Chain> {
113+
let blocks = (0..count).map(test_block);
114+
Arc::new(Chain::new(blocks, Default::default(), None))
115+
}
116+
117+
#[test]
118+
fn test_strip_block() {
119+
let block = test_block(0);
120+
assert_eq!(block.body().transactions.len(), 4);
121+
assert_eq!(block.senders().len(), 4);
122+
123+
let stripped = strip_block(block);
124+
assert_eq!(stripped.body().transactions.len(), 2);
125+
assert_eq!(stripped.senders().len(), 2);
126+
127+
for tx in stripped.body().transactions.iter() {
128+
assert!(MagicSig::try_from_signature(tx.signature()).is_none());
129+
}
130+
}
131+
132+
#[test]
133+
fn test_strip_chain() {
134+
let original = test_chain(2);
135+
assert_eq!(original.blocks().len(), 2);
136+
137+
let chain = strip_chain(&original);
138+
139+
assert_ne!(&*chain, &*original);
140+
141+
assert_eq!(chain.blocks().len(), 2);
142+
143+
for (_num, block) in chain.blocks().iter() {
144+
assert_eq!(block.body().transactions.len(), 2);
145+
assert_eq!(block.senders().len(), 2);
146+
for tx in block.body().transactions.iter() {
147+
assert!(MagicSig::try_from_signature(tx.signature()).is_none());
148+
}
149+
}
150+
}
151+
}

0 commit comments

Comments
 (0)