mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-09 11:27:28 -03:00
Merge bitcoin/bitcoin#30515: rpc: add utxo's blockhash and number of confirmations to scantxoutset output
17845e7f21
rpc: add utxo's blockhash and number of confirmations to scantxoutset output (Luis Schwab) Pull request description: This PR resolves #30478 by adding two fields to the `scantxoutset` RPC: - blockhash: the blockhash that an UTXO was created - confirmations: the number of confirmations an UTXO has relative to the chaintip. The rationale for the first field is that a blockhash is a much more reliable identifier than the height: > When using the scantxoutset RPC, the current behaviour is to show the block height of the UTXO. This is not optimal, as block height is ambiguous, especially in the case of a block reorganization happening at the same instant of the query. In this case, an UTXO that does not exist would be assumed to exist, unless the chain's tip hash is recorded before the scan, and make sure it still exists after, as per https://github.com/bitcoindevkit/bdk/issues/895#issuecomment-1475766797 comment by evanlinjin. The second one was suggested by maflcko, and I agree it's useful for human users: > While touching this, another thing to add could be the number of confirmations? I understand that this wouldn't help machine consumers of the interface, but human callers may find it useful? This will yield an RPC output like so: ```diff bitcoin-cli scantxoutset start "[\"addr(bc1q5q9344vdyjkcgv79ve3tldz4jmx4lf7knmnx6r)\"]" { "success": true, "txouts": 185259116, "height": 853622, "bestblock": "00000000000000000002e97d9be8f0ddf31829cf873061b938c10b0f80f708b2", "unspents": [ { "txid": "fae435084345fe26e464994aebc6544875bca0b897bf4ce52a65901ae28ace92", "vout": 0, "scriptPubKey": "0014a00b1ad58d24ad8433c56662bfb45596cd5fa7d6", "desc": "addr(bc1q5q9344vdyjkcgv79ve3tldz4jmx4lf7knmnx6r)#smk4xmt7", "amount": 0.00091190, "coinbase": false, "height": 852741, + "blockhash": "00000000000000000002eefe7e7db44d5619c3dace4c65f3fdcd2913d4945c13", + "confirmations": 882 } ], "total_amount": 0.00091190 } ``` ACKs for top commit: sipa: utACK17845e7f21
Eunovo: ACK17845e7f21
tdb3: ACK17845e7f21
Tree-SHA512: 02366d0004e5d547522115ef0efe6794a35978db53dda12c675cfae38197bf43f0bf89ca99a3d79e3d2cff95186015fe1ab764abb8ab82bda440ae9302ad973b
This commit is contained in:
commit
38c30a4b50
2 changed files with 17 additions and 4 deletions
|
@ -2190,7 +2190,7 @@ static RPCHelpMan scantxoutset()
|
|||
RPCResult{"when action=='start'; only returns after scan completes", RPCResult::Type::OBJ, "", "", {
|
||||
{RPCResult::Type::BOOL, "success", "Whether the scan was completed"},
|
||||
{RPCResult::Type::NUM, "txouts", "The number of unspent transaction outputs scanned"},
|
||||
{RPCResult::Type::NUM, "height", "The current block height (index)"},
|
||||
{RPCResult::Type::NUM, "height", "The block height at which the scan was done"},
|
||||
{RPCResult::Type::STR_HEX, "bestblock", "The hash of the block at the tip of the chain"},
|
||||
{RPCResult::Type::ARR, "unspents", "",
|
||||
{
|
||||
|
@ -2203,6 +2203,8 @@ static RPCHelpMan scantxoutset()
|
|||
{RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " of the unspent output"},
|
||||
{RPCResult::Type::BOOL, "coinbase", "Whether this is a coinbase output"},
|
||||
{RPCResult::Type::NUM, "height", "Height of the unspent transaction output"},
|
||||
{RPCResult::Type::STR_HEX, "blockhash", "Blockhash of the unspent transaction output"},
|
||||
{RPCResult::Type::NUM, "confirmations", "Number of confirmations of the unspent transaction output when the scan was done"},
|
||||
}},
|
||||
}},
|
||||
{RPCResult::Type::STR_AMOUNT, "total_amount", "The total amount of all found unspent outputs in " + CURRENCY_UNIT},
|
||||
|
@ -2292,17 +2294,20 @@ static RPCHelpMan scantxoutset()
|
|||
const COutPoint& outpoint = it.first;
|
||||
const Coin& coin = it.second;
|
||||
const CTxOut& txo = coin.out;
|
||||
const CBlockIndex& coinb_block{*CHECK_NONFATAL(tip->GetAncestor(coin.nHeight))};
|
||||
input_txos.push_back(txo);
|
||||
total_in += txo.nValue;
|
||||
|
||||
UniValue unspent(UniValue::VOBJ);
|
||||
unspent.pushKV("txid", outpoint.hash.GetHex());
|
||||
unspent.pushKV("vout", (int32_t)outpoint.n);
|
||||
unspent.pushKV("vout", outpoint.n);
|
||||
unspent.pushKV("scriptPubKey", HexStr(txo.scriptPubKey));
|
||||
unspent.pushKV("desc", descriptors[txo.scriptPubKey]);
|
||||
unspent.pushKV("amount", ValueFromAmount(txo.nValue));
|
||||
unspent.pushKV("coinbase", coin.IsCoinBase());
|
||||
unspent.pushKV("height", (int32_t)coin.nHeight);
|
||||
unspent.pushKV("height", coin.nHeight);
|
||||
unspent.pushKV("blockhash", coinb_block.GetBlockHash().GetHex());
|
||||
unspent.pushKV("confirmations", tip->nHeight - coin.nHeight + 1);
|
||||
|
||||
unspents.push_back(std::move(unspent));
|
||||
}
|
||||
|
|
|
@ -120,7 +120,15 @@ class ScantxoutsetTest(BitcoinTestFramework):
|
|||
assert_equal(self.nodes[0].scantxoutset("status"), None)
|
||||
assert_equal(self.nodes[0].scantxoutset("abort"), False)
|
||||
|
||||
# check that first arg is needed
|
||||
# Check that the blockhash and confirmations fields are correct
|
||||
self.generate(self.nodes[0], 2)
|
||||
unspent = self.nodes[0].scantxoutset("start", ["addr(mpQ8rokAhp1TAtJQR6F6TaUmjAWkAWYYBq)"])["unspents"][0]
|
||||
blockhash = self.nodes[0].getblockhash(info["height"])
|
||||
assert_equal(unspent["height"], info["height"])
|
||||
assert_equal(unspent["blockhash"], blockhash)
|
||||
assert_equal(unspent["confirmations"], 3)
|
||||
|
||||
# Check that first arg is needed
|
||||
assert_raises_rpc_error(-1, "scantxoutset \"action\" ( [scanobjects,...] )", self.nodes[0].scantxoutset)
|
||||
|
||||
# Check that second arg is needed for start
|
||||
|
|
Loading…
Reference in a new issue