From 346de0b019a1c5aadc2996d77f7486ef5efa0730 Mon Sep 17 00:00:00 2001 From: Peter Bushnell Date: Wed, 10 Nov 2021 14:14:23 +0000 Subject: [PATCH 01/12] Add vault history and getvaulthistory RPC call --- src/Makefile.am | 2 + src/init.cpp | 10 +- src/masternodes/accountshistory.cpp | 63 +++-- src/masternodes/accountshistory.h | 16 +- src/masternodes/mn_checks.cpp | 67 ++++-- src/masternodes/mn_checks.h | 7 +- src/masternodes/mn_rpc.cpp | 3 +- src/masternodes/rpc_customtx.cpp | 3 +- src/masternodes/rpc_vault.cpp | 174 ++++++++++++++ src/masternodes/vaulthistory.cpp | 25 ++ src/masternodes/vaulthistory.h | 78 +++++++ src/rpc/client.cpp | 1 + src/validation.cpp | 21 +- test/functional/rpc_getvaulthistory.py | 304 +++++++++++++++++++++++++ test/functional/test_runner.py | 1 + 15 files changed, 732 insertions(+), 43 deletions(-) create mode 100644 src/masternodes/vaulthistory.cpp create mode 100644 src/masternodes/vaulthistory.h create mode 100755 test/functional/rpc_getvaulthistory.py diff --git a/src/Makefile.am b/src/Makefile.am index 0bc3a6518e..6ef8328c34 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -179,6 +179,7 @@ DEFI_CORE_H = \ masternodes/undo.h \ masternodes/undos.h \ masternodes/vault.h \ + masternodes/vaulthistory.h \ memusage.h \ merkleblock.h \ miner.h \ @@ -404,6 +405,7 @@ libdefi_server_a_SOURCES = \ masternodes/skipped_txs.cpp \ masternodes/undos.cpp \ masternodes/vault.cpp \ + masternodes/vaulthistory.cpp \ miner.cpp \ net.cpp \ net_processing.cpp \ diff --git a/src/init.cpp b/src/init.cpp index 989450937f..bba94d87db 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -417,7 +418,8 @@ void SetupServerArgs() hidden_args.emplace_back("-sysperms"); #endif gArgs.AddArg("-txindex", strprintf("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)", DEFAULT_TXINDEX), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); - gArgs.AddArg("-acindex", strprintf("Maintain a full account history index, tracking all accounts balances changes. Used by the listaccounthistory and accounthistorycount rpc calls (default: %u)", false), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + gArgs.AddArg("-acindex", strprintf("Maintain a full account history index, tracking all accounts balances changes. Used by the listaccounthistory and accounthistorycount rpc calls (default: %u)", DEFAULT_ACINDEX), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); + gArgs.AddArg("-vaultindex", strprintf("Maintain a full vault history index, tracking all vault changes. Used by the getvaulthistory rpc call (default: %u)", DEFAULT_VAULTINDEX), ArgsManager::ALLOW_ANY, OptionsCategory::OPTIONS); gArgs.AddArg("-blockfilterindex=", strprintf("Maintain an index of compact filters by block (default: %s, values: %s).", DEFAULT_BLOCKFILTERINDEX, ListBlockFilterTypes()) + " If is not supplied or if = 1, indexes for all known types are enabled.", @@ -1630,6 +1632,12 @@ bool AppInitMain(InitInterfaces& interfaces) pburnHistoryDB.reset(); pburnHistoryDB = MakeUnique(GetDataDir() / "burn", nCustomCacheSize, false, fReset || fReindexChainState); + // Create vault history DB + pvaultHistoryDB.reset(); + if (gArgs.GetBoolArg("-vaultindex", DEFAULT_VAULTINDEX)) { + pvaultHistoryDB = MakeUnique(GetDataDir() / "vault", nCustomCacheSize, false, fReset || fReindexChainState); + } + // If necessary, upgrade from older database format. // This is a no-op if we cleared the coinsviewdb with -reindex or -reindex-chainstate if (!::ChainstateActive().CoinsDB().Upgrade()) { diff --git a/src/masternodes/accountshistory.cpp b/src/masternodes/accountshistory.cpp index ee08b4de7d..5a51365f7f 100644 --- a/src/masternodes/accountshistory.cpp +++ b/src/masternodes/accountshistory.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include void CAccountsHistoryView::ForEachAccountHistory(std::function)> callback, AccountHistoryKey const & start) @@ -34,20 +35,28 @@ CBurnHistoryStorage::CBurnHistoryStorage(const fs::path& dbName, std::size_t cac { } -CAccountsHistoryWriter::CAccountsHistoryWriter(CCustomCSView & storage, uint32_t height, uint32_t txn, const uint256& txid, uint8_t type, CAccountsHistoryView* historyView, CAccountsHistoryView* burnView) - : CStorageView(new CFlushableStorageKV(static_cast(storage.GetStorage()))), height(height), txn(txn), txid(txid), type(type), historyView(historyView), burnView(burnView) +CAccountsHistoryWriter::CAccountsHistoryWriter(CCustomCSView & storage, uint32_t height, uint32_t txn, const uint256& txid, uint8_t type, + CAccountsHistoryView* historyView, CAccountsHistoryView* burnView, CVaultHistoryView* vaultView, const uint256& vaultID) + : CStorageView(new CFlushableStorageKV(static_cast(storage.GetStorage()))), height(height), txn(txn), + txid(txid), type(type), historyView(historyView), burnView(burnView), vaultView(vaultView), vaultID(vaultID) { } Res CAccountsHistoryWriter::AddBalance(CScript const & owner, CTokenAmount amount) { auto res = CCustomCSView::AddBalance(owner, amount); - if (historyView && res.ok && amount.nValue != 0) { - diffs[owner][amount.nTokenId] += amount.nValue; - } - if (burnView && res.ok && amount.nValue != 0 && owner == Params().GetConsensus().burnAddress) { - burnDiffs[owner][amount.nTokenId] += amount.nValue; + if (amount.nValue != 0 && res.ok) { + if (historyView) { + diffs[owner][amount.nTokenId] += amount.nValue; + } + if (burnView && owner == Params().GetConsensus().burnAddress) { + burnDiffs[owner][amount.nTokenId] += amount.nValue; + } + if (vaultView && !vaultID.IsNull()) { + vaultDiffs[vaultID][owner][amount.nTokenId] += amount.nValue; + } } + return res; } @@ -62,12 +71,18 @@ Res CAccountsHistoryWriter::AddFeeBurn(CScript const & owner, CAmount amount) Res CAccountsHistoryWriter::SubBalance(CScript const & owner, CTokenAmount amount) { auto res = CCustomCSView::SubBalance(owner, amount); - if (historyView && res.ok && amount.nValue != 0) { - diffs[owner][amount.nTokenId] -= amount.nValue; - } - if (burnView && res.ok && amount.nValue != 0 && owner == Params().GetConsensus().burnAddress) { - burnDiffs[owner][amount.nTokenId] -= amount.nValue; + if (res.ok && amount.nValue != 0) { + if (historyView) { + diffs[owner][amount.nTokenId] -= amount.nValue; + } + if (burnView && owner == Params().GetConsensus().burnAddress) { + burnDiffs[owner][amount.nTokenId] -= amount.nValue; + } + if (vaultView && !vaultID.IsNull()) { + vaultDiffs[vaultID][owner][amount.nTokenId] -= amount.nValue; + } } + return res; } @@ -83,11 +98,20 @@ bool CAccountsHistoryWriter::Flush() burnView->WriteAccountHistory({diff.first, height, txn}, {txid, type, diff.second}); } } + if (vaultView) { + for (const auto& diff : vaultDiffs) { + for (const auto& addresses : diff.second) { + vaultView->WriteVaultHistory({diff.first, height, txn, addresses.first}, {txid, type, addresses.second}); + } + } + } return CCustomCSView::Flush(); } -CAccountsHistoryEraser::CAccountsHistoryEraser(CCustomCSView & storage, uint32_t height, uint32_t txn, CAccountsHistoryView* historyView, CAccountsHistoryView* burnView) - : CStorageView(new CFlushableStorageKV(static_cast(storage.GetStorage()))), height(height), txn(txn), historyView(historyView), burnView(burnView) +CAccountsHistoryEraser::CAccountsHistoryEraser(CCustomCSView & storage, uint32_t height, uint32_t txn, CAccountsHistoryView* historyView, + CAccountsHistoryView* burnView, CVaultHistoryView* vaultView, const uint256& vaultID) + : CStorageView(new CFlushableStorageKV(static_cast(storage.GetStorage()))), height(height), txn(txn), + historyView(historyView), burnView(burnView), vaultView(vaultView), vaultID(vaultID) { } @@ -99,6 +123,9 @@ Res CAccountsHistoryEraser::AddBalance(CScript const & owner, CTokenAmount) if (burnView && owner == Params().GetConsensus().burnAddress) { burnAccounts.insert(owner); } + if (vaultView && !vaultID.IsNull()) { + vaults.insert(vaultID); + } return Res::Ok(); } @@ -110,6 +137,9 @@ Res CAccountsHistoryEraser::SubBalance(CScript const & owner, CTokenAmount) if (burnView && owner == Params().GetConsensus().burnAddress) { burnAccounts.insert(owner); } + if (vaultView && !vaultID.IsNull()) { + vaults.insert(vaultID); + } return Res::Ok(); } @@ -133,6 +163,11 @@ bool CAccountsHistoryEraser::Flush() burnView->EraseAccountHistory({account, height, txn}); } } + if (vaultView) { + for (const auto& vault : vaults) { + vaultView->EraseVaultHistory({vault, height, txn}); + } + } return Res::Ok(); // makes sure no changes are applyed to underlaying view } diff --git a/src/masternodes/accountshistory.h b/src/masternodes/accountshistory.h index feda1bb4f3..bd504a0f50 100644 --- a/src/masternodes/accountshistory.h +++ b/src/masternodes/accountshistory.h @@ -12,6 +12,8 @@ #include