mirror of
https://github.com/romanz/electrs.git
synced 2024-11-19 01:43:29 +01:00
parent
e99906ff83
commit
0a04888673
@ -67,11 +67,19 @@ def main():
|
||||
client.request('blockchain.scripthash.get_balance', script_hash)
|
||||
for script_hash in script_hashes
|
||||
)
|
||||
for addr, balance in sorted(zip(args.address, balances), key=lambda v: v[0]):
|
||||
if balance["confirmed"]:
|
||||
log.info("{}: confirmed {:,.5f} mBTC", addr, balance["confirmed"] / 1e5)
|
||||
if balance["unconfirmed"]:
|
||||
log.info("{}: unconfirmed {:,.5f} mBTC", addr, balance["unconfirmed"] / 1e5)
|
||||
|
||||
unspents = conn.call(
|
||||
client.request('blockchain.scripthash.listunspent', script_hash)
|
||||
for script_hash in script_hashes
|
||||
)
|
||||
for addr, balance, unspent in sorted(zip(args.address, balances, unspents), key=lambda v: v[0]):
|
||||
if unspent:
|
||||
log.debug("{}: confirmed={:,.5f} mBTC, unconfirmed={:,.5f} mBTC",
|
||||
addr, balance["confirmed"] / 1e5, balance["unconfirmed"] / 1e5)
|
||||
for u in unspent:
|
||||
log.debug("\t{}:{} = {:,.5f} mBTC {}",
|
||||
u["tx_hash"], u["tx_pos"], u["value"] / 1e5,
|
||||
f'@ {u["height"]}' if u["height"] else "")
|
||||
|
||||
histories = conn.call(
|
||||
client.request('blockchain.scripthash.get_history', script_hash)
|
||||
|
@ -256,6 +256,24 @@ impl Rpc {
|
||||
Ok(json!(history_entries))
|
||||
}
|
||||
|
||||
fn scripthash_list_unspent(
|
||||
&self,
|
||||
client: &Client,
|
||||
(scripthash,): (ScriptHash,),
|
||||
) -> Result<Value> {
|
||||
let unspent_entries = match client.scripthashes.get(&scripthash) {
|
||||
Some(status) => self.tracker.get_unspent(status),
|
||||
None => {
|
||||
warn!(
|
||||
"blockchain.scripthash.listunspent called for unsubscribed scripthash: {}",
|
||||
scripthash
|
||||
);
|
||||
self.tracker.get_unspent(&self.new_status(scripthash)?)
|
||||
}
|
||||
};
|
||||
Ok(json!(unspent_entries))
|
||||
}
|
||||
|
||||
fn scripthash_subscribe(
|
||||
&self,
|
||||
client: &mut Client,
|
||||
@ -406,6 +424,7 @@ impl Rpc {
|
||||
Call::RelayFee => self.relayfee(),
|
||||
Call::ScriptHashGetBalance(args) => self.scripthash_get_balance(client, args),
|
||||
Call::ScriptHashGetHistory(args) => self.scripthash_get_history(client, args),
|
||||
Call::ScriptHashListUnspent(args) => self.scripthash_list_unspent(client, args),
|
||||
Call::ScriptHashSubscribe(args) => self.scripthash_subscribe(client, args),
|
||||
Call::TransactionBroadcast(args) => self.transaction_broadcast(args),
|
||||
Call::TransactionGet(args) => self.transaction_get(args),
|
||||
@ -445,6 +464,7 @@ enum Call {
|
||||
RelayFee,
|
||||
ScriptHashGetBalance((ScriptHash,)),
|
||||
ScriptHashGetHistory((ScriptHash,)),
|
||||
ScriptHashListUnspent((ScriptHash,)),
|
||||
ScriptHashSubscribe((ScriptHash,)),
|
||||
TransactionGet(TxGetArgs),
|
||||
TransactionGetMerkle((Txid, usize)),
|
||||
@ -461,6 +481,7 @@ impl Call {
|
||||
"blockchain.relayfee" => Call::RelayFee,
|
||||
"blockchain.scripthash.get_balance" => Call::ScriptHashGetBalance(convert(params)?),
|
||||
"blockchain.scripthash.get_history" => Call::ScriptHashGetHistory(convert(params)?),
|
||||
"blockchain.scripthash.listunspent" => Call::ScriptHashListUnspent(convert(params)?),
|
||||
"blockchain.scripthash.subscribe" => Call::ScriptHashSubscribe(convert(params)?),
|
||||
"blockchain.transaction.broadcast" => Call::TransactionBroadcast(convert(params)?),
|
||||
"blockchain.transaction.get" => Call::TransactionGet(convert(params)?),
|
||||
|
@ -142,6 +142,17 @@ pub(crate) struct Balance {
|
||||
mempool_delta: SignedAmount,
|
||||
}
|
||||
|
||||
// A single unspent transaction output entry:
|
||||
// https://electrumx-spesmilo.readthedocs.io/en/latest/protocol-methods.html#blockchain-scripthash-listunspent
|
||||
#[derive(Serialize)]
|
||||
pub(crate) struct UnspentEntry {
|
||||
height: usize, // 0 = mempool entry
|
||||
tx_hash: Txid,
|
||||
tx_pos: u32,
|
||||
#[serde(with = "bitcoin::util::amount::serde::as_sat")]
|
||||
value: Amount,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct Unspent {
|
||||
// mapping an outpoint to its value & confirmation height
|
||||
@ -172,6 +183,18 @@ impl Unspent {
|
||||
unspent
|
||||
}
|
||||
|
||||
fn into_entries(self) -> Vec<UnspentEntry> {
|
||||
self.outpoints
|
||||
.into_iter()
|
||||
.map(|(outpoint, (value, height))| UnspentEntry {
|
||||
height,
|
||||
tx_hash: outpoint.txid,
|
||||
tx_pos: outpoint.vout,
|
||||
value,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn balance(&self) -> Amount {
|
||||
self.outpoints
|
||||
.values()
|
||||
@ -237,6 +260,10 @@ impl ScriptHashStatus {
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub(crate) fn get_unspent(&self, chain: &Chain) -> Vec<UnspentEntry> {
|
||||
Unspent::build(self, chain).into_entries()
|
||||
}
|
||||
|
||||
pub(crate) fn get_balance(&self, chain: &Chain) -> Balance {
|
||||
let unspent = Unspent::build(self, chain);
|
||||
Balance {
|
||||
|
@ -12,7 +12,7 @@ use crate::{
|
||||
index::Index,
|
||||
mempool::{Histogram, Mempool},
|
||||
metrics::Metrics,
|
||||
status::{Balance, HistoryEntry, ScriptHashStatus},
|
||||
status::{Balance, HistoryEntry, ScriptHashStatus, UnspentEntry},
|
||||
};
|
||||
|
||||
/// Electrum protocol subscriptions' tracker
|
||||
@ -55,6 +55,10 @@ impl Tracker {
|
||||
status.get_history(self.index.chain(), &self.mempool)
|
||||
}
|
||||
|
||||
pub(crate) fn get_unspent(&self, status: &ScriptHashStatus) -> Vec<UnspentEntry> {
|
||||
status.get_unspent(self.index.chain())
|
||||
}
|
||||
|
||||
pub fn sync(&mut self, daemon: &Daemon) -> Result<()> {
|
||||
self.index.sync(daemon, self.index_batch_size)?;
|
||||
if !self.ignore_mempool {
|
||||
|
Loading…
Reference in New Issue
Block a user