Skip to content

Commit

Permalink
Move CHistoryWriter into CCustomCSView (#1700)
Browse files Browse the repository at this point in the history
* Discard bespoke DBs on VerifyDB

* Make CHistoryWriter a member of CCuscomCSView

* lint: Circular deps

* Pass block hash to account change and print TX type

* lint: circular deps

---------

Co-authored-by: Prasanna Loganathar <[email protected]>
  • Loading branch information
Bushstar and prasannavl authored Feb 6, 2023
1 parent 300e24f commit a8d147f
Show file tree
Hide file tree
Showing 15 changed files with 508 additions and 470 deletions.
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ DEFI_CORE_H = \
masternodes/govvariables/oracle_block_interval.h \
masternodes/govvariables/oracle_deviation.h \
masternodes/gv.h \
masternodes/historywriter.h \
masternodes/icxorder.h \
masternodes/incentivefunding.h \
masternodes/loan.h \
Expand Down Expand Up @@ -389,6 +390,7 @@ libdefi_server_a_SOURCES = \
masternodes/govvariables/oracle_block_interval.cpp \
masternodes/govvariables/oracle_deviation.cpp \
masternodes/gv.cpp \
masternodes/historywriter.cpp \
masternodes/icxorder.cpp \
masternodes/incentivefunding.cpp \
masternodes/loan.cpp \
Expand Down
2 changes: 1 addition & 1 deletion src/consensus/tx_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, c
const auto txType = GuessCustomTxType(tx, dummy);

if (NotAllowedToFail(txType, nSpendHeight) || (nSpendHeight >= chainparams.GetConsensus().GrandCentralHeight && txType == CustomTxType::UpdateMasternode)) {
CCustomCSView discardCache(mnview);
CCustomCSView discardCache(mnview, nullptr, nullptr, nullptr);
auto res = ApplyCustomTx(discardCache, inputs, tx, chainparams.GetConsensus(), nSpendHeight, 0, &canSpend);
if (!res.ok && (res.code & CustomTxErrCodes::Fatal)) {
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-txns-customtx", res.msg);
Expand Down
136 changes: 14 additions & 122 deletions src/masternodes/accountshistory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,38 +5,9 @@
#include <key_io.h>
#include <masternodes/accounts.h>
#include <masternodes/accountshistory.h>
#include <masternodes/masternodes.h>
#include <masternodes/historywriter.h>
#include <masternodes/vaulthistory.h>

struct AccountHistoryKeyNew {
uint32_t blockHeight;
CScript owner;
uint32_t txn; // for order in block

ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
inline void SerializationOp(Stream &s, Operation ser_action) {
if (ser_action.ForRead()) {
READWRITE(WrapBigEndian(blockHeight));
blockHeight = ~blockHeight;
} else {
uint32_t blockHeight_ = ~blockHeight;
READWRITE(WrapBigEndian(blockHeight_));
}

READWRITE(owner);

if (ser_action.ForRead()) {
READWRITE(WrapBigEndian(txn));
txn = ~txn;
} else {
uint32_t txn_ = ~txn;
READWRITE(WrapBigEndian(txn_));
}
}
};

static AccountHistoryKeyNew Convert(const AccountHistoryKey &key) {
return {key.blockHeight, key.owner, key.txn};
}
Expand Down Expand Up @@ -90,10 +61,9 @@ std::optional<AccountHistoryValue> CAccountsHistoryView::ReadAccountHistory(cons
return ReadBy<ByAccountHistoryKey, AccountHistoryValue>(key);
}

Res CAccountsHistoryView::WriteAccountHistory(const AccountHistoryKey &key, const AccountHistoryValue &value) {
void CAccountsHistoryView::WriteAccountHistory(const AccountHistoryKey &key, const AccountHistoryValue &value) {
WriteBy<ByAccountHistoryKey>(key, value);
WriteBy<ByAccountHistoryKeyNew>(Convert(key), '\0');
return Res::Ok();
}

Res CAccountsHistoryView::EraseAccountHistory(const AccountHistoryKey &key) {
Expand Down Expand Up @@ -126,119 +96,41 @@ CAccountsHistoryWriter::CAccountsHistoryWriter(CCustomCSView &storage,
uint32_t height,
uint32_t txn,
const uint256 &txid,
uint8_t type,
CHistoryWriters *writers)
uint8_t type)
: CStorageView(new CFlushableStorageKV(static_cast<CStorageKV &>(storage.GetStorage()))),
height(height),
txn(txn),
txid(txid),
type(type),
writers(writers) {}
writers(storage.GetHistoryWriters()) {
}

CAccountsHistoryWriter::~CAccountsHistoryWriter() {
writers.ClearState();
}

Res CAccountsHistoryWriter::AddBalance(const CScript &owner, CTokenAmount amount) {
auto res = CCustomCSView::AddBalance(owner, amount);
if (writers && amount.nValue != 0 && res.ok) {
writers->AddBalance(owner, amount, vaultID);
if (amount.nValue != 0 && res.ok) {
writers.AddBalance(owner, amount, vaultID);
}

return res;
}

Res CAccountsHistoryWriter::SubBalance(const CScript &owner, CTokenAmount amount) {
auto res = CCustomCSView::SubBalance(owner, amount);
if (writers && res.ok && amount.nValue != 0) {
writers->SubBalance(owner, amount, vaultID);
if (res.ok && amount.nValue != 0) {
writers.SubBalance(owner, amount, vaultID);
}

return res;
}

bool CAccountsHistoryWriter::Flush() {
if (writers) {
writers->Flush(height, txid, txn, type, vaultID);
}
writers.Flush(height, txid, txn, type, vaultID);
return CCustomCSView::Flush();
}

CAccountHistoryStorage *CAccountsHistoryWriter::GetAccountHistoryStore() {
return writers ? writers->GetAccountHistoryStore() : nullptr;
};

CHistoryWriters::CHistoryWriters(CAccountHistoryStorage *historyView,
CBurnHistoryStorage *burnView,
CVaultHistoryStorage *vaultView)
: historyView(historyView),
burnView(burnView),
vaultView(vaultView) {}

extern std::string ScriptToString(const CScript &script);

void CHistoryWriters::AddBalance(const CScript &owner, const CTokenAmount amount, const uint256 &vaultID) {
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;
}
}

void CHistoryWriters::AddFeeBurn(const CScript &owner, const CAmount amount) {
if (burnView && amount != 0) {
burnDiffs[owner][DCT_ID{0}] += amount;
}
}

void CHistoryWriters::SubBalance(const CScript &owner, const CTokenAmount amount, const uint256 &vaultID) {
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;
}
}

void CHistoryWriters::Flush(const uint32_t height,
const uint256 &txid,
const uint32_t txn,
const uint8_t type,
const uint256 &vaultID) {
if (historyView) {
for (const auto &diff : diffs) {
LogPrint(BCLog::ACCOUNTCHANGE,
"AccountChange: txid=%s addr=%s change=%s\n",
txid.GetHex(),
ScriptToString(diff.first),
(CBalances{diff.second}.ToString()));
historyView->WriteAccountHistory({diff.first, height, txn}, {txid, type, diff.second});
}
}
if (burnView) {
for (const auto &diff : burnDiffs) {
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({height, diff.first, txn, addresses.first},
{txid, type, addresses.second});
}
}
if (!schemeID.empty()) {
vaultView->WriteVaultScheme({vaultID, height}, {type, txid, schemeID, txn});
}
if (!globalLoanScheme.identifier.empty()) {
vaultView->WriteGlobalScheme({height, txn, globalLoanScheme.schemeCreationTxid},
{globalLoanScheme, type, txid});
}
}
}

std::unique_ptr<CAccountHistoryStorage> paccountHistoryDB;
std::unique_ptr<CBurnHistoryStorage> pburnHistoryDB;
82 changes: 8 additions & 74 deletions src/masternodes/accountshistory.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,55 +12,18 @@
#include <script/script.h>
#include <uint256.h>

class CHistoryWriters;
class CVaultHistoryView;
class CVaultHistoryStorage;

struct AccountHistoryKey {
CScript owner;
uint32_t blockHeight;
uint32_t txn; // for order in block

ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
inline void SerializationOp(Stream &s, Operation ser_action) {
READWRITE(owner);

if (ser_action.ForRead()) {
READWRITE(WrapBigEndian(blockHeight));
blockHeight = ~blockHeight;
READWRITE(WrapBigEndian(txn));
txn = ~txn;
} else {
uint32_t blockHeight_ = ~blockHeight;
READWRITE(WrapBigEndian(blockHeight_));
uint32_t txn_ = ~txn;
READWRITE(WrapBigEndian(txn_));
}
}
};

struct AccountHistoryValue {
uint256 txid;
unsigned char category;
TAmounts diff;

ADD_SERIALIZE_METHODS;

template <typename Stream, typename Operation>
inline void SerializationOp(Stream &s, Operation ser_action) {
READWRITE(txid);
READWRITE(category);
READWRITE(diff);
}
};
struct VaultHistoryKey;
struct VaultHistoryValue;

class CAccountsHistoryView : public virtual CStorageView {
public:
void CreateMultiIndexIfNeeded();
Res EraseAccountHistoryHeight(uint32_t height);
[[nodiscard]] std::optional<AccountHistoryValue> ReadAccountHistory(const AccountHistoryKey &key) const;
Res WriteAccountHistory(const AccountHistoryKey &key, const AccountHistoryValue &value);
void WriteAccountHistory(const AccountHistoryKey &key, const AccountHistoryValue &value);
Res EraseAccountHistory(const AccountHistoryKey &key);
void ForEachAccountHistory(std::function<bool(const AccountHistoryKey &, AccountHistoryValue)> callback,
const CScript &owner = {},
Expand Down Expand Up @@ -88,40 +51,12 @@ class CBurnHistoryStorage : public CAccountsHistoryView {
CBurnHistoryStorage(const fs::path &dbName, std::size_t cacheSize, bool fMemory = false, bool fWipe = false);
};

class CHistoryWriters {
CAccountHistoryStorage *historyView{};
CBurnHistoryStorage *burnView{};
std::map<CScript, TAmounts> diffs;
std::map<CScript, TAmounts> burnDiffs;
std::map<uint256, std::map<CScript, TAmounts>> vaultDiffs;

public:
CVaultHistoryStorage *vaultView{};
CLoanSchemeCreation globalLoanScheme;
std::string schemeID;

CHistoryWriters(CAccountHistoryStorage *historyView,
CBurnHistoryStorage *burnView,
CVaultHistoryStorage *vaultView);

CAccountHistoryStorage *GetAccountHistoryStore() { return historyView; };

void AddBalance(const CScript &owner, const CTokenAmount amount, const uint256 &vaultID);
void AddFeeBurn(const CScript &owner, const CAmount amount);
void SubBalance(const CScript &owner, const CTokenAmount amount, const uint256 &vaultID);
void Flush(const uint32_t height,
const uint256 &txid,
const uint32_t txn,
const uint8_t type,
const uint256 &vaultID);
};

class CAccountsHistoryWriter : public CCustomCSView {
const uint32_t height;
const uint32_t txn;
const uint256 txid;
const uint8_t type;
CHistoryWriters *writers{};
CHistoryWriters& writers;

public:
uint256 vaultID;
Expand All @@ -130,13 +65,12 @@ class CAccountsHistoryWriter : public CCustomCSView {
uint32_t height,
uint32_t txn,
const uint256 &txid,
uint8_t type,
CHistoryWriters *writers);
uint8_t type);
~CAccountsHistoryWriter() override;
Res AddBalance(const CScript &owner, CTokenAmount amount) override;
Res SubBalance(const CScript &owner, CTokenAmount amount) override;
bool Flush() override;

CAccountHistoryStorage *GetAccountHistoryStore() override;
CHistoryWriters& GetHistoryWriters() override { return writers; }
};

extern std::unique_ptr<CAccountHistoryStorage> paccountHistoryDB;
Expand Down
19 changes: 5 additions & 14 deletions src/masternodes/govvariables/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include <masternodes/mn_rpc.h>

#include <masternodes/accountshistory.h> /// CAccountsHistoryWriter
#include <masternodes/historywriter.h> /// CHiistoryWriter
#include <masternodes/masternodes.h> /// CCustomCSView
#include <masternodes/mn_checks.h> /// GetAggregatePrice / CustomTxType
#include <validation.h> /// GetNextAccPosition
Expand Down Expand Up @@ -878,22 +879,16 @@ Res ATTRIBUTES::RefundFuturesContracts(CCustomCSView &mnview, const uint32_t hei
CDataStructureV0 liveKey{AttributeTypes::Live, ParamIDs::Economy, EconomyKeys::DFIP2203Current};
auto balances = GetValue(liveKey, CBalances{});

CAccountHistoryStorage *historyStore{mnview.GetAccountHistoryStore()};
const auto currentHeight = mnview.GetLastHeight() + 1;

for (const auto &[key, value] : userFuturesValues) {
mnview.EraseFuturesUserValues(key);

CHistoryWriters subWriters{historyStore, nullptr, nullptr};
CAccountsHistoryWriter subView(
mnview, currentHeight, GetNextAccPosition(), {}, uint8_t(CustomTxType::FutureSwapRefund), &subWriters);
CAccountsHistoryWriter subView(mnview, currentHeight, GetNextAccPosition(), {}, uint8_t(CustomTxType::FutureSwapRefund));

Require(subView.SubBalance(*contractAddressValue, value.source));
subView.Flush();

CHistoryWriters addWriters{historyStore, nullptr, nullptr};
CAccountsHistoryWriter addView(
mnview, currentHeight, GetNextAccPosition(), {}, uint8_t(CustomTxType::FutureSwapRefund), &addWriters);
CAccountsHistoryWriter addView(mnview, currentHeight, GetNextAccPosition(), {}, uint8_t(CustomTxType::FutureSwapRefund));

Require(addView.AddBalance(key.owner, value.source));
addView.Flush();
Expand Down Expand Up @@ -933,18 +928,14 @@ Res ATTRIBUTES::RefundFuturesDUSD(CCustomCSView &mnview, const uint32_t height)
for (const auto &[key, amount] : userFuturesValues) {
mnview.EraseFuturesDUSD(key);

CHistoryWriters subWriters{paccountHistoryDB.get(), nullptr, nullptr};
CAccountsHistoryWriter subView(
mnview, height, GetNextAccPosition(), {}, uint8_t(CustomTxType::FutureSwapRefund), &subWriters);
CAccountsHistoryWriter subView(mnview, height, GetNextAccPosition(), {}, uint8_t(CustomTxType::FutureSwapRefund));
auto res = subView.SubBalance(*contractAddressValue, {DCT_ID{}, amount});
if (!res) {
return res;
}
subView.Flush();

CHistoryWriters addWriters{paccountHistoryDB.get(), nullptr, nullptr};
CAccountsHistoryWriter addView(
mnview, height, GetNextAccPosition(), {}, uint8_t(CustomTxType::FutureSwapRefund), &addWriters);
CAccountsHistoryWriter addView(mnview, height, GetNextAccPosition(), {}, uint8_t(CustomTxType::FutureSwapRefund));
res = addView.AddBalance(key.owner, {DCT_ID{}, amount});
if (!res) {
return res;
Expand Down
Loading

0 comments on commit a8d147f

Please sign in to comment.