From 2ddeb90cac23b5caad12901e4b2c405caa494bd3 Mon Sep 17 00:00:00 2001 From: Block Mechanic Date: Tue, 14 Jun 2022 02:48:38 +0200 Subject: [PATCH] Fix filters and asset recog --- src/assetdb.cpp | 13 +++++- src/assetdb.h | 2 +- src/init.cpp | 28 ++++++++++++- src/interfaces/chain.cpp | 2 +- src/rpc/contracts.cpp | 84 ++++++++++++++++++++++++++++++++++++-- src/rpc/rawtransaction.cpp | 1 + src/validation.cpp | 29 +++---------- src/validation.h | 3 +- src/wallet/rpcwallet.cpp | 11 +++-- src/wallet/wallet.cpp | 36 ++++++++-------- 10 files changed, 153 insertions(+), 56 deletions(-) diff --git a/src/assetdb.cpp b/src/assetdb.cpp index ba6dcb5..3ed61ea 100755 --- a/src/assetdb.cpp +++ b/src/assetdb.cpp @@ -23,7 +23,9 @@ CAssetData::CAssetData(const CAsset& _asset, const CTransactionRef& assetTx, con asset = _asset; nTime = _nTime; txhash = assetTx->GetHash(); - CTxOutAsset txout = assetTx->vpout[nOut]; + //CTxOutAsset txout = assetTx->vpout[nOut]; + CTxOutAsset txout = (assetTx->nVersion >= TX_ELE_VERSION ? assetTx->vpout[nOut] : assetTx->vout[nOut]); + issuingAddress = txout.scriptPubKey; if(txout.nValue) issuedAmount = txout.nValue; @@ -188,3 +190,12 @@ CAsset GetAsset(const std::string& name) } return cCheck; } + +std::vector GetAllAssets(){ + std::vector tmp; + + for(auto const& x : passetsCache->GetItemsMap()) + tmp.push_back(x.second->second.asset); + + return tmp; +} diff --git a/src/assetdb.h b/src/assetdb.h index 1f6f731..d3d7192 100755 --- a/src/assetdb.h +++ b/src/assetdb.h @@ -77,5 +77,5 @@ extern CLRUCache *passetsCache; void DumpAssets(); CAsset GetAsset(const std::string& name); - +std::vector GetAllAssets(); #endif //CROWN_ASSETDB_H diff --git a/src/init.cpp b/src/init.cpp index dad4219..20faf75 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -387,6 +387,28 @@ static void OnRPCStopped() LogPrint(BCLog::RPC, "RPC stopped.\n"); } +void checkAndAddDefaultAsset(){ + bool exists = false, dummy = false; + CAsset asset = Params().GetConsensus().subsidy_asset; + for(auto const& x : passetsCache->GetItemsMap()){ + CAsset checkasset = x.second->second.asset; + if(iequals(asset.getName(), checkasset.getName()) || iequals(asset.getName(), checkasset.getSymbol())) + exists = true; + if(iequals("", checkasset.getName()) || iequals("", checkasset.getSymbol())) + dummy = true; + } + CCoinsViewCache view(&::ChainstateActive().CoinsTip()); + if (!exists && !passetsCache->Exists(asset.getName())){ + LogPrintf("NOTIFICATION: %s: ADDING ASSET %s\n", __func__, asset.getName()); + passetsCache->Put(asset.getName(), CAssetData(asset, Params().GenesisBlock().vtx[0], 0, view, Params().GenesisBlock().nTime)); + } + + if (dummy){ + LogPrintf("NOTIFICATION: %s: REMOVING DUMMY ASSET \n", __func__); + passetsCache->Erase(""); + } +} + void SetupServerArgs(NodeContext& node) { assert(!node.args); @@ -612,7 +634,7 @@ void SetupServerArgs(NodeContext& node) argsman.AddArg("-systemnodeprivkey", "Systemnode private key", false, OptionsCategory::RPC); argsman.AddArg("-systemnodeaddr", strprintf(_("Set external address:port to get to this systemnode (example: %s)").translated, "1.2.3.4:12345"), false, OptionsCategory::RPC); argsman.AddArg("-sporkkey", strprintf(_("Set spork key (example: %s)").translated, "xxxxxxxxxxxxxxxxxxxxxx"), false, OptionsCategory::RPC); - + #if HAVE_DECL_DAEMON argsman.AddArg("-daemon", "Run in the background as a daemon and accept commands", ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); #else @@ -1381,7 +1403,7 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA LogPrintf("Script verification uses %d additional threads\n", script_threads); if (script_threads >= 1) { g_parallel_script_checks = true; - StartScriptCheckWorkerThreads(script_threads); + StartScriptCheckWorkerThreads(script_threads); } assert(!node.scheduler); @@ -2152,6 +2174,8 @@ bool AppInitMain(const util::Ref& context, NodeContext& node, interfaces::BlockA client->start(*node.scheduler); } + checkAndAddDefaultAsset(); + BanMan* banman = node.banman.get(); node.scheduler->scheduleEvery([banman]{ banman->DumpBanlist(); diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index 9f7c025..a3040ab 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -5,7 +5,7 @@ #include #include #include - +#include #include #include #include diff --git a/src/rpc/contracts.cpp b/src/rpc/contracts.cpp index 7d56560..fd1ac5c 100755 --- a/src/rpc/contracts.cpp +++ b/src/rpc/contracts.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -101,10 +102,10 @@ static RPCHelpMan createcontract() {"address", RPCArg::Type::STR, RPCArg::Optional::NO, "Issuing address"}, {"name", RPCArg::Type::STR, RPCArg::Optional::NO, "Max 10 characters"}, {"short_name", RPCArg::Type::STR, RPCArg::Optional::NO, "Max 4 characters"}, - {"contract_url", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "contract location online"}, - {"website_url", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Issuer website online"}, - {"description", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "contract decription"}, - {"scriptcode", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "contract script in hex"}, + {"contract_url", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "contract location online"}, + {"website_url", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "Issuer website online"}, + {"description", RPCArg::Type::STR, RPCArg::Optional::OMITTED, "contract decription"}, + {"scriptcode", RPCArg::Type::STR_HEX, RPCArg::Optional::OMITTED, "contract script in hex"}, }, RPCResult{ RPCResult::Type::STR, "signature", "The signature of the message encoded in base 64" @@ -252,6 +253,79 @@ static RPCHelpMan getasset() }; } +static RPCHelpMan getassets() +{ + return RPCHelpMan{"getassets", + "\n Get List of assets \n", + { + }, + RPCResult{ + RPCResult::Type::STR, "details", "The assets " + }, + RPCExamples{ + "\nRetrieve a asset\n" + + HelpExampleCli("getassets", "\"Asset Name\"") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("getassets", "\"Asset Name\"") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ + std::vector allassets = ::GetAllAssets(); + + UniValue result(UniValue::VARR); + for(auto asset : allassets){ + + UniValue entry(UniValue::VOBJ); + + entry.pushKV("version", (int)asset.nVersion); + uint32_t type = asset.GetType(); + entry.pushKV("type", AssetTypeToString(type)); + entry.pushKV("name", asset.getAssetName()); + entry.pushKV("symbol", asset.getShortName()); + entry.pushKV("id", asset.GetHex()); + entry.pushKV("contract_hash", asset.contract_hash.GetHex()); + entry.pushKV("expiry", (int64_t)asset.GetExpiry()); + entry.pushKV("transferable", asset.isTransferable() ? "yes" : "no"); + entry.pushKV("convertable", asset.isConvertable() ? "yes" : "no"); + entry.pushKV("limited", asset.isLimited() ? "yes" : "no"); + entry.pushKV("restricted", asset.isRestricted() ? "yes" : "no"); + entry.pushKV("stakeable", asset.isStakeable() ? "yes" : "no"); + entry.pushKV("inflation", asset.isInflatable() ? "yes" : "no"); + + result.push_back(entry); + } + + return result; +}, + }; +} + +static RPCHelpMan getnumassets() +{ + return RPCHelpMan{"getnumassets", + "\n Get List of assets \n", + { + }, + RPCResult{ + RPCResult::Type::STR, "details", "The assets " + }, + RPCExamples{ + "\nRetrieve a asset\n" + + HelpExampleCli("getnumassets", "\"Asset Name\"") + + "\nAs a JSON-RPC call\n" + + HelpExampleRpc("getnumassets", "\"Asset Name\"") + }, + [&](const RPCHelpMan& self, const JSONRPCRequest& request) -> UniValue +{ + std::vector allassets = ::GetAllAssets(); + UniValue deets(UniValue::VOBJ); + deets.pushKV("Asset count", allassets.size()); + + return deets; +}, + }; +} + void RegisterContractRPCCommands(CRPCTable &t) { // clang-format off @@ -263,6 +337,8 @@ static const CRPCCommand commands[] = { "contracts", "createcontract", &createcontract, {} }, { "contracts", "createasset", &createasset, {} }, { "contracts", "getasset", &getasset, {} }, + { "contracts", "getassets", &getassets, {} }, + { "contracts", "getnumassets", &getnumassets, {} }, }; diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index cc94c83..be6e98d 100644 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include diff --git a/src/validation.cpp b/src/validation.cpp index c1c9ab3..c023430 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -2742,6 +2742,7 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, CAsset asset = out.nAsset; bool exists = false; + LogPrintf("NOTIFICATION: %s: FOUND ASSET %s\n", __func__, asset.ToString()); for(auto const& x : passetsCache->GetItemsMap()){ CAsset checkasset = x.second->second.asset; @@ -2750,10 +2751,12 @@ bool CChainState::ConnectBlock(const CBlock& block, BlockValidationState& state, exists = true; } - if (!exists && !passetsCache->Exists(asset.getName())) - if(!fJustCheck) + if (!exists && !passetsCache->Exists(asset.getName())){ + if(!fJustCheck){ + LogPrintf("NOTIFICATION: %s: ADDING ASSET %s\n", __func__, asset.getName()); passetsCache->Put(asset.getName(), CAssetData(asset, tx, j, view, block.nTime)); - + } + } } for (unsigned int i = 0; i < tx->vdata.size(); i++){ @@ -5933,26 +5936,6 @@ double GuessVerificationProgress(const ChainTxData& data, const CBlockIndex *pin return std::min(pindex->nChainTx / fTxTotal, 1.0); } -CAsset GetAsset(std::string asset){ - CAsset tmp; - - for(auto const& x : passetsCache->GetItemsMap()){ - if(x.second->second.asset.getName() == asset) - tmp = x.second->second.asset; - } - - return tmp; -} - -std::vector GetAllAssets(){ - std::vector tmp; - - for(auto const& x : passetsCache->GetItemsMap()) - tmp.push_back(x.second->second.asset); - - return tmp; -} - std::optional ChainstateManager::SnapshotBlockhash() const { if (m_active_chainstate != nullptr) { // If a snapshot chainstate exists, it will always be our active. diff --git a/src/validation.h b/src/validation.h index 6851165..65cf50e 100644 --- a/src/validation.h +++ b/src/validation.h @@ -1018,6 +1018,5 @@ inline bool IsBlockPruned(const CBlockIndex* pblockindex) bool GetUTXOCoin(const COutPoint& outpoint, Coin& coin); int GetUTXOHeight(const COutPoint& outpoint); int GetUTXOConfirmations(const COutPoint& outpoint); -CAsset GetAsset(std::string asset); -std::vector GetAllAssets(); + #endif // CROWN_VALIDATION_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index ae040bf..4ad4ab4 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -492,15 +492,14 @@ static RPCHelpMan sendtoaddress() LOCK(pwallet->cs_wallet); CAsset asset; - if (!request.params[2].isNull() && !request.params[2].get_str().empty()) { + + if (request.params[2].get_str().empty() || request.params[2].isNull()) + asset = Params().GetConsensus().subsidy_asset; + else asset = pwallet->chain().getAsset(request.params[2].get_str()); - } - else if (request.params[2].get_str().empty()){ - asset = Params().GetConsensus().subsidy_asset; - } if (asset.IsNull()) { - throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Unknown label and invalid asset hex: %s %s", asset.GetHex(), asset.getName())); + throw JSONRPCError(RPC_WALLET_ERROR, strprintf("Unknown or invalid asset: %s %s", asset.GetHex(), asset.getName())); } // Wallet comments diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 4b8ac5d..57e2b1d 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2011,15 +2011,17 @@ CAmountMap CWalletTx::GetImmatureCredit(bool fUseCache) const if (IsImmatureCoinBase() && IsInMainChain()) { for(unsigned int i = 0; i < (tx->nVersion >= TX_ELE_VERSION ? tx->vpout.size() : tx->vout.size()) ; i++){ + if (pwallet->IsMine((tx->nVersion >= TX_ELE_VERSION ? tx->vpout[i] : tx->vout[i])) & ISMINE_SPENDABLE) { //nCredit += pwallet->GetCredit(txout, filter); - CAmount credit = (tx->nVersion >= TX_ELE_VERSION ? tx->vpout[i].nValue : tx->vout[i].nValue); - if (!MoneyRange(credit)) - throw std::runtime_error(std::string(__func__) + " : value out of range"); + CAmount credit = (tx->nVersion >= TX_ELE_VERSION ? tx->vpout[i].nValue : tx->vout[i].nValue); + if (!MoneyRange(credit)) + throw std::runtime_error(std::string(__func__) + " : value out of range"); - if(tx->nVersion >= TX_ELE_VERSION) - nCredit[tx->vpout[i].nAsset] += credit; - else - nCredit[Params().GetConsensus().subsidy_asset] += credit; + if(tx->nVersion >= TX_ELE_VERSION) + nCredit[tx->vpout[i].nAsset] += credit; + else + nCredit[Params().GetConsensus().subsidy_asset] += credit; + } } } @@ -2046,17 +2048,19 @@ CAmountMap CWalletTx::GetAvailableCredit(bool fUseCache, const isminefilter& fil CAmountMap nCredit; uint256 hashTx = GetHash(); for(unsigned int i = 0; i < (tx->nVersion >= TX_ELE_VERSION ? tx->vpout.size() : tx->vout.size()) ; i++){ + if (pwallet->IsMine((tx->nVersion >= TX_ELE_VERSION ? tx->vpout[i] : tx->vout[i])) & ISMINE_SPENDABLE) { - if (!pwallet->IsSpent(hashTx, i) && (allow_used_addresses || !pwallet->IsSpentKey(hashTx, i))) { - //nCredit += pwallet->GetCredit(txout, filter); - CAmount credit = (tx->nVersion >= TX_ELE_VERSION ? tx->vpout[i].nValue : tx->vout[i].nValue); - if (!MoneyRange(credit)) - throw std::runtime_error(std::string(__func__) + " : value out of range"); + if (!pwallet->IsSpent(hashTx, i) && (allow_used_addresses || !pwallet->IsSpentKey(hashTx, i))) { + //nCredit += pwallet->GetCredit(txout, filter); + CAmount credit = (tx->nVersion >= TX_ELE_VERSION ? tx->vpout[i].nValue : tx->vout[i].nValue); + if (!MoneyRange(credit)) + throw std::runtime_error(std::string(__func__) + " : value out of range"); - if(tx->nVersion >= TX_ELE_VERSION) - nCredit[tx->vpout[i].nAsset] += credit; - else - nCredit[Params().GetConsensus().subsidy_asset] += credit; + if(tx->nVersion >= TX_ELE_VERSION) + nCredit[tx->vpout[i].nAsset] += credit; + else + nCredit[Params().GetConsensus().subsidy_asset] += credit; + } } }