mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-25 10:43:19 -03:00
Include coinbase transactions in receivedby wallet rpcs
This commit is contained in:
parent
dca9ab48b8
commit
bce20c34d6
2 changed files with 56 additions and 13 deletions
|
@ -46,13 +46,17 @@ static const CRPCConvertParam vRPCConvertParams[] =
|
|||
{ "settxfee", 0, "amount" },
|
||||
{ "sethdseed", 0, "newkeypool" },
|
||||
{ "getreceivedbyaddress", 1, "minconf" },
|
||||
{ "getreceivedbyaddress", 2, "include_immature_coinbase" },
|
||||
{ "getreceivedbylabel", 1, "minconf" },
|
||||
{ "getreceivedbylabel", 2, "include_immature_coinbase" },
|
||||
{ "listreceivedbyaddress", 0, "minconf" },
|
||||
{ "listreceivedbyaddress", 1, "include_empty" },
|
||||
{ "listreceivedbyaddress", 2, "include_watchonly" },
|
||||
{ "listreceivedbyaddress", 4, "include_immature_coinbase" },
|
||||
{ "listreceivedbylabel", 0, "minconf" },
|
||||
{ "listreceivedbylabel", 1, "include_empty" },
|
||||
{ "listreceivedbylabel", 2, "include_watchonly" },
|
||||
{ "listreceivedbylabel", 3, "include_immature_coinbase" },
|
||||
{ "getbalance", 1, "minconf" },
|
||||
{ "getbalance", 2, "include_watchonly" },
|
||||
{ "getbalance", 3, "avoid_reuse" },
|
||||
|
|
|
@ -528,11 +528,26 @@ static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool b
|
|||
if (!params[1].isNull())
|
||||
min_depth = params[1].get_int();
|
||||
|
||||
const bool include_immature_coinbase{params[2].isNull() ? false : params[2].get_bool()};
|
||||
|
||||
// Excluding coinbase outputs is deprecated
|
||||
// It can be enabled by setting deprecatedrpc=exclude_coinbase
|
||||
const bool include_coinbase{!wallet.chain().rpcEnableDeprecated("exclude_coinbase")};
|
||||
|
||||
if (include_immature_coinbase && !include_coinbase) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "include_immature_coinbase is incompatible with deprecated exclude_coinbase");
|
||||
}
|
||||
|
||||
// Tally
|
||||
CAmount amount = 0;
|
||||
for (const std::pair<const uint256, CWalletTx>& wtx_pair : wallet.mapWallet) {
|
||||
const CWalletTx& wtx = wtx_pair.second;
|
||||
if (wtx.IsCoinBase() || !wallet.chain().checkFinalTx(*wtx.tx) || wallet.GetTxDepthInMainChain(wtx) < min_depth) {
|
||||
int depth{wallet.GetTxDepthInMainChain(wtx)};
|
||||
if (depth < min_depth
|
||||
// Coinbase with less than 1 confirmation is no longer in the main chain
|
||||
|| (wtx.IsCoinBase() && (depth < 1 || !include_coinbase))
|
||||
|| (wallet.IsTxImmatureCoinBase(wtx) && !include_immature_coinbase)
|
||||
|| !wallet.chain().checkFinalTx(*wtx.tx)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -555,6 +570,7 @@ static RPCHelpMan getreceivedbyaddress()
|
|||
{
|
||||
{"address", RPCArg::Type::STR, RPCArg::Optional::NO, "The bitcoin address for transactions."},
|
||||
{"minconf", RPCArg::Type::NUM, RPCArg::Default{1}, "Only include transactions confirmed at least this many times."},
|
||||
{"include_immature_coinbase", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include immature coinbase transactions."},
|
||||
},
|
||||
RPCResult{
|
||||
RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " received at this address."
|
||||
|
@ -566,6 +582,8 @@ static RPCHelpMan getreceivedbyaddress()
|
|||
+ HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 0") +
|
||||
"\nThe amount with at least 6 confirmations\n"
|
||||
+ HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 6") +
|
||||
"\nThe amount with at least 6 confirmations including immature coinbase outputs\n"
|
||||
+ HelpExampleCli("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\" 6 true") +
|
||||
"\nAs a JSON-RPC call\n"
|
||||
+ HelpExampleRpc("getreceivedbyaddress", "\"" + EXAMPLE_ADDRESS[0] + "\", 6")
|
||||
},
|
||||
|
@ -593,6 +611,7 @@ static RPCHelpMan getreceivedbylabel()
|
|||
{
|
||||
{"label", RPCArg::Type::STR, RPCArg::Optional::NO, "The selected label, may be the default label using \"\"."},
|
||||
{"minconf", RPCArg::Type::NUM, RPCArg::Default{1}, "Only include transactions confirmed at least this many times."},
|
||||
{"include_immature_coinbase", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include immature coinbase transactions."},
|
||||
},
|
||||
RPCResult{
|
||||
RPCResult::Type::STR_AMOUNT, "amount", "The total amount in " + CURRENCY_UNIT + " received for this label."
|
||||
|
@ -604,8 +623,10 @@ static RPCHelpMan getreceivedbylabel()
|
|||
+ HelpExampleCli("getreceivedbylabel", "\"tabby\" 0") +
|
||||
"\nThe amount with at least 6 confirmations\n"
|
||||
+ HelpExampleCli("getreceivedbylabel", "\"tabby\" 6") +
|
||||
"\nThe amount with at least 6 confirmations including immature coinbase outputs\n"
|
||||
+ HelpExampleCli("getreceivedbylabel", "\"tabby\" 6 true") +
|
||||
"\nAs a JSON-RPC call\n"
|
||||
+ HelpExampleRpc("getreceivedbylabel", "\"tabby\", 6")
|
||||
+ HelpExampleRpc("getreceivedbylabel", "\"tabby\", 6, true")
|
||||
},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||
{
|
||||
|
@ -894,7 +915,7 @@ struct tallyitem
|
|||
}
|
||||
};
|
||||
|
||||
static UniValue ListReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
|
||||
static UniValue ListReceived(const CWallet& wallet, const UniValue& params, const bool by_label, const bool include_immature_coinbase) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
|
||||
{
|
||||
// Minimum confirmations
|
||||
int nMinDepth = 1;
|
||||
|
@ -914,7 +935,7 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, bool
|
|||
|
||||
bool has_filtered_address = false;
|
||||
CTxDestination filtered_address = CNoDestination();
|
||||
if (!by_label && params.size() > 3) {
|
||||
if (!by_label && !params[3].isNull() && !params[3].get_str().empty()) {
|
||||
if (!IsValidDestinationString(params[3].get_str())) {
|
||||
throw JSONRPCError(RPC_WALLET_ERROR, "address_filter parameter was invalid");
|
||||
}
|
||||
|
@ -922,19 +943,30 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, bool
|
|||
has_filtered_address = true;
|
||||
}
|
||||
|
||||
// Excluding coinbase outputs is deprecated
|
||||
// It can be enabled by setting deprecatedrpc=exclude_coinbase
|
||||
const bool include_coinbase{!wallet.chain().rpcEnableDeprecated("exclude_coinbase")};
|
||||
|
||||
if (include_immature_coinbase && !include_coinbase) {
|
||||
throw JSONRPCError(RPC_INVALID_PARAMETER, "include_immature_coinbase is incompatible with deprecated exclude_coinbase");
|
||||
}
|
||||
|
||||
// Tally
|
||||
std::map<CTxDestination, tallyitem> mapTally;
|
||||
for (const std::pair<const uint256, CWalletTx>& pairWtx : wallet.mapWallet) {
|
||||
const CWalletTx& wtx = pairWtx.second;
|
||||
|
||||
if (wtx.IsCoinBase() || !wallet.chain().checkFinalTx(*wtx.tx)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int nDepth = wallet.GetTxDepthInMainChain(wtx);
|
||||
if (nDepth < nMinDepth)
|
||||
continue;
|
||||
|
||||
// Coinbase with less than 1 confirmation is no longer in the main chain
|
||||
if ((wtx.IsCoinBase() && (nDepth < 1 || !include_coinbase))
|
||||
|| (wallet.IsTxImmatureCoinBase(wtx) && !include_immature_coinbase)
|
||||
|| !wallet.chain().checkFinalTx(*wtx.tx)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const CTxOut& txout : wtx.tx->vout)
|
||||
{
|
||||
CTxDestination address;
|
||||
|
@ -1049,7 +1081,8 @@ static RPCHelpMan listreceivedbyaddress()
|
|||
{"minconf", RPCArg::Type::NUM, RPCArg::Default{1}, "The minimum number of confirmations before payments are included."},
|
||||
{"include_empty", RPCArg::Type::BOOL, RPCArg::Default{false}, "Whether to include addresses that haven't received any payments."},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, RPCArg::DefaultHint{"true for watch-only wallets, otherwise false"}, "Whether to include watch-only addresses (see 'importaddress')"},
|
||||
{"address_filter", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "If present, only return information on this address."},
|
||||
{"address_filter", RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, "If present and non-empty, only return information on this address."},
|
||||
{"include_immature_coinbase", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include immature coinbase transactions."},
|
||||
},
|
||||
RPCResult{
|
||||
RPCResult::Type::ARR, "", "",
|
||||
|
@ -1071,8 +1104,9 @@ static RPCHelpMan listreceivedbyaddress()
|
|||
RPCExamples{
|
||||
HelpExampleCli("listreceivedbyaddress", "")
|
||||
+ HelpExampleCli("listreceivedbyaddress", "6 true")
|
||||
+ HelpExampleCli("listreceivedbyaddress", "6 true true \"\" true")
|
||||
+ HelpExampleRpc("listreceivedbyaddress", "6, true, true")
|
||||
+ HelpExampleRpc("listreceivedbyaddress", "6, true, true, \"" + EXAMPLE_ADDRESS[0] + "\"")
|
||||
+ HelpExampleRpc("listreceivedbyaddress", "6, true, true, \"" + EXAMPLE_ADDRESS[0] + "\", true")
|
||||
},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||
{
|
||||
|
@ -1083,9 +1117,11 @@ static RPCHelpMan listreceivedbyaddress()
|
|||
// the user could have gotten from another RPC command prior to now
|
||||
pwallet->BlockUntilSyncedToCurrentChain();
|
||||
|
||||
const bool include_immature_coinbase{request.params[4].isNull() ? false : request.params[4].get_bool()};
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
||||
return ListReceived(*pwallet, request.params, false);
|
||||
return ListReceived(*pwallet, request.params, false, include_immature_coinbase);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -1098,6 +1134,7 @@ static RPCHelpMan listreceivedbylabel()
|
|||
{"minconf", RPCArg::Type::NUM, RPCArg::Default{1}, "The minimum number of confirmations before payments are included."},
|
||||
{"include_empty", RPCArg::Type::BOOL, RPCArg::Default{false}, "Whether to include labels that haven't received any payments."},
|
||||
{"include_watchonly", RPCArg::Type::BOOL, RPCArg::DefaultHint{"true for watch-only wallets, otherwise false"}, "Whether to include watch-only addresses (see 'importaddress')"},
|
||||
{"include_immature_coinbase", RPCArg::Type::BOOL, RPCArg::Default{false}, "Include immature coinbase transactions."},
|
||||
},
|
||||
RPCResult{
|
||||
RPCResult::Type::ARR, "", "",
|
||||
|
@ -1114,7 +1151,7 @@ static RPCHelpMan listreceivedbylabel()
|
|||
RPCExamples{
|
||||
HelpExampleCli("listreceivedbylabel", "")
|
||||
+ HelpExampleCli("listreceivedbylabel", "6 true")
|
||||
+ HelpExampleRpc("listreceivedbylabel", "6, true, true")
|
||||
+ HelpExampleRpc("listreceivedbylabel", "6, true, true, true")
|
||||
},
|
||||
[&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
|
||||
{
|
||||
|
@ -1125,9 +1162,11 @@ static RPCHelpMan listreceivedbylabel()
|
|||
// the user could have gotten from another RPC command prior to now
|
||||
pwallet->BlockUntilSyncedToCurrentChain();
|
||||
|
||||
const bool include_immature_coinbase{request.params[3].isNull() ? false : request.params[3].get_bool()};
|
||||
|
||||
LOCK(pwallet->cs_wallet);
|
||||
|
||||
return ListReceived(*pwallet, request.params, true);
|
||||
return ListReceived(*pwallet, request.params, true, include_immature_coinbase);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue