From b6e1aa7db85e34860445ec42adf959fec667b0ff Mon Sep 17 00:00:00 2001 From: Steven Roose Date: Wed, 25 Sep 2024 23:07:11 +0100 Subject: [PATCH] Add /txs endpoint to submit tx packages --- src/daemon.rs | 13 +++++++++++++ src/new_index/query.rs | 8 ++++++++ src/rest.rs | 8 ++++++++ 3 files changed, 29 insertions(+) diff --git a/src/daemon.rs b/src/daemon.rs index 457bf4230..c7e77d78b 100644 --- a/src/daemon.rs +++ b/src/daemon.rs @@ -549,6 +549,19 @@ impl Daemon { ) } + pub fn broadcast_pkg_raw(&self, txshex: &[String]) -> Result> { + let res = self.request("submitpackage", json!([txshex]))?; + res.as_object().chain_err(|| "no object")? + .get("tx-results").chain_err(|| "missing key tx-results")? + .as_object().chain_err(|| "tx-results not an object")? + .into_iter().map(|(_, tx_ret)| tx_ret + .as_object().chain_err(|| "tx result not an object")? + .get("txid").chain_err(|| "missing txid field")? + .as_str().chain_err(|| "txid not a string")? + .parse().chain_err(|| "invalid txid") + ).collect() + } + // Get estimated feerates for the provided confirmation targets using a batch RPC request // Missing estimates are logged but do not cause a failure, whatever is available is returned #[allow(clippy::float_cmp)] diff --git a/src/new_index/query.rs b/src/new_index/query.rs index 60d7510ab..3c78476e7 100644 --- a/src/new_index/query.rs +++ b/src/new_index/query.rs @@ -78,6 +78,14 @@ impl Query { Ok(txid) } + pub fn broadcast_pkg_raw(&self, txshex: &[String]) -> Result> { + let txids = self.daemon.broadcast_pkg_raw(txshex)?; + for txid in &txids { + self.mempool.write().unwrap().add_by_txid(&self.daemon, &txid); + } + Ok(txids) + } + pub fn utxo(&self, scripthash: &[u8]) -> Result> { let mut utxos = self.chain.utxo(scripthash, self.config.utxos_limit)?; let mempool = self.mempool(); diff --git a/src/rest.rs b/src/rest.rs index 43eab5c60..e8ce63b25 100644 --- a/src/rest.rs +++ b/src/rest.rs @@ -992,6 +992,14 @@ fn handle_request( .map_err(|err| HttpError::from(err.description().to_string()))?; http_message(StatusCode::OK, txid.to_string(), 0) } + (&Method::POST, Some(&"txs"), None, None, None, None) => { + let txshex = serde_json::from_slice::>(&body[..]).map_err(|_| { + HttpError(StatusCode::BAD_REQUEST, "expected array of hexes".into()) + })?; + let txids = query.broadcast_pkg_raw(&txshex) + .map_err(|err| HttpError::from(err.description().to_string()))?; + http_message(StatusCode::OK, serde_json::to_vec(&txids)?, 0) + } (&Method::GET, Some(&"mempool"), None, None, None, None) => { json_response(query.mempool().backlog_stats(), TTL_SHORT)