@@ -60,59 +60,110 @@ pub fn mine_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transac
60
60
/// Mine the given transaction at the given height, mining blocks as required to build to that
61
61
/// height
62
62
pub fn confirm_transaction_at < ' a , ' b , ' c , ' d > ( node : & ' a Node < ' b , ' c , ' d > , tx : & Transaction , conf_height : u32 ) {
63
- let starting_block = node. best_block_info ( ) ;
63
+ let first_connect_height = node. best_block_info ( ) . 1 + 1 ;
64
+ assert ! ( first_connect_height <= conf_height) ;
65
+ if conf_height - first_connect_height >= 1 {
66
+ connect_blocks ( node, conf_height - first_connect_height) ;
67
+ }
64
68
let mut block = Block {
65
- header : BlockHeader { version : 0x20000000 , prev_blockhash : starting_block . 0 , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ,
69
+ header : BlockHeader { version : 0x20000000 , prev_blockhash : node . best_block_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ,
66
70
txdata : Vec :: new ( ) ,
67
71
} ;
68
- let height = starting_block. 1 + 1 ;
69
- assert ! ( height <= conf_height) ;
70
- for _ in height..conf_height {
71
- connect_block ( node, & block) ;
72
- block = Block {
73
- header : BlockHeader { version : 0x20000000 , prev_blockhash : block. header . block_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ,
74
- txdata : vec ! [ ] ,
75
- } ;
76
- }
77
-
78
72
for _ in 0 ..* node. network_chan_count . borrow ( ) { // Make sure we don't end up with channels at the same short id by offsetting by chan_count
79
73
block. txdata . push ( Transaction { version : 0 , lock_time : 0 , input : Vec :: new ( ) , output : Vec :: new ( ) } ) ;
80
74
}
81
75
block. txdata . push ( tx. clone ( ) ) ;
82
76
connect_block ( node, & block) ;
83
77
}
84
78
79
+ /// The possible ways we may notify a ChannelManager of a new block
80
+ pub enum ConnectStyle {
81
+ /// Calls update_best_block first, detecting transactions in the block only after receiving the
82
+ /// header and height information.
83
+ BestBlockFirst ,
84
+ /// The same as BestBlockFirst, however when we have multiple blocks to connect, we only
85
+ /// make a single update_best_block call.
86
+ BestBlockFirstSkippingBlocks ,
87
+ /// Calls transactions_confirmed first, detecting transactions in the block before updating the
88
+ /// header and height information.
89
+ TransactionsFirst ,
90
+ /// The same as TransactionsFirst, however when we have multiple blocks to connect, we only
91
+ /// make a single update_best_block call.
92
+ TransactionsFirstSkippingBlocks ,
93
+ /// Provides the full block via the chain::Listen interface. In the current code this is
94
+ /// equivalent to TransactionsFirst with some additional assertions.
95
+ FullBlockViaListen ,
96
+ }
97
+
85
98
pub fn connect_blocks < ' a , ' b , ' c , ' d > ( node : & ' a Node < ' b , ' c , ' d > , depth : u32 ) -> BlockHash {
99
+ let skip_intermediaries = match * node. connect_style . borrow ( ) {
100
+ ConnectStyle :: BestBlockFirstSkippingBlocks |ConnectStyle :: TransactionsFirstSkippingBlocks => true ,
101
+ _ => false ,
102
+ } ;
103
+
86
104
let mut block = Block {
87
105
header : BlockHeader { version : 0x2000000 , prev_blockhash : node. best_block_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ,
88
106
txdata : vec ! [ ] ,
89
107
} ;
90
- connect_block ( node, & block) ;
91
- for _ in 2 ..depth + 1 {
108
+ assert ! ( depth >= 1 ) ;
109
+ for _ in 0 ..depth - 1 {
110
+ do_connect_block ( node, & block, skip_intermediaries) ;
92
111
block = Block {
93
112
header : BlockHeader { version : 0x20000000 , prev_blockhash : block. header . block_hash ( ) , merkle_root : Default :: default ( ) , time : 42 , bits : 42 , nonce : 42 } ,
94
113
txdata : vec ! [ ] ,
95
114
} ;
96
- connect_block ( node, & block) ;
97
115
}
116
+ connect_block ( node, & block) ;
98
117
block. header . block_hash ( )
99
118
}
100
119
101
120
pub fn connect_block < ' a , ' b , ' c , ' d > ( node : & ' a Node < ' b , ' c , ' d > , block : & Block ) {
121
+ do_connect_block ( node, block, false ) ;
122
+ }
123
+
124
+ fn do_connect_block < ' a , ' b , ' c , ' d > ( node : & ' a Node < ' b , ' c , ' d > , block : & Block , skip_manager : bool ) {
102
125
let txdata: Vec < _ > = block. txdata . iter ( ) . enumerate ( ) . collect ( ) ;
103
126
let height = node. best_block_info ( ) . 1 + 1 ;
104
127
node. chain_monitor . chain_monitor . block_connected ( & block. header , & txdata, height) ;
105
- node. node . block_connected ( & block, height) ;
128
+ if !skip_manager {
129
+ match * node. connect_style . borrow ( ) {
130
+ ConnectStyle :: BestBlockFirst |ConnectStyle :: BestBlockFirstSkippingBlocks => {
131
+ node. node . update_best_block ( & block. header , height) ;
132
+ node. node . transactions_confirmed ( & block. header , height, & block. txdata . iter ( ) . enumerate ( ) . collect :: < Vec < _ > > ( ) ) ;
133
+ } ,
134
+ ConnectStyle :: TransactionsFirst |ConnectStyle :: TransactionsFirstSkippingBlocks => {
135
+ node. node . transactions_confirmed ( & block. header , height, & block. txdata . iter ( ) . enumerate ( ) . collect :: < Vec < _ > > ( ) ) ;
136
+ node. node . update_best_block ( & block. header , height) ;
137
+ } ,
138
+ ConnectStyle :: FullBlockViaListen => {
139
+ Listen :: block_connected ( node. node , & block, height) ;
140
+ }
141
+ }
142
+ }
106
143
node. node . test_process_background_events ( ) ;
107
144
node. blocks . borrow_mut ( ) . push ( ( block. header , height) ) ;
108
145
}
109
146
110
147
pub fn disconnect_blocks < ' a , ' b , ' c , ' d > ( node : & ' a Node < ' b , ' c , ' d > , count : u32 ) {
111
- for _ in 0 ..count {
148
+ for i in 0 ..count {
112
149
let orig_header = node. blocks . borrow_mut ( ) . pop ( ) . unwrap ( ) ;
113
150
assert ! ( orig_header. 1 > 0 ) ; // Cannot disconnect genesis
151
+ let prev_header = node. blocks . borrow ( ) . last ( ) . unwrap ( ) . clone ( ) ;
152
+
114
153
node. chain_monitor . chain_monitor . block_disconnected ( & orig_header. 0 , orig_header. 1 ) ;
115
- node. node . block_disconnected ( & orig_header. 0 , orig_header. 1 ) ;
154
+ match * node. connect_style . borrow ( ) {
155
+ ConnectStyle :: FullBlockViaListen => {
156
+ Listen :: block_disconnected ( node. node , & orig_header. 0 , orig_header. 1 ) ;
157
+ } ,
158
+ ConnectStyle :: BestBlockFirstSkippingBlocks |ConnectStyle :: TransactionsFirstSkippingBlocks => {
159
+ if i == count - 1 {
160
+ node. node . update_best_block ( & prev_header. 0 , prev_header. 1 ) ;
161
+ }
162
+ } ,
163
+ _ => {
164
+ node. node . update_best_block ( & prev_header. 0 , prev_header. 1 ) ;
165
+ } ,
166
+ }
116
167
}
117
168
}
118
169
@@ -152,6 +203,7 @@ pub struct Node<'a, 'b: 'a, 'c: 'b> {
152
203
pub network_chan_count : Rc < RefCell < u32 > > ,
153
204
pub logger : & ' c test_utils:: TestLogger ,
154
205
pub blocks : RefCell < Vec < ( BlockHeader , u32 ) > > ,
206
+ pub connect_style : Rc < RefCell < ConnectStyle > > ,
155
207
}
156
208
impl < ' a , ' b , ' c > Node < ' a , ' b , ' c > {
157
209
pub fn best_block_hash ( & self ) -> BlockHash {
@@ -1224,6 +1276,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
1224
1276
let mut nodes = Vec :: new ( ) ;
1225
1277
let chan_count = Rc :: new ( RefCell :: new ( 0 ) ) ;
1226
1278
let payment_count = Rc :: new ( RefCell :: new ( 0 ) ) ;
1279
+ let connect_style = Rc :: new ( RefCell :: new ( ConnectStyle :: FullBlockViaListen ) ) ;
1227
1280
1228
1281
for i in 0 ..node_count {
1229
1282
let net_graph_msg_handler = NetGraphMsgHandler :: new ( cfgs[ i] . chain_source . genesis_hash , None , cfgs[ i] . logger ) ;
@@ -1232,7 +1285,8 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
1232
1285
keys_manager : & cfgs[ i] . keys_manager , node : & chan_mgrs[ i] , net_graph_msg_handler,
1233
1286
node_seed : cfgs[ i] . node_seed , network_chan_count : chan_count. clone ( ) ,
1234
1287
network_payment_count : payment_count. clone ( ) , logger : cfgs[ i] . logger ,
1235
- blocks : RefCell :: new ( vec ! [ ( genesis_block( Network :: Testnet ) . header, 0 ) ] )
1288
+ blocks : RefCell :: new ( vec ! [ ( genesis_block( Network :: Testnet ) . header, 0 ) ] ) ,
1289
+ connect_style : Rc :: clone ( & connect_style) ,
1236
1290
} )
1237
1291
}
1238
1292
0 commit comments