global: reused + mempool + favicon

This commit is contained in:
nym21
2026-04-23 23:13:39 +02:00
parent ce00de5da8
commit e4496742a4
77 changed files with 2631 additions and 1624 deletions

View File

@@ -10,7 +10,7 @@ exclude = ["examples/"]
[features]
default = ["corepc"]
bitcoincore-rpc = ["dep:bitcoincore-rpc", "brk_error/bitcoincore-rpc"]
bitcoincore-rpc = ["dep:bitcoincore-rpc", "dep:serde_json", "brk_error/bitcoincore-rpc"]
corepc = ["dep:corepc-client", "dep:corepc-jsonrpc", "dep:serde_json", "dep:serde", "brk_error/corepc"]
[dependencies]

View File

@@ -1,13 +1,19 @@
use std::{thread::sleep, time::Duration};
use bitcoincore_rpc::{Client as CoreClient, Error as RpcError, RpcApi, jsonrpc};
use bitcoincore_rpc::{
Client as CoreClient, Error as RpcError, RpcApi,
json::{GetBlockTemplateCapabilities, GetBlockTemplateModes, GetBlockTemplateRules},
jsonrpc,
};
use brk_error::{Error, Result};
use brk_types::Sats;
use brk_types::{Sats, Txid};
use parking_lot::RwLock;
use serde_json::value::RawValue;
use tracing::info;
use super::{Auth, BlockHeaderInfo, BlockInfo, BlockchainInfo, RawMempoolEntry, TxOutInfo};
use super::{
Auth, BlockHeaderInfo, BlockInfo, BlockTemplateTx, BlockchainInfo, RawMempoolEntry, TxOutInfo,
};
/// Per-batch request count for `get_block_hashes_range`. Sized so the
/// JSON request body stays well under a megabyte and bitcoind doesn't
@@ -310,4 +316,23 @@ impl ClientInner {
pub fn send_raw_transaction(&self, hex: &str) -> Result<bitcoin::Txid> {
Ok(self.call_once(|c| c.send_raw_transaction(hex))?)
}
/// Transactions Bitcoin Core would include in the next block it would
/// mine. Core requires the `segwit` rule to be declared.
pub fn get_block_template_txs(&self) -> Result<Vec<BlockTemplateTx>> {
let r = self.call_with_retry(|c| {
c.get_block_template(
GetBlockTemplateModes::Template,
&[GetBlockTemplateRules::SegWit],
&[] as &[GetBlockTemplateCapabilities],
)
})?;
Ok(r.transactions
.into_iter()
.map(|t| BlockTemplateTx {
txid: Txid::from(t.txid),
fee: Sats::from(t.fee.to_sat()),
})
.collect())
}
}

View File

@@ -1,13 +1,15 @@
use std::{thread::sleep, time::Duration};
use brk_error::{Error, Result};
use brk_types::Sats;
use brk_types::{Sats, Txid};
use corepc_client::client_sync::Auth as CorepcAuth;
use parking_lot::RwLock;
use serde_json::value::RawValue;
use tracing::info;
use super::{Auth, BlockHeaderInfo, BlockInfo, BlockchainInfo, RawMempoolEntry, TxOutInfo};
use super::{
Auth, BlockHeaderInfo, BlockInfo, BlockTemplateTx, BlockchainInfo, RawMempoolEntry, TxOutInfo,
};
type CoreClient = corepc_client::client_sync::v30::Client;
type CoreError = corepc_client::client_sync::Error;
@@ -186,11 +188,7 @@ impl ClientInner {
/// a 50 MB request body or hold every response in memory at once.
///
/// Returns hashes in canonical order (`start`, `start+1`, …, `end`).
pub fn get_block_hashes_range(
&self,
start: u64,
end: u64,
) -> Result<Vec<bitcoin::BlockHash>> {
pub fn get_block_hashes_range(&self, start: u64, end: u64) -> Result<Vec<bitcoin::BlockHash>> {
if end < start {
return Ok(Vec::new());
}
@@ -370,6 +368,22 @@ impl ClientInner {
c.call("sendrawtransaction", &args)
})?)
}
/// Transactions Bitcoin Core would include in the next block it would
/// mine. Core requires the `segwit` rule to be declared.
pub fn get_block_template_txs(&self) -> Result<Vec<BlockTemplateTx>> {
let args = [serde_json::json!({ "rules": ["segwit"] })];
let r: GetBlockTemplateResponse =
self.call_with_retry(|c| c.call("getblocktemplate", &args))?;
Ok(r.transactions
.into_iter()
.map(|t| BlockTemplateTx {
txid: Txid::from(t.txid),
fee: Sats::from(t.fee),
})
.collect())
}
}
// Local deserialization structs for raw RPC responses
@@ -386,3 +400,14 @@ struct TxOutResponse {
struct TxOutScriptPubKey {
hex: String,
}
#[derive(serde::Deserialize)]
struct GetBlockTemplateResponse {
transactions: Vec<GetBlockTemplateTx>,
}
#[derive(serde::Deserialize)]
struct GetBlockTemplateTx {
txid: bitcoin::Txid,
fee: u64,
}

View File

@@ -1,7 +1,7 @@
use std::path::PathBuf;
use bitcoin::ScriptBuf;
use brk_types::Sats;
use brk_types::{Sats, Txid};
#[derive(Debug, Clone)]
pub struct BlockchainInfo {
@@ -29,6 +29,12 @@ pub struct TxOutInfo {
pub script_pub_key: ScriptBuf,
}
#[derive(Debug, Clone)]
pub struct BlockTemplateTx {
pub txid: Txid,
pub fee: Sats,
}
#[derive(Debug, Clone)]
pub struct RawMempoolEntry {
pub vsize: u64,

View File

@@ -12,7 +12,7 @@ use brk_types::{BlockHash, Height, MempoolEntryInfo, Sats, Txid, Vout};
pub mod backend;
pub use backend::{Auth, BlockHeaderInfo, BlockInfo, BlockchainInfo, TxOutInfo};
pub use backend::{Auth, BlockHeaderInfo, BlockInfo, BlockTemplateTx, BlockchainInfo, TxOutInfo};
use backend::ClientInner;
use tracing::{debug, info};
@@ -201,6 +201,12 @@ impl Client {
self.0.send_raw_transaction(hex).map(Txid::from)
}
/// Transactions (txid + fee) Bitcoin Core would include in the next
/// block it would mine, via `getblocktemplate`.
pub fn get_block_template_txs(&self) -> Result<Vec<BlockTemplateTx>> {
self.0.get_block_template_txs()
}
/// Checks if a block is in the main chain (has positive confirmations)
pub fn is_in_main_chain(&self, hash: &BlockHash) -> Result<bool> {
let block_info = self.get_block_info(hash)?;