diff --git a/src/init.cpp b/src/init.cpp index b2fb076e96942..301ae53845eb4 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -259,7 +259,7 @@ void PrepareShutdown() pwallet->Flush(false); } #endif - miningManager->GenerateBitcoins(false, 0); + if (miningManager.get() != nullptr) miningManager->GenerateBitcoins(false, 0); MapPort(false); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index 6072e73bcb56c..f5f9eb065fc6a 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -1073,12 +1073,16 @@ static void ApplyStats(CCoinsStats &stats, CHashWriter& ss, const uint256& hash, ss << hash; ss << VARINT(outputs.begin()->second.nHeight * 4 + outputs.begin()->second.fCoinStake * 2 + outputs.begin()->second.fCoinBase); stats.nTransactions++; + for (const auto output : outputs) { ss << VARINT(output.first + 1); ss << output.second.out.scriptPubKey; ss << VARINT(output.second.out.nValue); stats.nTransactionOutputs++; - stats.nTotalAmount += output.second.out.nValue; + const CScript& script = output.second.out.scriptPubKey; + if (script.size() > 0 && script.size() < MAX_SCRIPT_SIZE && *script.begin() != OP_RETURN && *script.begin() != OP_ZEROCOINMINT) { + stats.nTotalAmount += output.second.out.nValue; + } stats.nBogoSize += 32 /* txid */ + 4 /* vout index */ + 4 /* height + coinbase */ + 8 /* amount */ + 2 /* scriptPubKey len */ + output.second.out.scriptPubKey.size() /* scriptPubKey */; } diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 790f43714f720..081a54aca9893 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -65,6 +65,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getbalance", 1, "minconf" }, { "getbalance", 2, "addlocked" }, { "getbalance", 3, "include_watchonly" }, + { "gettokenbalance", 2, "minconf" }, { "getchaintips", 0, "count" }, { "getchaintips", 1, "branchlen" }, { "getblockhash", 0, "height" }, @@ -84,6 +85,9 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listtransactionrecords", 1, "count" }, { "listtransactionrecords", 2, "skip" }, { "listtransactionrecords", 3, "include_watchonly" }, + { "listtokentransactions", 1, "count" }, + { "listtokentransactions", 2, "skip" }, + { "listtokentransactions", 3, "include_watchonly" }, { "listaccounts", 0, "minconf" }, { "listaccounts", 1, "addlocked" }, { "listaccounts", 2, "include_watchonly" }, @@ -93,6 +97,8 @@ static const CRPCConvertParam vRPCConvertParams[] = { "listsinceblock", 1, "target_confirmations" }, { "listsinceblock", 2, "include_watchonly" }, { "listsinceblock", 3, "include_removed" }, + { "listtokenssinceblock", 2, "target_confirmations" }, + { "listtokenssinceblock", 3, "include_watchonly" }, { "sendmany", 1, "amounts" }, { "sendmany", 2, "minconf" }, { "sendmany", 3, "addlocked" }, diff --git a/src/tokens/rpctokenwallet.cpp b/src/tokens/rpctokenwallet.cpp index b3dc0a0e6f964..31ae3466e0b51 100644 --- a/src/tokens/rpctokenwallet.cpp +++ b/src/tokens/rpctokenwallet.cpp @@ -390,13 +390,14 @@ extern UniValue gettokenbalance(const JSONRPCRequest& request) "\nArguments:\n" "1. \"groupid\" (string, optional) the token group identifier to filter\n" "2. \"address\" (string, optional) the ION address to filter\n" + "3. \"minconf\" (numeric, optional, default=1) Only include transactions confirmed at least this many times.\n" "\n" "\nExamples:\n" + HelpExampleCli("gettokenbalance", "groupid ionrt1zwm0kzlyptdmwy3849fd6z5epesnjkruqlwlv02u7y6ymf75nk4qs6u85re") + "\n" ); - if (request.params.size() > 2) + if (request.params.size() > 3) { throw std::runtime_error("Invalid number of argument to token balance"); } @@ -407,7 +408,7 @@ extern UniValue gettokenbalance(const JSONRPCRequest& request) { std::unordered_map balances; std::unordered_map authorities; - GetAllGroupBalancesAndAuthorities(pwallet, balances, authorities); + GetAllGroupBalancesAndAuthorities(pwallet, balances, authorities, 1); UniValue ret(UniValue::VARR); for (const auto &item : balances) { @@ -448,9 +449,15 @@ extern UniValue gettokenbalance(const JSONRPCRequest& request) { dst = DecodeDestination(request.params[curparam].get_str(), Params()); } + curparam++; + int nMinDepth = 0; + if (request.params.size() > curparam) + { + nMinDepth = request.params[curparam].get_int(); + } CAmount balance; GroupAuthorityFlags authorities; - GetGroupBalanceAndAuthorities(balance, authorities, grpID, dst, pwallet); + GetGroupBalanceAndAuthorities(balance, authorities, grpID, dst, pwallet, nMinDepth); UniValue retobj(UniValue::VOBJ); retobj.push_back(Pair("groupID", EncodeTokenGroup(grpID))); retobj.push_back(Pair("balance", tokenGroupManager->TokenValueFromAmount(balance, grpID))); @@ -469,10 +476,13 @@ extern UniValue listtokentransactions(const JSONRPCRequest& request) if (request.fHelp || request.params.size() > 4) throw std::runtime_error( - "listtokentransactions (\"groupid\")\n" + "listtokentransactions (\"groupid\" count skip include_watchonly)\n" "\nReturns transactions for given groupid.\n" "\nArguments:\n" - "1. \"groupid\" (string, required) the token group identifier.\n" + "1. \"groupid\" (string, required) the token group identifier.\n" + "2. count (numeric, optional, default=10) The number of transactions to return\n" + "3. skip (numeric, optional, default=0) The number of transactions to skip\n" + "4. include_watchonly (bool, optional, default=false) Include transactions to watch-only addresses (see 'importaddress')\n" "\nResult:\n" "[\n" " {\n" @@ -520,7 +530,7 @@ extern UniValue listtokentransactions(const JSONRPCRequest& request) unsigned int curparam = 0; std::string strAccount = "*"; - bool fAllGroups; + bool fAllGroups = true; CTokenGroupID grpID; if (request.params.size() > curparam) diff --git a/src/tokens/tokengroupwallet.cpp b/src/tokens/tokengroupwallet.cpp index d3fb989c949fc..0768cc0f06631 100644 --- a/src/tokens/tokengroupwallet.cpp +++ b/src/tokens/tokengroupwallet.cpp @@ -70,7 +70,7 @@ void GetAllGroupBalances(const CWallet *wallet, std::unordered_map &balances, std::unordered_map &authorities) +void GetAllGroupBalancesAndAuthorities(const CWallet *wallet, std::unordered_map &balances, std::unordered_map &authorities, const int nMinDepth) { std::vector coins; wallet->FilterCoins(coins, [&balances, &authorities](const CWalletTx *tx, const CTxOut *out) { @@ -87,7 +87,7 @@ void GetAllGroupBalancesAndAuthorities(const CWallet *wallet, std::unordered_map } } return false; // I don't want to actually filter anything - }); + }, nMinDepth); } void ListAllGroupAuthorities(const CWallet *wallet, std::vector &coins) { @@ -144,7 +144,7 @@ CAmount GetGroupBalance(const CTokenGroupID &grpID, const CTxDestination &dest, return balance; } -void GetGroupBalanceAndAuthorities(CAmount &balance, GroupAuthorityFlags &authorities, const CTokenGroupID &grpID, const CTxDestination &dest, const CWallet *wallet) +void GetGroupBalanceAndAuthorities(CAmount &balance, GroupAuthorityFlags &authorities, const CTokenGroupID &grpID, const CTxDestination &dest, const CWallet *wallet, const int nMinDepth) { std::vector coins; balance = 0; @@ -178,7 +178,7 @@ void GetGroupBalanceAndAuthorities(CAmount &balance, GroupAuthorityFlags &author } } return false; - }); + }, nMinDepth); } void GetGroupCoins(const CWallet *wallet, std::vector& coins, CAmount& balance, const CTokenGroupID &grpID, const CTxDestination &dest) { diff --git a/src/tokens/tokengroupwallet.h b/src/tokens/tokengroupwallet.h index 89794bfc79b62..20bd83e213ed1 100644 --- a/src/tokens/tokengroupwallet.h +++ b/src/tokens/tokengroupwallet.h @@ -21,11 +21,11 @@ CAmount GetGroupBalance(const CTokenGroupID &grpID, const CTxDestination &dest, // Returns a mapping of groupID->balance void GetAllGroupBalances(const CWallet *wallet, std::unordered_map &balances); void GetAllGroupBalancesAndAuthorities(const CWallet *wallet, std::unordered_map &balances, - std::unordered_map &authorities); + std::unordered_map &authorities, const int nMinDepth = 0); void ListAllGroupAuthorities(const CWallet *wallet, std::vector &coins); void ListGroupAuthorities(const CWallet *wallet, std::vector &coins, const CTokenGroupID &grpID); void GetGroupBalanceAndAuthorities(CAmount &balance, GroupAuthorityFlags &authorities, const CTokenGroupID &grpID, - const CTxDestination &dest, const CWallet *wallet); + const CTxDestination &dest, const CWallet *wallet, const int nMinDepth = 0); void GetGroupCoins(const CWallet *wallet, std::vector& coins, CAmount& balance, const CTokenGroupID &grpID, const CTxDestination &dest = CNoDestination()); void GetGroupAuthority(const CWallet *wallet, std::vector& coins, GroupAuthorityFlags flags, const CTokenGroupID &grpID, const CTxDestination &dest = CNoDestination()); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index d0b261d3cded6..508c43536193b 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2936,7 +2936,7 @@ CAmount CWallet::GetAvailableBalance(const CCoinControl* coinControl) const } unsigned int CWallet::FilterCoins(std::vector &vCoins, - std::function func) const + std::function func, int nMinDepth) const { vCoins.clear(); unsigned int ret = 0; @@ -2955,7 +2955,7 @@ unsigned int CWallet::FilterCoins(std::vector &vCoins, continue; int nDepth = pcoin->GetDepthInMainChain(); - if (nDepth < 0) + if (nDepth < nMinDepth) continue; // We should not consider coins which aren't at least in our mempool diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 8c1c0038fb201..ec9ffefe45056 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -947,7 +947,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface Returns the number of matches. */ unsigned int FilterCoins(std::vector &vCoins, - std::function) const; + std::function, int nMinDepth = 0) const; /** * Return list of available coins and locked coins grouped by non-change output address.