@@ -8,49 +8,144 @@ use std::sync::Arc;
88
99/// Removes Signet system transactions from the block.
1010fn 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`.
3943pub ( 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