Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ tracing-appender = "0.2.3"
tracing-indicatif = "0.3.8"
tracing-subscriber = "0.3.20"
transitive = "1.0.1"
typewit = { version = "1.15", default-features = false }
utoipa = { version = "5.2.0", default-features = false }
url = { version = "2.5.4", default-features = false }
uuid = "1.13.1"
Expand All @@ -96,7 +97,7 @@ path = "bip300301_enforcer/integration_tests"

[workspace.dependencies.l2l-openapi]
git = "https://github.com/Ash-L2L/l2l-openapi"
rev = "caa8c1c248aca1827b57007dcfcd8ff70d607e8e"
rev = "a97f7923ce4b62587aebc7561d713bb2ebc89e52"

[workspace.dependencies.rustreexo]
git = "https://github.com/mit-dci/rustreexo"
Expand Down
128 changes: 112 additions & 16 deletions app/rpc_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ use jsonrpsee::{
types::ErrorObject,
};
use thunder::types::{
Address, Block, Pointed, PointedOutput, SpentOutput, Txid,
Address, Block, M6id, Pointed, PointedOutput, SpentOutput, Txid,
WithdrawalBundle,
net::{Peer, PeerAddress},
wallet::Balance,
};
use thunder_app_rpc_api as rpc_api;
use thunder_app_rpc_api::{self as rpc_api, typewit::const_marker::Bool};
use tower_http::{
cors::CorsLayer,
request_id::{
Expand Down Expand Up @@ -117,6 +117,78 @@ impl rpc_api::node::PrivateRpcServer for RpcServerImpl<true> {
}
}

#[async_trait]
impl<const ENABLE_PRIVATE_API: bool>
rpc_api::node::get_block::RpcServer<Bool<false>>
for RpcServerImpl<ENABLE_PRIVATE_API>
{
async fn get_block(
&self,
block_hash: thunder::types::BlockHash,
_verbose: Bool<false>,
) -> RpcResult<
Option<<Bool<false> as rpc_api::node::get_block::Verbosity>::Response>,
> {
let Some(header) = self
.app
.node
.try_get_header(block_hash)
.map_err(custom_err)?
else {
return Ok(None);
};
let body = self.app.node.get_body(block_hash).map_err(custom_err)?;
let block = thunder::types::Block { header, body };
Ok(Some(block))
}
}

#[async_trait]
impl<const ENABLE_PRIVATE_API: bool>
rpc_api::node::get_block::RpcServer<Bool<true>>
for RpcServerImpl<ENABLE_PRIVATE_API>
{
async fn get_block(
&self,
block_hash: thunder::types::BlockHash,
_verbose: Bool<true>,
) -> RpcResult<
Option<<Bool<true> as rpc_api::node::get_block::Verbosity>::Response>,
> {
let Some(header) = self
.app
.node
.try_get_header(block_hash)
.map_err(custom_err)?
else {
return Ok(None);
};
let thunder::types::Body {
coinbase,
transactions,
authorizations,
} = self.app.node.get_body(block_hash).map_err(custom_err)?;
let transactions_verbose = transactions
.into_iter()
.map(|tx| {
Ok(thunder_app_rpc_api::node::TransactionVerbose {
canonical_bytes: tx.canonical_bytes()?,
tx,
})
})
.collect::<std::io::Result<_>>()
.map_err(custom_err)?;
let body = thunder_app_rpc_api::node::get_block::BodyVerbose {
coinbase,
transactions: transactions_verbose,
authorizations,
};
let block_verbose =
thunder_app_rpc_api::node::get_block::BlockVerbose { header, body };
Ok(Some(block_verbose))
}
}

#[async_trait]
impl<const ENABLE_PRIVATE_API: bool> rpc_api::node::RpcServer
for RpcServerImpl<ENABLE_PRIVATE_API>
Expand All @@ -140,21 +212,11 @@ impl<const ENABLE_PRIVATE_API: bool> rpc_api::node::RpcServer
.unwrap()
}

