@@ -7,155 +7,9 @@ use bdk_chain::{
77 local_chain:: { self , CheckPoint , LocalChain } ,
88 Append , BlockId , IndexedTxGraph , SpkTxOutIndex ,
99} ;
10- use bitcoin:: {
11- address:: NetworkChecked , block:: Header , hash_types:: TxMerkleNode , hashes:: Hash ,
12- secp256k1:: rand:: random, Block , CompactTarget , OutPoint , ScriptBuf , ScriptHash , Transaction ,
13- TxIn , TxOut , WScriptHash ,
14- } ;
15- use bitcoincore_rpc:: {
16- bitcoincore_rpc_json:: { GetBlockTemplateModes , GetBlockTemplateRules } ,
17- RpcApi ,
18- } ;
19-
20- struct TestEnv {
21- #[ allow( dead_code) ]
22- daemon : bitcoind:: BitcoinD ,
23- client : bitcoincore_rpc:: Client ,
24- }
25-
26- impl TestEnv {
27- fn new ( ) -> anyhow:: Result < Self > {
28- let daemon = match std:: env:: var_os ( "TEST_BITCOIND" ) {
29- Some ( bitcoind_path) => bitcoind:: BitcoinD :: new ( bitcoind_path) ,
30- None => bitcoind:: BitcoinD :: from_downloaded ( ) ,
31- } ?;
32- let client = bitcoincore_rpc:: Client :: new (
33- & daemon. rpc_url ( ) ,
34- bitcoincore_rpc:: Auth :: CookieFile ( daemon. params . cookie_file . clone ( ) ) ,
35- ) ?;
36- Ok ( Self { daemon, client } )
37- }
38-
39- fn mine_blocks (
40- & self ,
41- count : usize ,
42- address : Option < Address > ,
43- ) -> anyhow:: Result < Vec < BlockHash > > {
44- let coinbase_address = match address {
45- Some ( address) => address,
46- None => self . client . get_new_address ( None , None ) ?. assume_checked ( ) ,
47- } ;
48- let block_hashes = self
49- . client
50- . generate_to_address ( count as _ , & coinbase_address) ?;
51- Ok ( block_hashes)
52- }
53-
54- fn mine_empty_block ( & self ) -> anyhow:: Result < ( usize , BlockHash ) > {
55- let bt = self . client . get_block_template (
56- GetBlockTemplateModes :: Template ,
57- & [ GetBlockTemplateRules :: SegWit ] ,
58- & [ ] ,
59- ) ?;
60-
61- let txdata = vec ! [ Transaction {
62- version: 1 ,
63- lock_time: bitcoin:: absolute:: LockTime :: from_height( 0 ) ?,
64- input: vec![ TxIn {
65- previous_output: bitcoin:: OutPoint :: default ( ) ,
66- script_sig: ScriptBuf :: builder( )
67- . push_int( bt. height as _)
68- // randomn number so that re-mining creates unique block
69- . push_int( random( ) )
70- . into_script( ) ,
71- sequence: bitcoin:: Sequence :: default ( ) ,
72- witness: bitcoin:: Witness :: new( ) ,
73- } ] ,
74- output: vec![ TxOut {
75- value: 0 ,
76- script_pubkey: ScriptBuf :: new_p2sh( & ScriptHash :: all_zeros( ) ) ,
77- } ] ,
78- } ] ;
79-
80- let bits: [ u8 ; 4 ] = bt
81- . bits
82- . clone ( )
83- . try_into ( )
84- . expect ( "rpc provided us with invalid bits" ) ;
85-
86- let mut block = Block {
87- header : Header {
88- version : bitcoin:: block:: Version :: default ( ) ,
89- prev_blockhash : bt. previous_block_hash ,
90- merkle_root : TxMerkleNode :: all_zeros ( ) ,
91- time : Ord :: max ( bt. min_time , std:: time:: UNIX_EPOCH . elapsed ( ) ?. as_secs ( ) ) as u32 ,
92- bits : CompactTarget :: from_consensus ( u32:: from_be_bytes ( bits) ) ,
93- nonce : 0 ,
94- } ,
95- txdata,
96- } ;
97-
98- block. header . merkle_root = block. compute_merkle_root ( ) . expect ( "must compute" ) ;
99-
100- for nonce in 0 ..=u32:: MAX {
101- block. header . nonce = nonce;
102- if block. header . target ( ) . is_met_by ( block. block_hash ( ) ) {
103- break ;
104- }
105- }
106-
107- self . client . submit_block ( & block) ?;
108- Ok ( ( bt. height as usize , block. block_hash ( ) ) )
109- }
110-
111- fn invalidate_blocks ( & self , count : usize ) -> anyhow:: Result < ( ) > {
112- let mut hash = self . client . get_best_block_hash ( ) ?;
113- for _ in 0 ..count {
114- let prev_hash = self . client . get_block_info ( & hash) ?. previousblockhash ;
115- self . client . invalidate_block ( & hash) ?;
116- match prev_hash {
117- Some ( prev_hash) => hash = prev_hash,
118- None => break ,
119- }
120- }
121- Ok ( ( ) )
122- }
123-
124- fn reorg ( & self , count : usize ) -> anyhow:: Result < Vec < BlockHash > > {
125- let start_height = self . client . get_block_count ( ) ?;
126- self . invalidate_blocks ( count) ?;
127-
128- let res = self . mine_blocks ( count, None ) ;
129- assert_eq ! (
130- self . client. get_block_count( ) ?,
131- start_height,
132- "reorg should not result in height change"
133- ) ;
134- res
135- }
136-
137- fn reorg_empty_blocks ( & self , count : usize ) -> anyhow:: Result < Vec < ( usize , BlockHash ) > > {
138- let start_height = self . client . get_block_count ( ) ?;
139- self . invalidate_blocks ( count) ?;
140-
141- let res = ( 0 ..count)
142- . map ( |_| self . mine_empty_block ( ) )
143- . collect :: < Result < Vec < _ > , _ > > ( ) ?;
144- assert_eq ! (
145- self . client. get_block_count( ) ?,
146- start_height,
147- "reorg should not result in height change"
148- ) ;
149- Ok ( res)
150- }
151-
152- fn send ( & self , address : & Address < NetworkChecked > , amount : Amount ) -> anyhow:: Result < Txid > {
153- let txid = self
154- . client
155- . send_to_address ( address, amount, None , None , None , None , None , None ) ?;
156- Ok ( txid)
157- }
158- }
10+ use bitcoin:: { hashes:: Hash , Block , OutPoint , ScriptBuf , WScriptHash } ;
11+ use bitcoincore_rpc:: RpcApi ;
12+ use testenv:: TestEnv ;
15913
16014fn block_to_chain_update ( block : & bitcoin:: Block , height : u32 ) -> local_chain:: Update {
16115 let this_id = BlockId {
0 commit comments