@@ -15,32 +15,42 @@ use bdk::{
15
15
} ;
16
16
use jsonrpsee:: { core:: async_trait, proc_macros:: rpc, server:: Server , types:: ErrorObjectOwned } ;
17
17
use log:: info;
18
- use protocol:: { bitcoin, bitcoin:: {
19
- bip32:: Xpriv ,
20
- Network :: { Regtest , Testnet } ,
21
- OutPoint ,
22
- } , constants:: ChainAnchor , hasher:: { BaseHash , KeyHasher , SpaceKey } , prepare:: DataSource , slabel:: SLabel , validate:: TxChangeSet , Bytes , FullSpaceOut , SpaceOut } ;
18
+ use protocol:: bitcoin:: secp256k1;
19
+ use protocol:: {
20
+ bitcoin,
21
+ bitcoin:: {
22
+ bip32:: Xpriv ,
23
+ Network :: { Regtest , Testnet } ,
24
+ OutPoint ,
25
+ } ,
26
+ constants:: ChainAnchor ,
27
+ hasher:: { BaseHash , KeyHasher , SpaceKey } ,
28
+ prepare:: DataSource ,
29
+ slabel:: SLabel ,
30
+ validate:: TxChangeSet ,
31
+ Bytes , FullSpaceOut , SpaceOut ,
32
+ } ;
23
33
use serde:: { Deserialize , Serialize } ;
24
34
use tokio:: {
25
35
select,
26
36
sync:: { broadcast, mpsc, oneshot, RwLock } ,
27
37
task:: JoinSet ,
28
38
} ;
29
- use protocol:: bitcoin:: secp256k1;
30
- use wallet:: { bdk_wallet as bdk, bdk_wallet:: template:: Bip86 , bitcoin:: hashes:: Hash , export:: WalletExport , Balance , DoubleUtxo , Listing , SpacesWallet , WalletConfig , WalletDescriptors , WalletInfo , WalletOutput } ;
39
+ use wallet:: {
40
+ bdk_wallet as bdk, bdk_wallet:: template:: Bip86 , bitcoin:: hashes:: Hash , export:: WalletExport ,
41
+ Balance , DoubleUtxo , Listing , SpacesWallet , WalletConfig , WalletDescriptors , WalletInfo ,
42
+ WalletOutput ,
43
+ } ;
31
44
45
+ use crate :: wallets:: ListSpacesResponse ;
32
46
use crate :: {
33
47
checker:: TxChecker ,
34
48
config:: ExtendedNetwork ,
35
49
node:: { BlockMeta , TxEntry } ,
36
50
source:: BitcoinRpc ,
37
51
store:: { ChainState , LiveSnapshot , RolloutEntry , Sha256 } ,
38
- wallets:: {
39
- AddressKind , RpcWallet , TxInfo , TxResponse , WalletCommand ,
40
- WalletResponse ,
41
- } ,
52
+ wallets:: { AddressKind , RpcWallet , TxInfo , TxResponse , WalletCommand , WalletResponse } ,
42
53
} ;
43
- use crate :: wallets:: ListSpacesResponse ;
44
54
45
55
pub ( crate ) type Responder < T > = oneshot:: Sender < T > ;
46
56
@@ -65,7 +75,7 @@ pub enum BlockIdentifier {
65
75
impl < ' de > Deserialize < ' de > for BlockIdentifier {
66
76
fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
67
77
where
68
- D : serde:: Deserializer < ' de >
78
+ D : serde:: Deserializer < ' de > ,
69
79
{
70
80
#[ derive( Deserialize ) ]
71
81
#[ serde( untagged) ]
@@ -74,11 +84,9 @@ impl<'de> Deserialize<'de> for BlockIdentifier {
74
84
Number ( u32 ) ,
75
85
}
76
86
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
- }
87
+ RawIdentifier :: String ( s) => BlockHash :: from_str ( & s)
88
+ . map ( BlockIdentifier :: Hash )
89
+ . map_err ( serde:: de:: Error :: custom) ,
82
90
RawIdentifier :: Number ( n) => Ok ( BlockIdentifier :: Height ( n) ) ,
83
91
}
84
92
}
@@ -111,7 +119,7 @@ pub enum ChainStateCommand {
111
119
} ,
112
120
GetBlockMeta {
113
121
block_identifier : BlockIdentifier ,
114
- resp : Responder < anyhow:: Result < Option < BlockMeta > > > ,
122
+ resp : Responder < anyhow:: Result < BlockMeta > > ,
115
123
} ,
116
124
EstimateBid {
117
125
target : usize ,
@@ -172,7 +180,7 @@ pub trait Rpc {
172
180
async fn get_block_meta (
173
181
& self ,
174
182
block_identifier : BlockIdentifier ,
175
- ) -> Result < Option < BlockMeta > , ErrorObjectOwned > ;
183
+ ) -> Result < BlockMeta , ErrorObjectOwned > ;
176
184
177
185
#[ method( name = "gettxmeta" ) ]
178
186
async fn get_tx_meta ( & self , txid : Txid ) -> Result < Option < TxEntry > , ErrorObjectOwned > ;
@@ -187,7 +195,12 @@ pub trait Rpc {
187
195
async fn verify_message ( & self , msg : SignedMessage ) -> Result < ( ) , ErrorObjectOwned > ;
188
196
189
197
#[ method( name = "walletsignmessage" ) ]
190
- async fn wallet_sign_message ( & self , wallet : & str , space : & str , msg : protocol:: Bytes ) -> Result < SignedMessage , ErrorObjectOwned > ;
198
+ async fn wallet_sign_message (
199
+ & self ,
200
+ wallet : & str ,
201
+ space : & str ,
202
+ msg : protocol:: Bytes ,
203
+ ) -> Result < SignedMessage , ErrorObjectOwned > ;
191
204
192
205
#[ method( name = "walletgetinfo" ) ]
193
206
async fn wallet_get_info ( & self , name : & str ) -> Result < WalletInfo , ErrorObjectOwned > ;
@@ -239,10 +252,7 @@ pub trait Rpc {
239
252
) -> Result < Listing , ErrorObjectOwned > ;
240
253
241
254
#[ method( name = "verifylisting" ) ]
242
- async fn verify_listing (
243
- & self ,
244
- listing : Listing ,
245
- ) -> Result < ( ) , ErrorObjectOwned > ;
255
+ async fn verify_listing ( & self , listing : Listing ) -> Result < ( ) , ErrorObjectOwned > ;
246
256
247
257
#[ method( name = "walletlisttransactions" ) ]
248
258
async fn wallet_list_transactions (
@@ -261,8 +271,10 @@ pub trait Rpc {
261
271
) -> Result < TxResponse , ErrorObjectOwned > ;
262
272
263
273
#[ method( name = "walletlistspaces" ) ]
264
- async fn wallet_list_spaces ( & self , wallet : & str )
265
- -> Result < ListSpacesResponse , ErrorObjectOwned > ;
274
+ async fn wallet_list_spaces (
275
+ & self ,
276
+ wallet : & str ,
277
+ ) -> Result < ListSpacesResponse , ErrorObjectOwned > ;
266
278
267
279
#[ method( name = "walletlistunspent" ) ]
268
280
async fn wallet_list_unspent (
@@ -704,7 +716,7 @@ impl RpcServer for RpcServerImpl {
704
716
async fn get_block_meta (
705
717
& self ,
706
718
block_identifier : BlockIdentifier ,
707
- ) -> Result < Option < BlockMeta > , ErrorObjectOwned > {
719
+ ) -> Result < BlockMeta , ErrorObjectOwned > {
708
720
let data = self
709
721
. store
710
722
. get_block_meta ( block_identifier)
@@ -806,23 +818,39 @@ impl RpcServer for RpcServerImpl {
806
818
. map_err ( |error| ErrorObjectOwned :: owned ( -1 , error. to_string ( ) , None :: < String > ) )
807
819
}
808
820
809
- async fn wallet_buy ( & self , wallet : & str , listing : Listing , fee_rate : Option < FeeRate > , skip_tx_check : bool ) -> Result < TxResponse , ErrorObjectOwned > {
821
+ async fn wallet_buy (
822
+ & self ,
823
+ wallet : & str ,
824
+ listing : Listing ,
825
+ fee_rate : Option < FeeRate > ,
826
+ skip_tx_check : bool ,
827
+ ) -> Result < TxResponse , ErrorObjectOwned > {
810
828
self . wallet ( & wallet)
811
829
. await ?
812
830
. send_buy ( listing, fee_rate, skip_tx_check)
813
831
. await
814
832
. map_err ( |error| ErrorObjectOwned :: owned ( -1 , error. to_string ( ) , None :: < String > ) )
815
833
}
816
834
817
- async fn wallet_sell ( & self , wallet : & str , space : String , amount : u64 ) -> Result < Listing , ErrorObjectOwned > {
835
+ async fn wallet_sell (
836
+ & self ,
837
+ wallet : & str ,
838
+ space : String ,
839
+ amount : u64 ,
840
+ ) -> Result < Listing , ErrorObjectOwned > {
818
841
self . wallet ( & wallet)
819
842
. await ?
820
843
. send_sell ( space, amount)
821
844
. await
822
845
. map_err ( |error| ErrorObjectOwned :: owned ( -1 , error. to_string ( ) , None :: < String > ) )
823
846
}
824
847
825
- async fn wallet_sign_message ( & self , wallet : & str , space : & str , msg : Bytes ) -> Result < SignedMessage , ErrorObjectOwned > {
848
+ async fn wallet_sign_message (
849
+ & self ,
850
+ wallet : & str ,
851
+ space : & str ,
852
+ msg : Bytes ,
853
+ ) -> Result < SignedMessage , ErrorObjectOwned > {
826
854
self . wallet ( & wallet)
827
855
. await ?
828
856
. send_sign_message ( space, msg)
@@ -930,15 +958,19 @@ impl AsyncChainState {
930
958
BlockHash :: from_str ( info. get ( "blockhash" ) . and_then ( |t| t. as_str ( ) ) . ok_or_else (
931
959
|| anyhow ! ( "Could not retrieve block hash for tx (is it in the mempool?)" ) ,
932
960
) ?) ?;
933
- let block = Self :: get_indexed_block ( index, BlockIdentifier :: Hash ( block_hash) , client, rpc, chain_state) . await ?;
961
+ let block = Self :: get_indexed_block (
962
+ index,
963
+ BlockIdentifier :: Hash ( block_hash) ,
964
+ client,
965
+ rpc,
966
+ chain_state,
967
+ )
968
+ . await ?;
934
969
935
- if let Some ( block) = block {
936
- return Ok ( block
937
- . tx_meta
938
- . into_iter ( )
939
- . find ( |tx| & tx. changeset . txid == txid) ) ;
940
- }
941
- Ok ( None )
970
+ Ok ( block
971
+ . tx_meta
972
+ . into_iter ( )
973
+ . find ( |tx| & tx. changeset . txid == txid) )
942
974
}
943
975
944
976
async fn get_indexed_block (
@@ -947,24 +979,24 @@ impl AsyncChainState {
947
979
client : & reqwest:: Client ,
948
980
rpc : & BitcoinRpc ,
949
981
chain_state : & mut LiveSnapshot ,
950
- ) -> Result < Option < BlockMeta > , anyhow:: Error > {
982
+ ) -> Result < BlockMeta , anyhow:: Error > {
951
983
let index = index
952
984
. as_mut ( )
953
985
. ok_or_else ( || anyhow ! ( "block index must be enabled" ) ) ?;
954
986
let block_hash = match block_identifier {
955
987
BlockIdentifier :: Hash ( hash) => hash,
956
988
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) ) ?
989
+ . send_json ( client, & rpc. get_block_hash ( height) )
990
+ . await
991
+ . map_err ( |e| anyhow ! ( "Could not retrieve block hash ({})" , e) ) ?,
960
992
} ;
961
993
let hash = BaseHash :: from_slice ( block_hash. as_ref ( ) ) ;
962
994
let block: Option < BlockMeta > = index
963
995
. get ( hash)
964
996
. context ( "Could not fetch block from index" ) ?;
965
997
966
998
if let Some ( block_set) = block {
967
- return Ok ( Some ( block_set) ) ;
999
+ return Ok ( block_set) ;
968
1000
}
969
1001
970
1002
let info: serde_json:: Value = rpc
@@ -975,17 +1007,21 @@ impl AsyncChainState {
975
1007
let height = info
976
1008
. get ( "height" )
977
1009
. and_then ( |t| t. as_u64 ( ) )
1010
+ . and_then ( |h| u32:: try_from ( h) . ok ( ) )
978
1011
. ok_or_else ( || anyhow ! ( "Could not retrieve block height" ) ) ?;
979
1012
980
1013
let tip = chain_state. tip . read ( ) . expect ( "read meta" ) . clone ( ) ;
981
- if height > tip. height as u64 {
1014
+ if height > tip. height {
982
1015
return Err ( anyhow ! (
983
1016
"Spaces is syncing at height {}, requested block height {}" ,
984
1017
tip. height,
985
1018
height
986
1019
) ) ;
987
1020
}
988
- Ok ( None )
1021
+ Ok ( BlockMeta {
1022
+ height,
1023
+ tx_meta : Vec :: new ( ) ,
1024
+ } )
989
1025
}
990
1026
991
1027
pub async fn handle_command (
@@ -1032,10 +1068,18 @@ impl AsyncChainState {
1032
1068
. context ( "could not fetch spaceout" ) ;
1033
1069
let _ = resp. send ( result) ;
1034
1070
}
1035
- ChainStateCommand :: GetBlockMeta { block_identifier, resp } => {
1036
- let res =
1037
- Self :: get_indexed_block ( block_index, block_identifier, client, rpc, chain_state)
1038
- . await ;
1071
+ ChainStateCommand :: GetBlockMeta {
1072
+ block_identifier,
1073
+ resp,
1074
+ } => {
1075
+ let res = Self :: get_indexed_block (
1076
+ block_index,
1077
+ block_identifier,
1078
+ client,
1079
+ rpc,
1080
+ chain_state,
1081
+ )
1082
+ . await ;
1039
1083
let _ = resp. send ( res) ;
1040
1084
}
1041
1085
ChainStateCommand :: GetTxMeta { txid, resp } => {
@@ -1051,12 +1095,20 @@ impl AsyncChainState {
1051
1095
_ = resp. send ( rollouts) ;
1052
1096
}
1053
1097
ChainStateCommand :: VerifyListing { listing, resp } => {
1054
- _ = resp. send ( SpacesWallet :: verify_listing :: < Sha256 > ( chain_state, & listing) . map ( |_| ( ) ) ) ;
1098
+ _ = resp. send (
1099
+ SpacesWallet :: verify_listing :: < Sha256 > ( chain_state, & listing) . map ( |_| ( ) ) ,
1100
+ ) ;
1055
1101
}
1056
1102
ChainStateCommand :: VerifyMessage { msg, resp } => {
1057
- _ = resp. send ( SpacesWallet :: verify_message :: < Sha256 > (
1058
- chain_state, & msg. space , msg. message . as_slice ( ) , & msg. signature
1059
- ) . map ( |_| ( ) ) ) ;
1103
+ _ = resp. send (
1104
+ SpacesWallet :: verify_message :: < Sha256 > (
1105
+ chain_state,
1106
+ & msg. space ,
1107
+ msg. message . as_slice ( ) ,
1108
+ & msg. signature ,
1109
+ )
1110
+ . map ( |_| ( ) ) ,
1111
+ ) ;
1060
1112
}
1061
1113
}
1062
1114
}
@@ -1156,10 +1208,16 @@ impl AsyncChainState {
1156
1208
resp_rx. await ?
1157
1209
}
1158
1210
1159
- pub async fn get_block_meta ( & self , block_identifier : BlockIdentifier ) -> anyhow:: Result < Option < BlockMeta > > {
1211
+ pub async fn get_block_meta (
1212
+ & self ,
1213
+ block_identifier : BlockIdentifier ,
1214
+ ) -> anyhow:: Result < BlockMeta > {
1160
1215
let ( resp, resp_rx) = oneshot:: channel ( ) ;
1161
1216
self . sender
1162
- . send ( ChainStateCommand :: GetBlockMeta { block_identifier, resp } )
1217
+ . send ( ChainStateCommand :: GetBlockMeta {
1218
+ block_identifier,
1219
+ resp,
1220
+ } )
1163
1221
. await ?;
1164
1222
resp_rx. await ?
1165
1223
}
0 commit comments