@@ -57,6 +57,33 @@ pub struct SignedMessage {
57
57
pub signature : secp256k1:: schnorr:: Signature ,
58
58
}
59
59
60
+ #[ derive( Debug , Serialize ) ]
61
+ pub enum BlockIdentifier {
62
+ Hash ( BlockHash ) ,
63
+ Height ( u32 ) ,
64
+ }
65
+ impl < ' de > Deserialize < ' de > for BlockIdentifier {
66
+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
67
+ where
68
+ D : serde:: Deserializer < ' de >
69
+ {
70
+ #[ derive( Deserialize ) ]
71
+ #[ serde( untagged) ]
72
+ enum RawIdentifier {
73
+ String ( String ) ,
74
+ Number ( u32 ) ,
75
+ }
76
+ match RawIdentifier :: deserialize ( deserializer) ? {
77
+ RawIdentifier :: String ( s) => {
78
+ BlockHash :: from_str ( & s)
79
+ . map ( BlockIdentifier :: Hash )
80
+ . map_err ( serde:: de:: Error :: custom)
81
+ }
82
+ RawIdentifier :: Number ( n) => Ok ( BlockIdentifier :: Height ( n) ) ,
83
+ }
84
+ }
85
+ }
86
+
60
87
pub enum ChainStateCommand {
61
88
CheckPackage {
62
89
txs : Vec < String > ,
@@ -83,7 +110,7 @@ pub enum ChainStateCommand {
83
110
resp : Responder < anyhow:: Result < Option < TxEntry > > > ,
84
111
} ,
85
112
GetBlockMeta {
86
- block_hash : BlockHash ,
113
+ block_identifier : BlockIdentifier ,
87
114
resp : Responder < anyhow:: Result < Option < BlockMeta > > > ,
88
115
} ,
89
116
EstimateBid {
@@ -144,7 +171,7 @@ pub trait Rpc {
144
171
#[ method( name = "getblockmeta" ) ]
145
172
async fn get_block_meta (
146
173
& self ,
147
- block_hash : BlockHash ,
174
+ block_identifier : BlockIdentifier ,
148
175
) -> Result < Option < BlockMeta > , ErrorObjectOwned > ;
149
176
150
177
#[ method( name = "gettxmeta" ) ]
@@ -502,19 +529,6 @@ impl WalletManager {
502
529
Ok ( ( ) )
503
530
}
504
531
505
- pub async fn get_block_hash (
506
- & self ,
507
- client : & reqwest:: Client ,
508
- height : u32 ,
509
- ) -> anyhow:: Result < BlockId > {
510
- let hash = self
511
- . rpc
512
- . send_json ( & client, & self . rpc . get_block_hash ( height) )
513
- . await ?;
514
-
515
- Ok ( BlockId { height, hash } )
516
- }
517
-
518
532
async fn get_wallet_start_block ( & self , client : & reqwest:: Client ) -> anyhow:: Result < BlockId > {
519
533
let count: i32 = self
520
534
. rpc
@@ -689,11 +703,11 @@ impl RpcServer for RpcServerImpl {
689
703
690
704
async fn get_block_meta (
691
705
& self ,
692
- block_hash : BlockHash ,
706
+ block_identifier : BlockIdentifier ,
693
707
) -> Result < Option < BlockMeta > , ErrorObjectOwned > {
694
708
let data = self
695
709
. store
696
- . get_block_meta ( block_hash )
710
+ . get_block_meta ( block_identifier )
697
711
. await
698
712
. map_err ( |error| ErrorObjectOwned :: owned ( -1 , error. to_string ( ) , None :: < String > ) ) ?;
699
713
@@ -916,7 +930,7 @@ impl AsyncChainState {
916
930
BlockHash :: from_str ( info. get ( "blockhash" ) . and_then ( |t| t. as_str ( ) ) . ok_or_else (
917
931
|| anyhow ! ( "Could not retrieve block hash for tx (is it in the mempool?)" ) ,
918
932
) ?) ?;
919
- let block = Self :: get_indexed_block ( index, & block_hash, client, rpc, chain_state) . await ?;
933
+ let block = Self :: get_indexed_block ( index, BlockIdentifier :: Hash ( block_hash) , client, rpc, chain_state) . await ?;
920
934
921
935
if let Some ( block) = block {
922
936
return Ok ( block
@@ -929,14 +943,21 @@ impl AsyncChainState {
929
943
930
944
async fn get_indexed_block (
931
945
index : & mut Option < LiveSnapshot > ,
932
- block_hash : & BlockHash ,
946
+ block_identifier : BlockIdentifier ,
933
947
client : & reqwest:: Client ,
934
948
rpc : & BitcoinRpc ,
935
949
chain_state : & mut LiveSnapshot ,
936
950
) -> Result < Option < BlockMeta > , anyhow:: Error > {
937
951
let index = index
938
952
. as_mut ( )
939
953
. ok_or_else ( || anyhow ! ( "block index must be enabled" ) ) ?;
954
+ let block_hash = match block_identifier {
955
+ BlockIdentifier :: Hash ( hash) => hash,
956
+ BlockIdentifier :: Height ( height) => rpc
957
+ . send_json ( client, & rpc. get_block_hash ( height) )
958
+ . await
959
+ . map_err ( |e| anyhow ! ( "Could not retrieve block hash ({})" , e) ) ?
960
+ } ;
940
961
let hash = BaseHash :: from_slice ( block_hash. as_ref ( ) ) ;
941
962
let block: Option < BlockMeta > = index
942
963
. get ( hash)
@@ -947,7 +968,7 @@ impl AsyncChainState {
947
968
}
948
969
949
970
let info: serde_json:: Value = rpc
950
- . send_json ( client, & rpc. get_block_header ( block_hash) )
971
+ . send_json ( client, & rpc. get_block_header ( & block_hash) )
951
972
. await
952
973
. map_err ( |e| anyhow ! ( "Could not retrieve block ({})" , e) ) ?;
953
974
@@ -1011,9 +1032,9 @@ impl AsyncChainState {
1011
1032
. context ( "could not fetch spaceout" ) ;
1012
1033
let _ = resp. send ( result) ;
1013
1034
}
1014
- ChainStateCommand :: GetBlockMeta { block_hash , resp } => {
1035
+ ChainStateCommand :: GetBlockMeta { block_identifier , resp } => {
1015
1036
let res =
1016
- Self :: get_indexed_block ( block_index, & block_hash , client, rpc, chain_state)
1037
+ Self :: get_indexed_block ( block_index, block_identifier , client, rpc, chain_state)
1017
1038
. await ;
1018
1039
let _ = resp. send ( res) ;
1019
1040
}
@@ -1135,10 +1156,10 @@ impl AsyncChainState {
1135
1156
resp_rx. await ?
1136
1157
}
1137
1158
1138
- pub async fn get_block_meta ( & self , block_hash : BlockHash ) -> anyhow:: Result < Option < BlockMeta > > {
1159
+ pub async fn get_block_meta ( & self , block_identifier : BlockIdentifier ) -> anyhow:: Result < Option < BlockMeta > > {
1139
1160
let ( resp, resp_rx) = oneshot:: channel ( ) ;
1140
1161
self . sender
1141
- . send ( ChainStateCommand :: GetBlockMeta { block_hash , resp } )
1162
+ . send ( ChainStateCommand :: GetBlockMeta { block_identifier , resp } )
1142
1163
. await ?;
1143
1164
resp_rx. await ?
1144
1165
}
0 commit comments