Skip to content

Commit 5e7a7d1

Browse files
committed
getblockmeta: return empty tx_meta instead of null
1 parent 89c450b commit 5e7a7d1

File tree

1 file changed

+114
-56
lines changed

1 file changed

+114
-56
lines changed

node/src/rpc.rs

+114-56
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,42 @@ use bdk::{
1515
};
1616
use jsonrpsee::{core::async_trait, proc_macros::rpc, server::Server, types::ErrorObjectOwned};
1717
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+
};
2333
use serde::{Deserialize, Serialize};
2434
use tokio::{
2535
select,
2636
sync::{broadcast, mpsc, oneshot, RwLock},
2737
task::JoinSet,
2838
};
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+
};
3144

45+
use crate::wallets::ListSpacesResponse;
3246
use crate::{
3347
checker::TxChecker,
3448
config::ExtendedNetwork,
3549
node::{BlockMeta, TxEntry},
3650
source::BitcoinRpc,
3751
store::{ChainState, LiveSnapshot, RolloutEntry, Sha256},
38-
wallets::{
39-
AddressKind, RpcWallet, TxInfo, TxResponse, WalletCommand,
40-
WalletResponse,
41-
},
52+
wallets::{AddressKind, RpcWallet, TxInfo, TxResponse, WalletCommand, WalletResponse},
4253
};
43-
use crate::wallets::ListSpacesResponse;
4454

4555
pub(crate) type Responder<T> = oneshot::Sender<T>;
4656