async fn get_block(
async fn get_block_hash(
&self,
block_hash: thunder::types::BlockHash,
) -> RpcResult<Option<thunder::types::Block>> {
let Some(header) = self
.app
.node
.try_get_header(block_hash)
.map_err(custom_err)?
else {
return Ok(None);
};
let body = self.app.node.get_body(block_hash).map_err(custom_err)?;
let block = thunder::types::Block { header, body };
Ok(Some(block))
height: u32,
) -> RpcResult<Option<thunder::types::BlockHash>> {
self.app.node.try_get_block_hash(height).map_err(custom_err)
}

async fn get_best_sidechain_block_hash(
Expand Down Expand Up @@ -235,6 +297,25 @@ impl<const ENABLE_PRIVATE_API: bool> rpc_api::node::RpcServer
Ok(res)
}

async fn get_withdrawal_bundle(
&self,
m6id: M6id,
) -> RpcResult<Option<rpc_api::node::GetWithdrawalBundleResponse>> {
let Some((bundle_info, bundle_status)) = self
.app
.node
.try_get_withdrawal_bundle(&m6id)
.map_err(custom_err)?
else {
return Ok(None);
};
let response = rpc_api::node::GetWithdrawalBundleResponse {
info: bundle_info,
status: bundle_status,
};
Ok(Some(response))
}

async fn getblockcount(&self) -> RpcResult<u32> {
let height = self.app.node.try_get_height().map_err(custom_err)?;
let block_count = height.map_or(0, |height| height + 1);
Expand Down Expand Up @@ -569,6 +650,11 @@ pub async fn run_server(
let rpc_server_impl = RpcServerImpl::<false> { app: app.clone() };
let mut rpc_module =
rpc_api::open_api::RpcServer::into_rpc(rpc_server_impl.clone());
rpc_module.merge(
rpc_api::node::get_block::untyped::RpcServer::into_rpc(
rpc_server_impl.clone(),
),
)?;
rpc_module
.merge(rpc_api::node::RpcServer::into_rpc(rpc_server_impl))?;
server.start(rpc_module)
Expand All @@ -578,6 +664,11 @@ pub async fn run_server(
let mut rpc_module = rpc_api::open_api::RpcServer::into_rpc(
PrivateOnlyRpcServerImpl,
);
rpc_module.merge(
rpc_api::node::get_block::untyped::RpcServer::into_rpc(
rpc_server_impl.clone(),
),
)?;
rpc_module.merge(rpc_api::node::PrivateRpcServer::into_rpc(
rpc_server_impl.clone(),
))?;
Expand All @@ -603,6 +694,11 @@ pub async fn run_server(
rpc_module.merge(rpc_api::node::PrivateRpcServer::into_rpc(
rpc_server_impl.clone(),
))?;
rpc_module.merge(
rpc_api::node::get_block::untyped::RpcServer::into_rpc(
rpc_server_impl.clone(),
),
)?;
rpc_module.merge(rpc_api::node::RpcServer::into_rpc(
rpc_server_impl.clone(),
))?;
Expand Down
49 changes: 38 additions & 11 deletions cli/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ use clap::{Parser, Subcommand};
use http::HeaderMap;
use jsonrpsee::{core::client::ClientT, http_client::HttpClientBuilder};

use thunder::types::{Address, Txid, net::PeerAddress};
use thunder::types::{Address, M6id, Txid, net::PeerAddress};
use thunder_app_rpc_api::{
node::{PrivateRpcClient as _, RpcClient as _},
node::{PrivateRpcClient as _, RpcClient as _, get_block::RpcClient as _},
typewit::const_marker::Bool,
wallet::RpcClient as _,
};
use tracing_subscriber::layer::SubscriberExt as _;
Expand Down Expand Up @@ -79,7 +80,13 @@ pub enum Command {
/// Get the block with specified block hash, if it exists
GetBlock {
block_hash: thunder::types::BlockHash,
verbose: Option<bool>,
},
/// Get the current block count
GetBlockcount,
/// Get the block hash at the specified height in the active chain, if it
/// exists
GetBlockHash { height: u32 },
/// Assemble a block to blind merge mine, without requesting BMM for it
GetBlockTemplate,
/// Get mainchain blocks that commit to a specified block hash
Expand All @@ -104,8 +111,8 @@ pub enum Command {
GetWalletAddresses,
/// Get wallet UTXOs
GetWalletUtxos,
/// Get the current block count
GetBlockcount,
/// Get withdrawal bundle by M6id
GetWithdrawalBundle { m6id: M6id },
/// Invalidate a block, potentially re-orging to a valid ancestor of the
/// current tip.
InvalidateBlock {
Expand Down Expand Up @@ -190,6 +197,10 @@ where
rpc_client.connect_block(block, main_block_hash).await?;
format!("{accepted}")
}
Command::GetBlockHash { height } => {
let block_hash = rpc_client.get_block_hash(height).await?;
serde_json::to_string_pretty(&block_hash)?
}
Command::ConnectPeer { addr } => {
let () = rpc_client.connect_peer(addr).await?;
String::default()
Expand Down Expand Up @@ -237,10 +248,6 @@ where
rpc_client.forget_peer(addr).await?;
String::default()
}
Command::GetBlock { block_hash } => {
let block = rpc_client.get_block(block_hash).await?;
serde_json::to_string_pretty(&block)?
}
Command::GetBestMainchainBlockHash => {
let block_hash = rpc_client.get_best_mainchain_block_hash().await?;
serde_json::to_string_pretty(&block_hash)?
Expand All @@ -249,6 +256,25 @@ where
let block_hash = rpc_client.get_best_sidechain_block_hash().await?;
serde_json::to_string_pretty(&block_hash)?
}
Command::GetBlock {
block_hash,
verbose,
} => match verbose {
Some(true) => {
let block =
rpc_client.get_block(block_hash, Bool::<true>).await?;
serde_json::to_string_pretty(&block)?
}
Some(false) | None => {
let block =
rpc_client.get_block(block_hash, Bool::<false>).await?;
serde_json::to_string_pretty(&block)?
}
},
Command::GetBlockcount => {
let blockcount = rpc_client.getblockcount().await?;
format!("{blockcount}")
}
Command::GetBlockTemplate => {
let template = rpc_client.get_block_template().await?;
serde_json::to_string_pretty(&template)?
Expand Down Expand Up @@ -285,9 +311,10 @@ where
let utxos = rpc_client.get_wallet_utxos().await?;
serde_json::to_string_pretty(&utxos)?
}
Command::GetBlockcount => {
let blockcount = rpc_client.getblockcount().await?;
format!("{blockcount}")
Command::GetWithdrawalBundle { m6id } => {
let withdrawal_bundle =
rpc_client.get_withdrawal_bundle(m6id).await?;
serde_json::to_string_pretty(&withdrawal_bundle)?
}
Command::InvalidateBlock { block_hash } => {
let () = rpc_client.invalidate_block(block_hash).await?;
Expand Down
20 changes: 18 additions & 2 deletions lib/node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,17 @@ use bitcoin::amount::CheckedSum;
use fallible_iterator::{FallibleIterator, IteratorExt};
use futures::Stream;
use sneed::{DbError, Env, EnvError, RwTxnError};
use thunder_types::{
M6id, WithdrawalBundleStatus, state::WithdrawalBundleInfo,
};
use tokio::sync::Mutex;
use tonic::transport::Channel;

use crate::{
archive::Archive,
mempool::{self, MemPool},
net::{DialKnownPeersHandle, Net},
state::State,
state::{self, State},
types::{
Accumulator, Address, AmountOverflowError, AmountUnderflowError,
Authorized, AuthorizedTransaction, BlockHash, BmmResult, Body,
Expand Down Expand Up @@ -380,7 +383,7 @@ where
Ok(self.archive.get_header(&txn, block_hash)?)
}

/// Get the block hash at the specified height in the current chain,
/// Get the block hash at the specified height in the active chain,
/// if it exists
pub fn try_get_block_hash(
&self,
Expand Down Expand Up @@ -558,6 +561,19 @@ where
}
}

pub fn try_get_withdrawal_bundle(
&self,
m6id: &M6id,
) -> Result<Option<(WithdrawalBundleInfo, WithdrawalBundleStatus)>, Error>
{
let rotxn = self.env.read_txn()?;
let res = self
.state
.try_get_withdrawal_bundle(&rotxn, m6id)
.map_err(state::Error::from)?;
Ok(res)
}

pub fn try_get_pending_withdrawal_bundle(
&self,
) -> Result<Option<WithdrawalBundle>, Error> {
Expand Down
Loading
Loading