jsonrpc: a new 'updatespend' RPC

This commit is contained in:
Antoine Poinsot 2022-09-15 11:37:22 +02:00
parent cf45ba0fa5
commit 3dfc7261db
No known key found for this signature in database
GPG Key ID: E13FC145CD3F4304
3 changed files with 60 additions and 1 deletions

View File

@ -109,3 +109,24 @@ This command will refuse to create any output worth less than 5k sats.
| Field | Type | Description |
| -------------- | --------- | ---------------------------------------------------- |
| `psbt` | string | PSBT of the spending transaction, encoded as base64. |
### `updatespend`
Store the PSBT of a Spend transaction in database, updating it if it already exists.
Will merge the partial signatures for all inputs if a PSBT for a transaction with the same txid
exists in DB.
#### Request
| Field | Type | Description |
| --------- | ------ | ------------------------------------------- |
| `psbt` | string | Base64-encoded PSBT of a Spend transaction. |
#### Response
This command does not return anything for now.
| Field | Type | Description |
| -------------- | --------- | ---------------------------------------------------- |

View File

@ -5,7 +5,7 @@ use crate::{
use std::{collections::HashMap, convert::TryInto, str::FromStr};
use miniscript::bitcoin;
use miniscript::bitcoin::{self, consensus, util::psbt::PartiallySignedTransaction as Psbt};
fn create_spend(control: &DaemonControl, params: Params) -> Result<serde_json::Value, Error> {
let outpoints = params
@ -47,6 +47,19 @@ fn create_spend(control: &DaemonControl, params: Params) -> Result<serde_json::V
Ok(serde_json::json!(&res))
}
fn update_spend(control: &DaemonControl, params: Params) -> Result<serde_json::Value, Error> {
let psbt: Psbt = params
.get(0, "psbt")
.ok_or(Error::invalid_params("Missing 'psbt' parameter."))?
.as_str()
.and_then(|s| base64::decode(&s).ok())
.and_then(|bytes| consensus::deserialize(&bytes).ok())
.ok_or(Error::invalid_params("Invalid 'feerate' parameter."))?;
control.update_spend(psbt)?;
Ok(serde_json::json!({}))
}
/// Handle an incoming JSONRPC2 request.
pub fn handle_request(control: &DaemonControl, req: Request) -> Result<Response, Error> {
let result = match req.method.as_str() {
@ -60,6 +73,12 @@ pub fn handle_request(control: &DaemonControl, req: Request) -> Result<Response,
"getnewaddress" => serde_json::json!(&control.get_new_address()),
"listcoins" => serde_json::json!(&control.list_coins()),
"stop" => serde_json::json!({}),
"updatespend" => {
let params = req
.params
.ok_or(Error::invalid_params("Missing 'psbt' parameter."))?;
update_spend(control, params)?
}
_ => {
return Err(Error::method_not_found());
}

View File

@ -93,3 +93,22 @@ def test_create_spend(minisafed, bitcoind):
# We can sign it and broadcast it.
signed_tx_hex = minisafed.sign_psbt(spend_psbt)
bitcoind.rpc.sendrawtransaction(signed_tx_hex)
def test_update_spend(minisafed, bitcoind):
# Start by creating a Spend PSBT
addr = minisafed.rpc.getnewaddress()["address"]
bitcoind.rpc.sendtoaddress(addr, 0.2567)
wait_for(lambda: len(minisafed.rpc.listcoins()["coins"]) > 0)
outpoints = [c["outpoint"] for c in minisafed.rpc.listcoins()["coins"]]
destinations = {
bitcoind.rpc.getnewaddress(): 200_000,
}
res = minisafed.rpc.createspend(outpoints, destinations, 6)
assert "psbt" in res
# Now update it
minisafed.rpc.updatespend(res["psbt"])
# TODO: check it's stored once we implement 'listspendtxs'
# TODO: check with added signatures once we implement 'listspendtxs'