@@ -65,7 +75,7 @@ pub enum BlockIdentifier {
6575
impl<'de> Deserialize<'de> for BlockIdentifier {
6676
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
6777
where
68-
D: serde::Deserializer<'de>
78+
D: serde::Deserializer<'de>,
6979
{
7080
#[derive(Deserialize)]
7181
#[serde(untagged)]
@@ -74,11 +84,9 @@ impl<'de> Deserialize<'de> for BlockIdentifier {
7484
Number(u32),
7585
}
7686
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),
8290
RawIdentifier::Number(n) => Ok(BlockIdentifier::Height(n)),
8391
}
8492
}
@@ -111,7 +119,7 @@ pub enum ChainStateCommand {
111119
},
112120
GetBlockMeta {
113121
block_identifier: BlockIdentifier,
114-
resp: Responder<anyhow::Result<Option<BlockMeta>>>,
122+
resp: Responder<anyhow::Result<BlockMeta>>,
115123
},
116124
EstimateBid {
117125
target: usize,
@@ -172,7 +180,7 @@ pub trait Rpc {
172180
async fn get_block_meta(
173181
&self,
174182
block_identifier: BlockIdentifier,
175-
) -> Result<Option<BlockMeta>, ErrorObjectOwned>;
183+
) -> Result<BlockMeta, ErrorObjectOwned>;
176184

177185
#[method(name = "gettxmeta")]
178186
async fn get_tx_meta(&self, txid: Txid) -> Result<Option<TxEntry>, ErrorObjectOwned>;
@@ -187,7 +195,12 @@ pub trait Rpc {
187195
async fn verify_message(&self, msg: SignedMessage) -> Result<(), ErrorObjectOwned>;
188196

189197
#[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>;
191204

192205
#[method(name = "walletgetinfo")]
193206
async fn wallet_get_info(&self, name: &str) -> Result<WalletInfo, ErrorObjectOwned>;
@@ -239,10 +252,7 @@ pub trait Rpc {
239252
) -> Result<Listing, ErrorObjectOwned>;
240253

241254
#[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>;
246256

247257
#[method(name = "walletlisttransactions")]
248258
async fn wallet_list_transactions(
@@ -261,8 +271,10 @@ pub trait Rpc {
261271
) -> Result<TxResponse, ErrorObjectOwned>;
262272

263273
#[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>;
266278

267279
#[method(name = "walletlistunspent")]
268280
async fn wallet_list_unspent(
@@ -704,7 +716,7 @@ impl RpcServer for RpcServerImpl {
704716
async fn get_block_meta(
705717
&self,
706718
block_identifier: BlockIdentifier,
707-
) -> Result<Option<BlockMeta>, ErrorObjectOwned> {
719+
) -> Result<BlockMeta, ErrorObjectOwned> {
708720
let data = self
709721
.store
710722
.get_block_meta(block_identifier)
@@ -806,23 +818,39 @@ impl RpcServer for RpcServerImpl {
806818
.map_err(|error| ErrorObjectOwned::owned(-1, error.to_string(), None::<String>))
807819
}
808820

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> {
810828
self.wallet(&wallet)
811829
.await?
812830
.send_buy(listing, fee_rate, skip_tx_check)
813831
.await
814832
.map_err(|error| ErrorObjectOwned::owned(-1, error.to_string(), None::<String>))
815833
}
816834

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> {
818841
self.wallet(&wallet)
819842
.await?
820843
.send_sell(space, amount)
821844
.await
822845
.map_err(|error| ErrorObjectOwned::owned(-1, error.to_string(), None::<String>))
823846
}
824847

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> {
826854
self.wallet(&wallet)
827855
.await?
828856
.send_sign_message(space, msg)
@@ -930,15 +958,19 @@ impl AsyncChainState {
930958
BlockHash::from_str(info.get("blockhash").and_then(|t| t.as_str()).ok_or_else(
931959
|| anyhow!("Could not retrieve block hash for tx (is it in the mempool?)"),
932960
)?)?;
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?;
934969

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))
942974
}
943975

944976
async fn get_indexed_block(
@@ -947,24 +979,24 @@ impl AsyncChainState {
947979
client: &reqwest::Client,
948980
rpc: &BitcoinRpc,
949981
chain_state: &mut LiveSnapshot,
950-
) -> Result<Option<BlockMeta>, anyhow::Error> {
982+
) -> Result<BlockMeta, anyhow::Error> {
951983
let index = index
952984
.as_mut()
953985
.ok_or_else(|| anyhow!("block index must be enabled"))?;
954986
let block_hash = match block_identifier {
955987
BlockIdentifier::Hash(hash) => hash,
956988
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))?,
960992
};
961993
let hash = BaseHash::from_slice(block_hash.as_ref());
962994
let block: Option<BlockMeta> = index
963995
.get(hash)
964996
.context("Could not fetch block from index")?;
965997

966998
if let Some(block_set) = block {
967-
return Ok(Some(block_set));
999+
return Ok(block_set);
9681000
}
9691001

9701002
let info: serde_json::Value = rpc
@@ -975,17 +1007,21 @@ impl AsyncChainState {
9751007
let height = info
9761008
.get("height")
9771009
.and_then(|t| t.as_u64())
1010+
.and_then(|h| u32::try_from(h).ok())
9781011
.ok_or_else(|| anyhow!("Could not retrieve block height"))?;
9791012

9801013
let tip = chain_state.tip.read().expect("read meta").clone();
981-
if height > tip.height as u64 {
1014+
if height > tip.height {
9821015
return Err(anyhow!(
9831016
"Spaces is syncing at height {}, requested block height {}",
9841017
tip.height,
9851018
height
9861019
));
9871020
}
988-
Ok(None)
1021+
Ok(BlockMeta {
1022+
height,
1023+
tx_meta: Vec::new(),
1024+
})
9891025
}
9901026

9911027
pub async fn handle_command(
@@ -1032,10 +1068,18 @@ impl AsyncChainState {
10321068
.context("could not fetch spaceout");
10331069
let _ = resp.send(result);
10341070
}
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;
10391083
let _ = resp.send(res);
10401084
}
10411085
ChainStateCommand::GetTxMeta { txid, resp } => {
@@ -1051,12 +1095,20 @@ impl AsyncChainState {
10511095
_ = resp.send(rollouts);
10521096
}
10531097
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+
);
10551101
}
10561102
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+
);
10601112
}
10611113
}
10621114
}
@@ -1156,10 +1208,16 @@ impl AsyncChainState {
11561208
resp_rx.await?
11571209
}
11581210

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> {
11601215
let (resp, resp_rx) = oneshot::channel();
11611216
self.sender
1162-
.send(ChainStateCommand::GetBlockMeta { block_identifier, resp })
1217+
.send(ChainStateCommand::GetBlockMeta {
1218+
block_identifier,
1219+
resp,
1220+
})
11631221
.await?;
11641222
resp_rx.await?
11651223
}

0 commit comments

Comments
 (0)