@@ -1102,6 +1102,17 @@ impl<T: Read + Write> ElectrumApi for RawClient<T> {
1102
1102
Ok ( serde_json:: from_value ( result) ?)
1103
1103
}
1104
1104
1105
+ fn batch_transaction_get_merkle < ' s , I > (
1106
+ & self ,
1107
+ txids_and_hashes : I ,
1108
+ ) -> Result < Vec < GetMerkleRes > , Error >
1109
+ where
1110
+ I : IntoIterator + Clone ,
1111
+ I :: Item : Borrow < & ' s ( Txid , usize ) > ,
1112
+ {
1113
+ impl_batch_call ! ( self , txids_and_hashes, transaction_get_merkle)
1114
+ }
1115
+
1105
1116
fn txid_from_pos ( & self , height : usize , tx_pos : usize ) -> Result < Txid , Error > {
1106
1117
let params = vec ! [ Param :: Usize ( height) , Param :: Usize ( tx_pos) ] ;
1107
1118
let req = Request :: new_id (
@@ -1448,6 +1459,95 @@ mod test {
1448
1459
) ) ;
1449
1460
}
1450
1461
1462
+ #[ test]
1463
+ fn test_batch_transaction_get_merkle ( ) {
1464
+ use bitcoin:: Txid ;
1465
+
1466
+ let client = RawClient :: new ( get_test_server ( ) , None ) . unwrap ( ) ;
1467
+
1468
+ let txid_1 =
1469
+ Txid :: from_str ( "1f7ff3c407f33eabc8bec7d2cc230948f2249ec8e591bcf6f971ca9366c8788d" )
1470
+ . unwrap ( ) ;
1471
+ let block_height_1 = 630000 ;
1472
+
1473
+ let merkle_1_pos = 68 ;
1474
+ let merkle_1_bytes = [
1475
+ 34 , 65 , 51 , 64 , 49 , 139 , 115 , 189 , 185 , 246 , 70 , 225 , 168 , 193 , 217 , 195 , 47 , 66 , 179 ,
1476
+ 240 , 153 , 24 , 114 , 215 , 144 , 196 , 212 , 41 , 39 , 155 , 246 , 25 ,
1477
+ ] ;
1478
+
1479
+ let txid_2 =
1480
+ Txid :: from_str ( "70a8639bc9b743c0610d1231103a2f8e99f4a25670946b91f16c55a5373b37d1" )
1481
+ . unwrap ( ) ;
1482
+ let block_height_2 = 630001 ;
1483
+
1484
+ let merkle_2_pos = 25 ;
1485
+ let merkle_2_bytes = [
1486
+ 169 , 100 , 34 , 99 , 168 , 101 , 25 , 168 , 184 , 90 , 77 , 50 , 151 , 245 , 130 , 101 , 193 , 229 ,
1487
+ 136 , 128 , 63 , 110 , 241 , 19 , 242 , 59 , 184 , 137 , 245 , 249 , 188 , 110 ,
1488
+ ] ;
1489
+
1490
+ let txid_3 =
1491
+ Txid :: from_str ( "a0db149ace545beabbd87a8d6b20ffd6aa3b5a50e58add49a3d435f898c272cf" )
1492
+ . unwrap ( ) ;
1493
+ let block_height_3 = 840000 ;
1494
+
1495
+ let merkle_3_pos = 0 ;
1496
+ let merkle_3_bytes = [
1497
+ 43 , 184 , 95 , 75 , 0 , 75 , 230 , 218 , 84 , 247 , 102 , 193 , 124 , 30 , 133 , 81 , 135 , 50 , 113 ,
1498
+ 18 , 194 , 49 , 239 , 47 , 243 , 94 , 186 , 208 , 234 , 103 , 198 , 158 ,
1499
+ ] ;
1500
+
1501
+ let txids_and_heights = vec ! [
1502
+ ( txid_1, block_height_1) ,
1503
+ ( txid_2, block_height_2) ,
1504
+ ( txid_3, block_height_3) ,
1505
+ ] ;
1506
+ let resp = client
1507
+ . batch_transaction_get_merkle ( & txids_and_heights)
1508
+ . unwrap ( ) ;
1509
+
1510
+ assert_eq ! ( resp[ 0 ] . block_height, block_height_1) ;
1511
+ assert_eq ! ( resp[ 0 ] . pos, merkle_1_pos) ;
1512
+ assert_eq ! ( resp[ 0 ] . merkle. len( ) , 12 ) ;
1513
+ assert_eq ! ( resp[ 0 ] . merkle[ 0 ] , merkle_1_bytes) ;
1514
+
1515
+ assert_eq ! ( resp[ 1 ] . block_height, block_height_2) ;
1516
+ assert_eq ! ( resp[ 1 ] . pos, merkle_2_pos) ;
1517
+ assert_eq ! ( resp[ 1 ] . merkle. len( ) , 12 ) ;
1518
+ assert_eq ! ( resp[ 1 ] . merkle[ 0 ] , merkle_2_bytes) ;
1519
+
1520
+ assert_eq ! ( resp[ 2 ] . block_height, block_height_3) ;
1521
+ assert_eq ! ( resp[ 2 ] . pos, merkle_3_pos) ;
1522
+ assert_eq ! ( resp[ 2 ] . merkle. len( ) , 12 ) ;
1523
+ assert_eq ! ( resp[ 2 ] . merkle[ 0 ] , merkle_3_bytes) ;
1524
+
1525
+ for ( i, res) in resp. iter ( ) . enumerate ( ) {
1526
+ // Check we can verify the merkle proof validity, but fail if we supply wrong data.
1527
+ let block_header = client. block_header ( res. block_height ) . unwrap ( ) ;
1528
+ assert ! ( utils:: validate_merkle_proof(
1529
+ & txids_and_heights[ i] . 0 ,
1530
+ & block_header. merkle_root,
1531
+ & res
1532
+ ) ) ;
1533
+
1534
+ let mut fail_res = res. clone ( ) ;
1535
+ fail_res. pos = 13 ;
1536
+ assert ! ( !utils:: validate_merkle_proof(
1537
+ & txids_and_heights[ i] . 0 ,
1538
+ & block_header. merkle_root,
1539
+ & fail_res
1540
+ ) ) ;
1541
+
1542
+ let fail_block_header = client. block_header ( res. block_height + 1 ) . unwrap ( ) ;
1543
+ assert ! ( !utils:: validate_merkle_proof(
1544
+ & txids_and_heights[ i] . 0 ,
1545
+ & fail_block_header. merkle_root,
1546
+ & res
1547
+ ) ) ;
1548
+ }
1549
+ }
1550
+
1451
1551
#[ test]
1452
1552
fn test_txid_from_pos ( ) {
1453
1553
use bitcoin:: Txid ;
0 commit comments