@@ -107,6 +107,14 @@ pub enum ConnectStyle {
107107 /// The same as `TransactionsFirst`, however when we have multiple blocks to connect, we only
108108 /// make a single `best_block_updated` call.
109109 TransactionsFirstSkippingBlocks ,
110+ /// The same as `TransactionsFirst`, however when we have multiple blocks to connect, we only
111+ /// make a single `best_block_updated` call. Further, we call transactions_confirmed multiple
112+ /// times to ensure its idempotent.
113+ TransactionsDuplicativelyFirstSkippingBlocks ,
114+ /// The same as `TransactionsFirst`, however when we have multiple blocks to connect, we only
115+ /// make a single `best_block_updated` call. Further, we call transactions_confirmed multiple
116+ /// times to ensure its idempotent.
117+ HighlyRedundantTransactionsFirstSkippingBlocks ,
110118 /// The same as `TransactionsFirst` when connecting blocks. During disconnection only
111119 /// `transaction_unconfirmed` is called.
112120 TransactionsFirstReorgsOnlyTip ,
@@ -121,14 +129,16 @@ impl ConnectStyle {
121129 use core:: hash:: { BuildHasher , Hasher } ;
122130 // Get a random value using the only std API to do so - the DefaultHasher
123131 let rand_val = std:: collections:: hash_map:: RandomState :: new ( ) . build_hasher ( ) . finish ( ) ;
124- let res = match rand_val % 7 {
132+ let res = match rand_val % 9 {
125133 0 => ConnectStyle :: BestBlockFirst ,
126134 1 => ConnectStyle :: BestBlockFirstSkippingBlocks ,
127135 2 => ConnectStyle :: BestBlockFirstReorgsOnlyTip ,
128136 3 => ConnectStyle :: TransactionsFirst ,
129137 4 => ConnectStyle :: TransactionsFirstSkippingBlocks ,
130- 5 => ConnectStyle :: TransactionsFirstReorgsOnlyTip ,
131- 6 => ConnectStyle :: FullBlockViaListen ,
138+ 5 => ConnectStyle :: TransactionsDuplicativelyFirstSkippingBlocks ,
139+ 6 => ConnectStyle :: HighlyRedundantTransactionsFirstSkippingBlocks ,
140+ 7 => ConnectStyle :: TransactionsFirstReorgsOnlyTip ,
141+ 8 => ConnectStyle :: FullBlockViaListen ,
132142 _ => unreachable ! ( ) ,
133143 } ;
134144 eprintln ! ( "Using Block Connection Style: {:?}" , res) ;
@@ -143,6 +153,7 @@ impl ConnectStyle {
143153pub fn connect_blocks < ' a , ' b , ' c , ' d > ( node : & ' a Node < ' b , ' c , ' d > , depth : u32 ) -> BlockHash {
144154 let skip_intermediaries = match * node. connect_style . borrow ( ) {
145155 ConnectStyle :: BestBlockFirstSkippingBlocks |ConnectStyle :: TransactionsFirstSkippingBlocks |
156+ ConnectStyle :: TransactionsDuplicativelyFirstSkippingBlocks |ConnectStyle :: HighlyRedundantTransactionsFirstSkippingBlocks |
146157 ConnectStyle :: BestBlockFirstReorgsOnlyTip |ConnectStyle :: TransactionsFirstReorgsOnlyTip => true ,
147158 _ => false ,
148159 } ;
@@ -193,8 +204,13 @@ fn do_connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: Block, sk
193204 node. node . best_block_updated ( & block. header , height) ;
194205 node. node . transactions_confirmed ( & block. header , & txdata, height) ;
195206 } ,
196- ConnectStyle :: TransactionsFirst |ConnectStyle :: TransactionsFirstSkippingBlocks |ConnectStyle :: TransactionsFirstReorgsOnlyTip => {
207+ ConnectStyle :: TransactionsFirst |ConnectStyle :: TransactionsFirstSkippingBlocks |
208+ ConnectStyle :: TransactionsDuplicativelyFirstSkippingBlocks |ConnectStyle :: HighlyRedundantTransactionsFirstSkippingBlocks |
209+ ConnectStyle :: TransactionsFirstReorgsOnlyTip => {
197210 node. chain_monitor . chain_monitor . transactions_confirmed ( & block. header , & txdata, height) ;
211+ if * node. connect_style . borrow ( ) == ConnectStyle :: TransactionsDuplicativelyFirstSkippingBlocks {
212+ node. chain_monitor . chain_monitor . transactions_confirmed ( & block. header , & txdata, height) ;
213+ }
198214 call_claimable_balances ( node) ;
199215 node. chain_monitor . chain_monitor . best_block_updated ( & block. header , height) ;
200216 node. node . transactions_confirmed ( & block. header , & txdata, height) ;
@@ -205,6 +221,17 @@ fn do_connect_block<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, block: Block, sk
205221 node. node . block_connected ( & block, height) ;
206222 }
207223 }
224+ if * node. connect_style . borrow ( ) == ConnectStyle :: TransactionsDuplicativelyFirstSkippingBlocks {
225+ for ( block, height) in node. blocks . lock ( ) . unwrap ( ) . iter ( ) {
226+ if !block. txdata . is_empty ( ) {
227+ // Reconnect all transactions we've ever seen to ensure transaction connection
228+ // is *really* idempotent. This is a somewhat likely deployment for some
229+ // esplora implementations of chain sync which try to reduce state and
230+ // complexity as much as possible.
231+ node. chain_monitor . chain_monitor . transactions_confirmed ( & block. header , & txdata, * height) ;
232+ }
233+ }
234+ }
208235 }
209236 call_claimable_balances ( node) ;
210237 node. node . test_process_background_events ( ) ;
@@ -226,7 +253,8 @@ pub fn disconnect_blocks<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, count: u32)
226253 node. chain_monitor . chain_monitor . block_disconnected ( & orig. 0 . header , orig. 1 ) ;
227254 Listen :: block_disconnected ( node. node , & orig. 0 . header , orig. 1 ) ;
228255 } ,
229- ConnectStyle :: BestBlockFirstSkippingBlocks |ConnectStyle :: TransactionsFirstSkippingBlocks => {
256+ ConnectStyle :: BestBlockFirstSkippingBlocks |ConnectStyle :: TransactionsFirstSkippingBlocks |
257+ ConnectStyle :: HighlyRedundantTransactionsFirstSkippingBlocks |ConnectStyle :: TransactionsDuplicativelyFirstSkippingBlocks => {
230258 if i == count - 1 {
231259 node. chain_monitor . chain_monitor . best_block_updated ( & prev. 0 . header , prev. 1 ) ;
232260 node. node . best_block_updated ( & prev. 0 . header , prev. 1 ) ;
0 commit comments