mirror of
https://github.com/romanz/electrs.git
synced 2025-02-24 15:02:21 +01:00
Support 'blockchain.address.listunspent' Electrum RPC
This commit is contained in:
parent
321d655d7a
commit
b83b0718dd
1 changed files with 34 additions and 16 deletions
50
src/rpc.rs
50
src/rpc.rs
|
@ -1,5 +1,6 @@
|
|||
use bitcoin::blockdata::transaction::Transaction;
|
||||
use bitcoin::network::serialize::{deserialize, serialize};
|
||||
use bitcoin::util::address::Address;
|
||||
use bitcoin::util::hash::Sha256dHash;
|
||||
use error_chain::ChainedError;
|
||||
use hex;
|
||||
|
@ -7,12 +8,14 @@ use serde_json::{from_str, Number, Value};
|
|||
use std::collections::HashMap;
|
||||
use std::io::{BufRead, BufReader, Write};
|
||||
use std::net::{Shutdown, SocketAddr, TcpListener, TcpStream};
|
||||
use std::str::FromStr;
|
||||
use std::sync::mpsc::{Sender, SyncSender, TrySendError};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread;
|
||||
|
||||
use index::compute_script_hash;
|
||||
use metrics::{Gauge, HistogramOpts, HistogramVec, MetricOpts, Metrics};
|
||||
use query::Query;
|
||||
use query::{Query, Status};
|
||||
use util::{spawn_thread, Channel, HeaderEntry, SyncChannel};
|
||||
|
||||
use errors::*;
|
||||
|
@ -31,6 +34,23 @@ fn usize_from_value(val: Option<&Value>, name: &str) -> Result<usize> {
|
|||
Ok(val as usize)
|
||||
}
|
||||
|
||||
fn unspent_from_status(status: &Status) -> Value {
|
||||
json!(Value::Array(
|
||||
status
|
||||
.unspent()
|
||||
.into_iter()
|
||||
.map(|out| {
|
||||
json!({
|
||||
"height": out.height,
|
||||
"tx_pos": out.output_index,
|
||||
"tx_hash": out.txn_id.be_hex_string(),
|
||||
"value": out.value,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
))
|
||||
}
|
||||
|
||||
fn jsonify_header(entry: &HeaderEntry) -> Value {
|
||||
let header = entry.header();
|
||||
json!({
|
||||
|
@ -166,21 +186,18 @@ impl Connection {
|
|||
|
||||
fn blockchain_scripthash_listunspent(&self, params: &[Value]) -> Result<Value> {
|
||||
let script_hash = hash_from_value(params.get(0)).chain_err(|| "bad script_hash")?;
|
||||
let status = self.query.status(&script_hash[..])?;
|
||||
Ok(json!(Value::Array(
|
||||
status
|
||||
.unspent()
|
||||
.into_iter()
|
||||
.map(|out| {
|
||||
json!({
|
||||
"height": out.height,
|
||||
"tx_pos": out.output_index,
|
||||
"tx_hash": out.txn_id.be_hex_string(),
|
||||
"value": out.value,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
)))
|
||||
Ok(unspent_from_status(&self.query.status(&script_hash[..])?))
|
||||
}
|
||||
|
||||
fn blockchain_address_listunspent(&self, params: &[Value]) -> Result<Value> {
|
||||
let address = params
|
||||
.get(0)
|
||||
.chain_err(|| "no address")?
|
||||
.as_str()
|
||||
.chain_err(|| "non-string address")?;
|
||||
let addr = Address::from_str(address).chain_err(|| format!("invalid address {}", address))?;
|
||||
let script_hash = compute_script_hash(&addr.script_pubkey().into_vec());
|
||||
Ok(unspent_from_status(&self.query.status(&script_hash[..])?))
|
||||
}
|
||||
|
||||
fn blockchain_transaction_broadcast(&self, params: &[Value]) -> Result<Value> {
|
||||
|
@ -231,6 +248,7 @@ impl Connection {
|
|||
"blockchain.block.get_header" => self.blockchain_block_get_header(¶ms),
|
||||
"blockchain.estimatefee" => self.blockchain_estimatefee(¶ms),
|
||||
"blockchain.relayfee" => self.blockchain_relayfee(),
|
||||
"blockchain.address.listunspent" => self.blockchain_address_listunspent(¶ms),
|
||||
"blockchain.scripthash.subscribe" => self.blockchain_scripthash_subscribe(¶ms),
|
||||
"blockchain.scripthash.get_balance" => self.blockchain_scripthash_get_balance(¶ms),
|
||||
"blockchain.scripthash.get_history" => self.blockchain_scripthash_get_history(¶ms),
|
||||
|
|
Loading…
Add table
Reference in a new issue