Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scoped EVM queue ID class #2537

Merged
merged 10 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/consensus/tx_verify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,8 @@ bool Consensus::CheckTxInputs(const CTransaction& tx, CValidationState& state, c
CCustomCSView discardCache(mnview, nullptr, nullptr, nullptr);
// Note: TXs are already filtered. So we pass isEVMEnabled to false, but for future proof, refactor this enough,
// that it's propagated.
auto res = ApplyCustomTx(discardCache, inputs, tx, chainparams.GetConsensus(), nSpendHeight, 0, &canSpend, 0, 0, false, false);
std::shared_ptr<CScopedQueueID> evmQueueId{};
auto res = ApplyCustomTx(discardCache, inputs, tx, chainparams.GetConsensus(), nSpendHeight, 0, &canSpend, 0, evmQueueId, false, false);
if (!res.ok && (res.code & CustomTxErrCodes::Fatal)) {
return state.Invalid(ValidationInvalidReason::CONSENSUS, false, REJECT_INVALID, "bad-txns-customtx", res.msg);
}
Expand Down
2 changes: 1 addition & 1 deletion src/masternodes/consensus/poolpairs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ Res CPoolPairsConsensus::operator()(const CCreatePoolPairMessage &obj) const {
token.creationTx = tx.GetHash();
token.creationHeight = height;

auto tokenId = mnview.CreateToken(token, false, false, evmQueueId);
auto tokenId = mnview.CreateToken(token, false);
Require(tokenId);

rewards = obj.rewards;
Expand Down
2 changes: 1 addition & 1 deletion src/masternodes/consensus/txvisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ CCustomTxVisitor::CCustomTxVisitor(const CTransaction &tx,
const Consensus::Params &consensus,
const uint64_t time,
const uint32_t txn,
const uint64_t evmQueueId,
const std::shared_ptr<CScopedQueueID> &evmQueueId,
const bool isEvmEnabledForBlock,
const bool evmPreValidate)
: height(height),
Expand Down
5 changes: 3 additions & 2 deletions src/masternodes/consensus/txvisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class CCustomCSView;
struct CLoanSchemeData;
class CPoolPair;
class CScript;
class CScopedQueueID;
class CTokenImplementation;
class CTransaction;
class CVaultAssets;
Expand Down Expand Up @@ -51,7 +52,7 @@ class CCustomTxVisitor {
const Consensus::Params &consensus;
const uint64_t time;
const uint32_t txn;
uint64_t evmQueueId;
const std::shared_ptr<CScopedQueueID> &evmQueueId;
bool isEvmEnabledForBlock;
bool evmPreValidate;

Expand All @@ -63,7 +64,7 @@ class CCustomTxVisitor {
const Consensus::Params &consensus,
const uint64_t time,
const uint32_t txn,
const uint64_t evmQueueId,
const std::shared_ptr<CScopedQueueID> &evmQueueId,
const bool isEvmEnabledForBlock,
const bool evmPreValidate);

Expand Down
28 changes: 15 additions & 13 deletions src/masternodes/consensus/xvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ static Res ValidateTransferDomain(const CTransaction &tx,
CCustomCSView &mnview,
const Consensus::Params &consensus,
const CTransferDomainMessage &obj,
const std::shared_ptr<CScopedQueueID> &evmQueueId,
const bool isEvmEnabledForBlock,
std::vector<TransferDomainInfo> &contexts)
{
Expand Down Expand Up @@ -208,7 +209,7 @@ static Res ValidateTransferDomain(const CTransaction &tx,

Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const {
std::vector<TransferDomainInfo> contexts;
auto res = ValidateTransferDomain(tx, height, coins, mnview, consensus, obj, isEvmEnabledForBlock, contexts);
auto res = ValidateTransferDomain(tx, height, coins, mnview, consensus, obj, evmQueueId, isEvmEnabledForBlock, contexts);
if (!res) { return res; }

auto attributes = mnview.GetAttributes();
Expand All @@ -230,7 +231,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const {
}

// Check if destination address is a contract
auto isSmartContract = evm_try_unsafe_is_smart_contract_in_q(result, toAddress->GetHex(), evmQueueId);
auto isSmartContract = evm_try_unsafe_is_smart_contract_in_q(result, toAddress->GetHex(), evmQueueId->GetQueueID());
if (!result.ok) {
return Res::Err("Error checking contract address: %s", result.reason);
}
Expand All @@ -251,7 +252,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const {
return DeFiErrors::TransferDomainInvalidDataSize(MAX_TRANSFERDOMAIN_EVM_DATA_LEN);
}
const auto evmTx = HexStr(dst.data);
evm_try_unsafe_validate_transferdomain_tx_in_q(result, evmQueueId, evmTx, contexts[idx]);
evm_try_unsafe_validate_transferdomain_tx_in_q(result, evmQueueId->GetQueueID(), evmTx, contexts[idx]);
if (!result.ok) {
LogPrintf("[evm_try_validate_transferdomain_tx] failed, reason : %s\n", result.reason);
return Res::Err("transferdomain evm tx failed to pre-validate : %s", result.reason);
Expand All @@ -268,13 +269,13 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const {
// Add balance to ERC55 address
auto tokenId = dst.amount.nTokenId;
if (tokenId == DCT_ID{0}) {
evm_try_unsafe_add_balance_in_q(result, evmQueueId, evmTx, tx.GetHash().GetHex());
evm_try_unsafe_add_balance_in_q(result, evmQueueId->GetQueueID(), evmTx, tx.GetHash().GetHex());
if (!result.ok) {
return Res::Err("Error bridging DFI: %s", result.reason);
}
}
else {
evm_try_unsafe_bridge_dst20(result, evmQueueId, evmTx, tx.GetHash().GetHex(), tokenId.v, true);
evm_try_unsafe_bridge_dst20(result, evmQueueId->GetQueueID(), evmTx, tx.GetHash().GetHex(), tokenId.v, true);
if (!result.ok) {
return Res::Err("Error bridging DST20: %s", result.reason);
}
Expand All @@ -293,7 +294,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const {
}

// Check if source address is a contract
auto isSmartContract = evm_try_unsafe_is_smart_contract_in_q(result, fromAddress->GetHex(), evmQueueId);
auto isSmartContract = evm_try_unsafe_is_smart_contract_in_q(result, fromAddress->GetHex(), evmQueueId->GetQueueID());
if (!result.ok) {
return Res::Err("Error checking contract address: %s", result.reason);
}
Expand All @@ -305,7 +306,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const {
return DeFiErrors::TransferDomainInvalidDataSize(MAX_TRANSFERDOMAIN_EVM_DATA_LEN);
}
const auto evmTx = HexStr(src.data);
evm_try_unsafe_validate_transferdomain_tx_in_q(result, evmQueueId, evmTx, contexts[idx]);
evm_try_unsafe_validate_transferdomain_tx_in_q(result, evmQueueId->GetQueueID(), evmTx, contexts[idx]);
if (!result.ok) {
LogPrintf("[evm_try_validate_transferdomain_tx] failed, reason : %s\n", result.reason);
return Res::Err("transferdomain evm tx failed to pre-validate %s", result.reason);
Expand All @@ -323,15 +324,15 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const {
// Subtract balance from ERC55 address
auto tokenId = dst.amount.nTokenId;
if (tokenId == DCT_ID{0}) {
if (!evm_try_unsafe_sub_balance_in_q(result, evmQueueId, evmTx, tx.GetHash().GetHex())) {
if (!evm_try_unsafe_sub_balance_in_q(result, evmQueueId->GetQueueID(), evmTx, tx.GetHash().GetHex())) {
return DeFiErrors::TransferDomainNotEnoughBalance(EncodeDestination(dest));
}
if (!result.ok) {
return Res::Err("Error bridging DFI: %s", result.reason);
}
}
else {
evm_try_unsafe_bridge_dst20(result, evmQueueId, evmTx, tx.GetHash().GetHex(), tokenId.v, false);
evm_try_unsafe_bridge_dst20(result, evmQueueId->GetQueueID(), evmTx, tx.GetHash().GetHex(), tokenId.v, false);
if (!result.ok) {
return Res::Err("Error bridging DST20: %s", result.reason);
}
Expand All @@ -343,7 +344,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const {
// Add balance to DFI address
res = mnview.AddBalance(dst.address, dst.amount);
if (!res) {
evm_try_unsafe_remove_txs_above_hash_in_q(result, evmQueueId, tx.GetHash().GetHex());
evm_try_unsafe_remove_txs_above_hash_in_q(result, evmQueueId->GetQueueID(), tx.GetHash().GetHex());
return res;
}
stats.evmDvmTotal.Add(dst.amount);
Expand All @@ -370,7 +371,7 @@ Res CXVMConsensus::operator()(const CTransferDomainMessage &obj) const {
attributes->SetValue(CTransferDomainStatsLive::Key, stats);
res = mnview.SetVariable(*attributes);
if (!res) {
evm_try_unsafe_remove_txs_above_hash_in_q(result, evmQueueId, tx.GetHash().GetHex());
evm_try_unsafe_remove_txs_above_hash_in_q(result, evmQueueId->GetQueueID(), tx.GetHash().GetHex());
return res;
}
return Res::Ok();
Expand All @@ -386,15 +387,16 @@ Res CXVMConsensus::operator()(const CEvmTxMessage &obj) const {

CrossBoundaryResult result;
if (evmPreValidate) {
evm_try_unsafe_validate_raw_tx_in_q(result, evmQueueId, HexStr(obj.evmTx));
evm_try_unsafe_validate_raw_tx_in_q(result, evmQueueId->GetQueueID(), HexStr(obj.evmTx));
if (!result.ok) {
LogPrintf("[evm_try_validate_raw_tx] failed, reason : %s\n", result.reason);
return Res::Err("evm tx failed to pre-validate %s", result.reason);
}
return Res::Ok();
}

const auto validateResults = evm_try_unsafe_push_tx_in_q(result, evmQueueId, HexStr(obj.evmTx), tx.GetHash().GetHex());

const auto validateResults = evm_try_unsafe_push_tx_in_q(result, evmQueueId->GetQueueID(), HexStr(obj.evmTx), tx.GetHash().GetHex());
if (!result.ok) {
LogPrintf("[evm_try_push_tx_in_q] failed, reason : %s\n", result.reason);
return Res::Err("evm tx failed to queue %s\n", result.reason);
Expand Down
24 changes: 24 additions & 0 deletions src/masternodes/evm.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <ain_rs_exports.h>
#include <masternodes/evm.h>
#include <masternodes/errors.h>
#include <masternodes/res.h>
Expand Down Expand Up @@ -46,3 +47,26 @@ void CVMDomainGraphView::ForEachVMDomainTxEdges(std::function<bool(const std::pa
return callback(k, val);
}, std::make_pair(static_cast<uint8_t>(start.first), start.second));
}

CScopedQueueID::CScopedQueueID(uint64_t id) : evmQueueId(id) {}

std::shared_ptr<CScopedQueueID> CScopedQueueID::Create(const uint64_t timestamp) {
CrossBoundaryResult result;
uint64_t queueId = evm_try_unsafe_create_queue(result, timestamp);
if (result.ok) {
return std::shared_ptr<CScopedQueueID>(new CScopedQueueID(queueId));
}
return nullptr;
}

CScopedQueueID::~CScopedQueueID() {
CrossBoundaryResult result;
evm_try_unsafe_remove_queue(result, evmQueueId);
if (!result.ok) {
LogPrintf("Failed to destroy queue %d\n", evmQueueId);
}
}

uint64_t CScopedQueueID::GetQueueID() const {
return evmQueueId;
}
12 changes: 12 additions & 0 deletions src/masternodes/evm.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,16 @@ class CVMDomainGraphView : public virtual CStorageView {
};
};

class CScopedQueueID {
explicit CScopedQueueID(uint64_t id);

uint64_t evmQueueId;

public:
static std::shared_ptr<CScopedQueueID> Create(const uint64_t timestamp);
~CScopedQueueID();

uint64_t GetQueueID() const;
};

#endif // DEFI_MASTERNODES_EVM_H
29 changes: 17 additions & 12 deletions src/masternodes/govvariables/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,15 +910,18 @@ void TrackLiveBalances(CCustomCSView &mnview, const CBalances &balances, const u
mnview.SetVariable(*attributes);
}

bool IsEVMEnabled(const int height, const CCustomCSView &view, const Consensus::Params &consensus) {
if (height < consensus.DF22NextHeight) {
return false;
}
bool IsEVMEnabled(const std::shared_ptr<ATTRIBUTES> attributes) {
if (!attributes) return false;

const CDataStructureV0 enabledKey{AttributeTypes::Param, ParamIDs::Feature, DFIPKeys::EVMEnabled};
return attributes->GetValue(enabledKey, false);
}

bool IsEVMEnabled(const CCustomCSView &view, const Consensus::Params &consensus) {
auto attributes = view.GetAttributes();
assert(attributes);
return attributes->GetValue(enabledKey, false);

return IsEVMEnabled(attributes);
}

Res StoreGovVars(const CGovernanceHeightMessage &obj, CCustomCSView &view) {
Expand Down Expand Up @@ -2327,13 +2330,15 @@ Res ATTRIBUTES::Apply(CCustomCSView &mnview, const uint32_t height) {
govVarValue.reserve(govVarVec.size());
std::copy(govVarVec.begin(), govVarVec.end(), govVarValue.begin());

CrossBoundaryResult result;
const auto rustKey = GovVarKeyDataStructure{attrV0->type, attrV0->typeId, attrV0->key, attrV0->keyId};
if (!evm_try_handle_attribute_apply(result, evmQueueId, rustKey, govVarValue)) {
return DeFiErrors::SettingEVMAttributeFailure();
}
if (!result.ok) {
return DeFiErrors::SettingEVMAttributeFailure(result.reason.c_str());
if (evmQueueId) {
CrossBoundaryResult result;
const auto rustKey = GovVarKeyDataStructure{attrV0->type, attrV0->typeId, attrV0->key, attrV0->keyId};
if (!evm_try_handle_attribute_apply(result, evmQueueId->GetQueueID(), rustKey, govVarValue)) {
return DeFiErrors::SettingEVMAttributeFailure();
}
if (!result.ok) {
return DeFiErrors::SettingEVMAttributeFailure(result.reason.c_str());
}
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/masternodes/govvariables/attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <amount.h>
#include <masternodes/balances.h>
#include <masternodes/evm.h>
#include <masternodes/gv.h>
#include <masternodes/oracles.h>

Expand Down Expand Up @@ -441,7 +442,8 @@ void TrackLiveBalances(CCustomCSView &mnview, const CBalances &balances, const u
void TrackDUSDAdd(CCustomCSView &mnview, const CTokenAmount &amount);
void TrackDUSDSub(CCustomCSView &mnview, const CTokenAmount &amount);

bool IsEVMEnabled(const int height, const CCustomCSView &view, const Consensus::Params &consensus);
bool IsEVMEnabled(const std::shared_ptr<ATTRIBUTES> attributes);
bool IsEVMEnabled(const CCustomCSView &view, const Consensus::Params &consensus);
Res StoreGovVars(const CGovernanceHeightMessage &obj, CCustomCSView &view);

enum GovVarsFilter {
Expand Down Expand Up @@ -543,7 +545,7 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
}

uint32_t time{0};
uint64_t evmQueueId{};
std::shared_ptr<CScopedQueueID> evmQueueId{};

// For formatting in export
static const std::map<uint8_t, std::string> &displayVersions();
Expand Down
32 changes: 11 additions & 21 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ class CCustomTxApplyVisitor {
const Consensus::Params& consensus;
uint64_t time;
uint32_t txn;
uint64_t evmQueueId;
const std::shared_ptr<CScopedQueueID> &evmQueueId;
bool isEvmEnabledForBlock;
bool evmPreValidate;

Expand All @@ -356,7 +356,7 @@ class CCustomTxApplyVisitor {
const Consensus::Params &consensus,
uint64_t time,
uint32_t txn,
const uint64_t evmQueueId,
const std::shared_ptr<CScopedQueueID> &evmQueueId,
const bool isEvmEnabledForBlock,
const bool evmPreValidate)

Expand Down Expand Up @@ -445,38 +445,28 @@ Res CustomTxVisit(CCustomCSView &mnview,
const CCustomTxMessage &txMessage,
const uint64_t time,
const uint32_t txn,
const uint64_t evmQueueId,
std::shared_ptr<CScopedQueueID> &evmQueueId,
const bool isEvmEnabledForBlock,
const bool evmPreValidate) {
if (IsDisabledTx(height, tx, consensus)) {
return Res::ErrCode(CustomTxErrCodes::Fatal, "Disabled custom transaction");
}

auto q = evmQueueId;
bool wipeQueue{};
if (q == 0) {
wipeQueue = true;
auto r = XResultValue(evm_try_unsafe_create_queue(result, time));
if (r) { q = *r; } else { return r; }
if (!evmQueueId && isEvmEnabledForBlock) {
evmQueueId = CScopedQueueID::Create(time);
if (!evmQueueId) {
return Res::Err("Failed to create queue");
}
}

try {
auto res = std::visit(
CCustomTxApplyVisitor(tx, height, coins, mnview, consensus, time, txn, q, isEvmEnabledForBlock, evmPreValidate),
txMessage);
if (wipeQueue) {
XResultStatusLogged(evm_try_unsafe_remove_queue(result, q));
}
CCustomTxApplyVisitor(tx, height, coins, mnview, consensus, time, txn, evmQueueId, isEvmEnabledForBlock, evmPreValidate),
txMessage);
return res;
} catch (const std::bad_variant_access &e) {
if (wipeQueue) {
XResultStatusLogged(evm_try_unsafe_remove_queue(result, q));
}
return Res::Err(e.what());
} catch (...) {
if (wipeQueue) {
XResultStatusLogged(evm_try_unsafe_remove_queue(result, q));
}
return Res::Err("%s unexpected error", __func__ );
}
}
Expand Down Expand Up @@ -559,7 +549,7 @@ Res ApplyCustomTx(CCustomCSView &mnview,
uint64_t time,
uint256 *canSpend,
uint32_t txn,
const uint64_t evmQueueId,
std::shared_ptr<CScopedQueueID> &evmQueueId,
const bool isEvmEnabledForBlock,
const bool evmPreValidate) {
auto res = Res::Ok();
Expand Down
4 changes: 2 additions & 2 deletions src/masternodes/mn_checks.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ Res ApplyCustomTx(CCustomCSView &mnview,
uint64_t time,
uint256 *canSpend,
uint32_t txn,
const uint64_t evmQueueId,
std::shared_ptr<CScopedQueueID> &evmQueueId,
const bool isEvmEnabledForBlock,
const bool evmPreValidate);

Expand All @@ -185,7 +185,7 @@ Res CustomTxVisit(CCustomCSView &mnview,
const CCustomTxMessage &txMessage,
const uint64_t time,
const uint32_t txn,
const uint64_t evmQueueId,
std::shared_ptr<CScopedQueueID> &evmQueueId,
const bool isEvmEnabledForBlock,
const bool evmPreValidate);

Expand Down
Loading