@@ -528,11 +528,26 @@ static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool b
528528 if (!params[1 ].isNull ())
529529 min_depth = params[1 ].get_int ();
530530
531+ const bool include_immature_coinbase{params[2 ].isNull () ? false : params[2 ].get_bool ()};
532+
533+ // Excluding coinbase outputs is deprecated
534+ // It can be enabled by setting deprecatedrpc=exclude_coinbase
535+ const bool include_coinbase{!wallet.chain ().rpcEnableDeprecated (" exclude_coinbase" )};
536+
537+ if (include_immature_coinbase && !include_coinbase) {
538+ throw JSONRPCError (RPC_INVALID_PARAMETER, " include_immature_coinbase is incompatible with deprecated exclude_coinbase" );
539+ }
540+
531541 // Tally
532542 CAmount amount = 0 ;
533543 for (const std::pair<const uint256, CWalletTx>& wtx_pair : wallet.mapWallet ) {
534544 const CWalletTx& wtx = wtx_pair.second ;
535- if (wtx.IsCoinBase () || !wallet.chain ().checkFinalTx (*wtx.tx ) || wallet.GetTxDepthInMainChain (wtx) < min_depth) {
545+ int depth{wallet.GetTxDepthInMainChain (wtx)};
546+ if (depth < min_depth
547+ // Coinbase with less than 1 confirmation is no longer in the main chain
548+ || (wtx.IsCoinBase () && (depth < 1 || !include_coinbase))
549+ || (wallet.IsTxImmatureCoinBase (wtx) && !include_immature_coinbase)
550+ || !wallet.chain ().checkFinalTx (*wtx.tx )) {
536551 continue ;
537552 }
538553
@@ -555,6 +570,7 @@ static RPCHelpMan getreceivedbyaddress()
555570 {
556571 {" address" , RPCArg::Type::STR, RPCArg::Optional::NO, " The bitcoin address for transactions." },
557572 {" minconf" , RPCArg::Type::NUM, RPCArg::Default{1 }, " Only include transactions confirmed at least this many times." },
573+ {" include_immature_coinbase" , RPCArg::Type::BOOL, RPCArg::Default{false }, " Include immature coinbase transactions." },
558574 },
559575 RPCResult{
560576 RPCResult::Type::STR_AMOUNT, " amount" , " The total amount in " + CURRENCY_UNIT + " received at this address."
@@ -566,6 +582,8 @@ static RPCHelpMan getreceivedbyaddress()
566582 + HelpExampleCli (" getreceivedbyaddress" , " \" " + EXAMPLE_ADDRESS[0 ] + " \" 0" ) +
567583 " \n The amount with at least 6 confirmations\n "
568584 + HelpExampleCli (" getreceivedbyaddress" , " \" " + EXAMPLE_ADDRESS[0 ] + " \" 6" ) +
585+ " \n The amount with at least 6 confirmations including immature coinbase outputs\n "
586+ + HelpExampleCli (" getreceivedbyaddress" , " \" " + EXAMPLE_ADDRESS[0 ] + " \" 6 true" ) +
569587 " \n As a JSON-RPC call\n "
570588 + HelpExampleRpc (" getreceivedbyaddress" , " \" " + EXAMPLE_ADDRESS[0 ] + " \" , 6" )
571589 },
@@ -593,6 +611,7 @@ static RPCHelpMan getreceivedbylabel()
593611 {
594612 {" label" , RPCArg::Type::STR, RPCArg::Optional::NO, " The selected label, may be the default label using \"\" ." },
595613 {" minconf" , RPCArg::Type::NUM, RPCArg::Default{1 }, " Only include transactions confirmed at least this many times." },
614+ {" include_immature_coinbase" , RPCArg::Type::BOOL, RPCArg::Default{false }, " Include immature coinbase transactions." },
596615 },
597616 RPCResult{
598617 RPCResult::Type::STR_AMOUNT, " amount" , " The total amount in " + CURRENCY_UNIT + " received for this label."
@@ -604,8 +623,10 @@ static RPCHelpMan getreceivedbylabel()
604623 + HelpExampleCli (" getreceivedbylabel" , " \" tabby\" 0" ) +
605624 " \n The amount with at least 6 confirmations\n "
606625 + HelpExampleCli (" getreceivedbylabel" , " \" tabby\" 6" ) +
626+ " \n The amount with at least 6 confirmations including immature coinbase outputs\n "
627+ + HelpExampleCli (" getreceivedbylabel" , " \" tabby\" 6 true" ) +
607628 " \n As a JSON-RPC call\n "
608- + HelpExampleRpc (" getreceivedbylabel" , " \" tabby\" , 6" )
629+ + HelpExampleRpc (" getreceivedbylabel" , " \" tabby\" , 6, true " )
609630 },
610631 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
611632{
@@ -894,7 +915,7 @@ struct tallyitem
894915 }
895916};
896917
897- static UniValue ListReceived (const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
918+ static UniValue ListReceived (const CWallet& wallet, const UniValue& params, const bool by_label, const bool include_immature_coinbase ) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
898919{
899920 // Minimum confirmations
900921 int nMinDepth = 1 ;
@@ -914,27 +935,38 @@ static UniValue ListReceived(const CWallet& wallet, const UniValue& params, bool
914935
915936 bool has_filtered_address = false ;
916937 CTxDestination filtered_address = CNoDestination ();
917- if (!by_label && params. size () > 3 ) {
938+ if (!by_label && ! params[ 3 ]. isNull () && !params[ 3 ]. get_str (). empty () ) {
918939 if (!IsValidDestinationString (params[3 ].get_str ())) {
919940 throw JSONRPCError (RPC_WALLET_ERROR, " address_filter parameter was invalid" );
920941 }
921942 filtered_address = DecodeDestination (params[3 ].get_str ());
922943 has_filtered_address = true ;
923944 }
924945
946+ // Excluding coinbase outputs is deprecated
947+ // It can be enabled by setting deprecatedrpc=exclude_coinbase
948+ const bool include_coinbase{!wallet.chain ().rpcEnableDeprecated (" exclude_coinbase" )};
949+
950+ if (include_immature_coinbase && !include_coinbase) {
951+ throw JSONRPCError (RPC_INVALID_PARAMETER, " include_immature_coinbase is incompatible with deprecated exclude_coinbase" );
952+ }
953+
925954 // Tally
926955 std::map<CTxDestination, tallyitem> mapTally;
927956 for (const std::pair<const uint256, CWalletTx>& pairWtx : wallet.mapWallet ) {
928957 const CWalletTx& wtx = pairWtx.second ;
929958
930- if (wtx.IsCoinBase () || !wallet.chain ().checkFinalTx (*wtx.tx )) {
931- continue ;
932- }
933-
934959 int nDepth = wallet.GetTxDepthInMainChain (wtx);
935960 if (nDepth < nMinDepth)
936961 continue ;
937962
963+ // Coinbase with less than 1 confirmation is no longer in the main chain
964+ if ((wtx.IsCoinBase () && (nDepth < 1 || !include_coinbase))
965+ || (wallet.IsTxImmatureCoinBase (wtx) && !include_immature_coinbase)
966+ || !wallet.chain ().checkFinalTx (*wtx.tx )) {
967+ continue ;
968+ }
969+
938970 for (const CTxOut& txout : wtx.tx ->vout )
939971 {
940972 CTxDestination address;
@@ -1049,7 +1081,8 @@ static RPCHelpMan listreceivedbyaddress()
10491081 {" minconf" , RPCArg::Type::NUM, RPCArg::Default{1 }, " The minimum number of confirmations before payments are included." },
10501082 {" include_empty" , RPCArg::Type::BOOL, RPCArg::Default{false }, " Whether to include addresses that haven't received any payments." },
10511083 {" include_watchonly" , RPCArg::Type::BOOL, RPCArg::DefaultHint{" true for watch-only wallets, otherwise false" }, " Whether to include watch-only addresses (see 'importaddress')" },
1052- {" address_filter" , RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, " If present, only return information on this address." },
1084+ {" address_filter" , RPCArg::Type::STR, RPCArg::Optional::OMITTED_NAMED_ARG, " If present and non-empty, only return information on this address." },
1085+ {" include_immature_coinbase" , RPCArg::Type::BOOL, RPCArg::Default{false }, " Include immature coinbase transactions." },
10531086 },
10541087 RPCResult{
10551088 RPCResult::Type::ARR, " " , " " ,
@@ -1071,8 +1104,9 @@ static RPCHelpMan listreceivedbyaddress()
10711104 RPCExamples{
10721105 HelpExampleCli (" listreceivedbyaddress" , " " )
10731106 + HelpExampleCli (" listreceivedbyaddress" , " 6 true" )
1107+ + HelpExampleCli (" listreceivedbyaddress" , " 6 true true \"\" true" )
10741108 + HelpExampleRpc (" listreceivedbyaddress" , " 6, true, true" )
1075- + HelpExampleRpc (" listreceivedbyaddress" , " 6, true, true, \" " + EXAMPLE_ADDRESS[0 ] + " \" " )
1109+ + HelpExampleRpc (" listreceivedbyaddress" , " 6, true, true, \" " + EXAMPLE_ADDRESS[0 ] + " \" , true " )
10761110 },
10771111 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
10781112{
@@ -1083,9 +1117,11 @@ static RPCHelpMan listreceivedbyaddress()
10831117 // the user could have gotten from another RPC command prior to now
10841118 pwallet->BlockUntilSyncedToCurrentChain ();
10851119
1120+ const bool include_immature_coinbase{request.params [4 ].isNull () ? false : request.params [4 ].get_bool ()};
1121+
10861122 LOCK (pwallet->cs_wallet );
10871123
1088- return ListReceived (*pwallet, request.params , false );
1124+ return ListReceived (*pwallet, request.params , false , include_immature_coinbase );
10891125},
10901126 };
10911127}
@@ -1098,6 +1134,7 @@ static RPCHelpMan listreceivedbylabel()
10981134 {" minconf" , RPCArg::Type::NUM, RPCArg::Default{1 }, " The minimum number of confirmations before payments are included." },
10991135 {" include_empty" , RPCArg::Type::BOOL, RPCArg::Default{false }, " Whether to include labels that haven't received any payments." },
11001136 {" include_watchonly" , RPCArg::Type::BOOL, RPCArg::DefaultHint{" true for watch-only wallets, otherwise false" }, " Whether to include watch-only addresses (see 'importaddress')" },
1137+ {" include_immature_coinbase" , RPCArg::Type::BOOL, RPCArg::Default{false }, " Include immature coinbase transactions." },
11011138 },
11021139 RPCResult{
11031140 RPCResult::Type::ARR, " " , " " ,
@@ -1114,7 +1151,7 @@ static RPCHelpMan listreceivedbylabel()
11141151 RPCExamples{
11151152 HelpExampleCli (" listreceivedbylabel" , " " )
11161153 + HelpExampleCli (" listreceivedbylabel" , " 6 true" )
1117- + HelpExampleRpc (" listreceivedbylabel" , " 6, true, true" )
1154+ + HelpExampleRpc (" listreceivedbylabel" , " 6, true, true, true " )
11181155 },
11191156 [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue
11201157{
@@ -1125,9 +1162,11 @@ static RPCHelpMan listreceivedbylabel()
11251162 // the user could have gotten from another RPC command prior to now
11261163 pwallet->BlockUntilSyncedToCurrentChain ();
11271164
1165+ const bool include_immature_coinbase{request.params [3 ].isNull () ? false : request.params [3 ].get_bool ()};
1166+
11281167 LOCK (pwallet->cs_wallet );
11291168
1130- return ListReceived (*pwallet, request.params , true );
1169+ return ListReceived (*pwallet, request.params , true , include_immature_coinbase );
11311170},
11321171 };
11331172}
0 commit comments