1- use  bitcoind:: bitcoincore_rpc:: RpcApi ; 
1+ use  bitcoin:: hashes:: { sha256,  Hash } ; 
2+ use  bitcoind:: bitcoincore_rpc:: { self ,  RpcApi } ; 
23use  serde_json:: Value ; 
34use  std:: collections:: HashSet ; 
45
@@ -24,23 +25,8 @@ fn test_rest() -> Result<()> {
2425            . into_string ( ) ?) 
2526    } ; 
2627
27-     let  newaddress = || -> Result < Address >  { 
28-         let  addr = tester. node_client ( ) . call :: < Address > ( "getnewaddress" ,  & [ ] ) ?; 
29-         // On Liquid, return the unconfidential address, so that the tests below work 
30-         // on both Bitcoin and Liquid mode. The Liquid-specific functionality, including 
31-         // confidentially, is tested separately below. 
32-         #[ cfg( feature = "liquid" ) ]  
33-         let  addr = { 
34-             let  mut  info = tester
35-                 . node_client ( ) 
36-                 . call :: < Value > ( "getaddressinfo" ,  & [ addr. to_string ( ) . into ( ) ] ) ?; 
37-             serde_json:: from_value ( info[ "unconfidential" ] . take ( ) ) ?
38-         } ; 
39-         Ok ( addr) 
40-     } ; 
41- 
4228    // Send transaction and confirm it 
43-     let  addr1 = newaddress ( ) ?; 
29+     let  addr1 = newaddress ( tester . node_client ( ) ) ?; 
4430    let  txid1_confirmed = tester. send ( & addr1,  "1.19123 BTC" . parse ( ) . unwrap ( ) ) ?; 
4531    tester. mine ( ) ?; 
4632
@@ -183,6 +169,171 @@ fn test_rest() -> Result<()> {
183169    tester. mine ( ) ?; 
184170    assert_eq ! ( get_json( "/mempool" ) ?[ "count" ] . as_u64( ) ,  Some ( 0 ) ) ; 
185171
172+     // Elements-only tests 
173+     #[ cfg( feature = "liquid" ) ]  
174+     { 
175+         // Test confidential transactions 
176+         { 
177+             let  ( c_addr,  uc_addr)  = elements_newaddress ( tester. node_client ( ) ) ?; 
178+             let  txid = tester. send ( & c_addr,  "3.5 BTC" . parse ( ) . unwrap ( ) ) ?; 
179+             tester. mine ( ) ?; 
180+ 
181+             let  tx = get_json ( & format ! ( "/tx/{}" ,  txid) ) ?; 
182+             log:: debug!( "blinded tx = {:#?}" ,  tx) ; 
183+             assert_eq ! ( tx[ "status" ] [ "confirmed" ] . as_bool( ) ,  Some ( true ) ) ; 
184+             let  outs = tx[ "vout" ] . as_array ( ) . expect ( "array of outs" ) ; 
185+             let  vout = outs
186+                 . iter ( ) 
187+                 . find ( |vout| vout[ "scriptpubkey_address" ] . as_str ( )  == Some ( & uc_addr. to_string ( ) ) ) 
188+                 . expect ( "our output" ) ; 
189+             assert ! ( vout[ "value" ] . is_null( ) ) ; 
190+             assert ! ( vout[ "valuecommitment" ] . is_string( ) ) ; 
191+             assert ! ( vout[ "assetcommitment" ] . is_string( ) ) ; 
192+         } 
193+ 
194+         // Test blinded asset issuance 
195+         { 
196+             let  contract_hash = sha256:: Hash :: hash ( & [ 0x11 ,  0x22 ,  0x33 ,  0x44 ] ) . to_string ( ) ; 
197+             let  contract_hash = contract_hash. as_str ( ) ; 
198+             let  issuance = tester. node_client ( ) . call :: < Value > ( 
199+                 "issueasset" , 
200+                 & [ 1.5 . into ( ) ,  0 . into ( ) ,  true . into ( ) ,  contract_hash. into ( ) ] , 
201+             ) ?; 
202+             tester. mine ( ) ?; 
203+ 
204+             let  assetid = issuance[ "asset" ] . as_str ( ) . expect ( "asset id" ) ; 
205+             let  issuance_txid = issuance[ "txid" ] . as_str ( ) . expect ( "issuance txid" ) ; 
206+ 
207+             // Test GET /tx/:txid for issuance tx 
208+             let  asset = get_json ( & format ! ( "/asset/{}" ,  assetid) ) ?; 
209+             let  stats = & asset[ "chain_stats" ] ; 
210+             assert_eq ! ( asset[ "asset_id" ] . as_str( ) ,  Some ( assetid) ) ; 
211+             assert_eq ! ( asset[ "issuance_txin" ] [ "txid" ] . as_str( ) ,  Some ( issuance_txid) ) ; 
212+             assert_eq ! ( asset[ "contract_hash" ] . as_str( ) ,  Some ( contract_hash) ) ; 
213+             assert_eq ! ( asset[ "status" ] [ "confirmed" ] . as_bool( ) ,  Some ( true ) ) ; 
214+             assert_eq ! ( stats[ "issuance_count" ] . as_u64( ) ,  Some ( 1 ) ) ; 
215+             assert_eq ! ( stats[ "has_blinded_issuances" ] . as_bool( ) ,  Some ( true ) ) ; 
216+             assert_eq ! ( stats[ "issued_amount" ] . as_u64( ) ,  Some ( 0 ) ) ; 
217+ 
218+             // Test GET /asset/:assetid 
219+             let  issuance_tx = get_json ( & format ! ( "/tx/{}" ,  issuance_txid) ) ?; 
220+             let  issuance_in_index = asset[ "issuance_txin" ] [ "vin" ] . as_u64 ( ) . unwrap ( ) ; 
221+             let  issuance_in = & issuance_tx[ "vin" ] [ issuance_in_index as  usize ] ; 
222+             let  issuance_data = & issuance_in[ "issuance" ] ; 
223+             assert_eq ! ( issuance_data[ "asset_id" ] . as_str( ) ,  Some ( assetid) ) ; 
224+             assert_eq ! ( issuance_data[ "is_reissuance" ] . as_bool( ) ,  Some ( false ) ) ; 
225+             assert_eq ! ( issuance_data[ "contract_hash" ] . as_str( ) ,  Some ( contract_hash) ) ; 
226+             assert ! ( issuance_data[ "assetamount" ] . is_null( ) ) ; 
227+             assert ! ( issuance_data[ "assetamountcommitment" ] . is_string( ) ) ; 
228+         } 
229+ 
230+         // Test unblinded asset issuance 
231+         { 
232+             let  issuance = tester
233+                 . node_client ( ) 
234+                 . call :: < Value > ( "issueasset" ,  & [ 1.5 . into ( ) ,  0 . into ( ) ,  false . into ( ) ] ) ?; 
235+             tester. mine ( ) ?; 
236+             let  assetid = issuance[ "asset" ] . as_str ( ) . expect ( "asset id" ) ; 
237+             let  issuance_txid = issuance[ "txid" ] . as_str ( ) . expect ( "issuance txid" ) ; 
238+ 
239+             // Test GET /tx/:txid for issuance tx 
240+             let  asset = get_json ( & format ! ( "/asset/{}" ,  assetid) ) ?; 
241+             let  stats = & asset[ "chain_stats" ] ; 
242+             assert_eq ! ( stats[ "has_blinded_issuances" ] . as_bool( ) ,  Some ( false ) ) ; 
243+             assert_eq ! ( stats[ "issued_amount" ] . as_u64( ) ,  Some ( 150000000 ) ) ; 
244+ 
245+             // Test GET /asset/:assetid 
246+             let  issuance_tx = get_json ( & format ! ( "/tx/{}" ,  issuance_txid) ) ?; 
247+             let  issuance_in_index = asset[ "issuance_txin" ] [ "vin" ] . as_u64 ( ) . unwrap ( ) ; 
248+             let  issuance_in = & issuance_tx[ "vin" ] [ issuance_in_index as  usize ] ; 
249+             let  issuance_data = & issuance_in[ "issuance" ] ; 
250+             assert_eq ! ( issuance_data[ "assetamount" ] . as_u64( ) ,  Some ( 150000000 ) ) ; 
251+             assert ! ( issuance_data[ "assetamountcommitment" ] . is_null( ) ) ; 
252+         } 
253+ 
254+         // Test a regular (non-issuance) transaction sending an issued asset 
255+         { 
256+             let  issuance = tester
257+                 . node_client ( ) 
258+                 . call :: < Value > ( "issueasset" ,  & [ 1.5 . into ( ) ,  0 . into ( ) ,  false . into ( ) ] ) ?; 
259+             let  assetid = issuance[ "asset" ] . as_str ( ) . expect ( "asset id" ) ; 
260+             tester. mine ( ) ?; 
261+ 
262+             let  ( c_addr,  uc_addr)  = elements_newaddress ( tester. node_client ( ) ) ?; 
263+ 
264+             // With blinding off 
265+             let  txid = tester. send_asset ( 
266+                 & uc_addr, 
267+                 "0.3 BTC" . parse ( ) . unwrap ( ) ,  // not actually BTC, but this is what Amount expects 
268+                 assetid. parse ( ) . unwrap ( ) , 
269+             ) ?; 
270+             let  tx = get_json ( & format ! ( "/tx/{}" ,  txid) ) ?; 
271+             let  outs = tx[ "vout" ] . as_array ( ) . expect ( "array of outs" ) ; 
272+             let  vout = outs
273+                 . iter ( ) 
274+                 . find ( |vout| vout[ "scriptpubkey_address" ] . as_str ( )  == Some ( & uc_addr. to_string ( ) ) ) 
275+                 . expect ( "our output" ) ; 
276+             assert_eq ! ( vout[ "asset" ] . as_str( ) ,  Some ( assetid) ) ; 
277+             assert_eq ! ( vout[ "value" ] . as_u64( ) ,  Some ( 30000000 ) ) ; 
278+ 
279+             // With blinding on 
280+             let  txid = tester. send_asset ( 
281+                 & c_addr, 
282+                 "0.3 BTC" . parse ( ) . unwrap ( ) , 
283+                 assetid. parse ( ) . unwrap ( ) , 
284+             ) ?; 
285+             let  tx = get_json ( & format ! ( "/tx/{}" ,  txid) ) ?; 
286+             let  outs = tx[ "vout" ] . as_array ( ) . expect ( "array of outs" ) ; 
287+             let  vout = outs
288+                 . iter ( ) 
289+                 . find ( |vout| vout[ "scriptpubkey_address" ] . as_str ( )  == Some ( & uc_addr. to_string ( ) ) ) 
290+                 . expect ( "our output" ) ; 
291+             assert ! ( vout[ "asset" ] . is_null( ) ) ; 
292+             assert ! ( vout[ "value" ] . is_null( ) ) ; 
293+             assert ! ( vout[ "assetcommitment" ] . is_string( ) ) ; 
294+             assert ! ( vout[ "valuecommitment" ] . is_string( ) ) ; 
295+         } 
296+ 
297+         // Test GET /block/:hash 
298+         { 
299+             let  bestblockhash = get_plain ( "/blocks/tip/hash" ) ?; 
300+             let  block = get_json ( & format ! ( "/block/{}" ,  bestblockhash) ) ?; 
301+ 
302+             // No PoW-related stuff 
303+             assert ! ( block[ "bits" ] . is_null( ) ) ; 
304+             assert ! ( block[ "nonce" ] . is_null( ) ) ; 
305+             assert ! ( block[ "difficulty" ] . is_null( ) ) ; 
306+ 
307+             // Dynamic Federations (dynafed) fields 
308+             assert ! ( block[ "ext" ] [ "current" ] [ "signblockscript" ] . is_string( ) ) ; 
309+             assert ! ( block[ "ext" ] [ "current" ] [ "fedpegscript" ] . is_string( ) ) ; 
310+             assert ! ( block[ "ext" ] [ "current" ] [ "fedpeg_program" ] . is_string( ) ) ; 
311+             assert ! ( block[ "ext" ] [ "current" ] [ "signblock_witness_limit" ] . is_u64( ) ) ; 
312+             assert ! ( block[ "ext" ] [ "current" ] [ "extension_space" ] . is_array( ) ) ; 
313+             assert ! ( block[ "ext" ] [ "proposed" ] . is_object( ) ) ; 
314+             assert ! ( block[ "ext" ] [ "signblock_witness" ] . is_array( ) ) ; 
315+         } 
316+     } 
317+ 
186318    rest_handle. stop ( ) ; 
187319    Ok ( ( ) ) 
188320} 
321+ 
322+ fn  newaddress ( client :  & bitcoincore_rpc:: Client )  -> Result < Address >  { 
323+     #[ cfg( not( feature = "liquid" ) ) ]  
324+     return  Ok ( client. get_new_address ( None ,  None ) ?) ; 
325+ 
326+     // Return the unconfidential address on Liquid, so that the tests below work 
327+     // on both Bitcoin and Liquid mode. The Liquid-specific functionality, including 
328+     // confidentially, is tested separately below. 
329+     #[ cfg( feature = "liquid" ) ]  
330+     return  Ok ( elements_newaddress ( client) ?. 1 ) ; 
331+ } 
332+ 
333+ #[ cfg( feature = "liquid" ) ]  
334+ fn  elements_newaddress ( client :  & bitcoincore_rpc:: Client )  -> Result < ( Address ,  Address ) >  { 
335+     let  c_addr = client. call :: < Address > ( "getnewaddress" ,  & [ ] ) ?; 
336+     let  mut  info = client. call :: < Value > ( "getaddressinfo" ,  & [ c_addr. to_string ( ) . into ( ) ] ) ?; 
337+     let  uc_addr = serde_json:: from_value ( info[ "unconfidential" ] . take ( ) ) ?; 
338+     Ok ( ( c_addr,  uc_addr) ) 
339+ } 
0 commit comments