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

Check ATTRIBUTE export keys. Do not import empty set. #2565

Merged
merged 9 commits into from
Oct 12, 2023
1 change: 0 additions & 1 deletion src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,6 @@ class CTestNetParams : public CChainParams {
{300000, uint256S("205b522772ce34206a08a635c800f99d2fc4e9696ab8c470dad7f5fa51dfea1a")},
{1445000, uint256S("6fd0cafbbd2262d5cecd2e07e73fe6703bac364e5d4986da3fe512b0eccf944d")},
{1471000, uint256S("dcf4a5fb69c004d0921710e09a09d10f275b3bc696e45ca03f6c322bb32f41bc")},
{1910000, uint256S("83b9b52e7f22ae6e9bb44e9b01aecf9bbf1bd9c93a7d09a6c1a1f1e6aafbdbf1")},
}
};

Expand Down
33 changes: 32 additions & 1 deletion src/dfi/consensus/governance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,21 @@ Res CGovernanceConsensus::operator()(const CGovernanceMessage &obj) const {
govVar->evmQueueId = evmQueueId;

auto newVar = std::dynamic_pointer_cast<ATTRIBUTES>(var);
assert(newVar);
if (!newVar) {
return Res::Err("Failed to cast Gov var to ATTRIBUTES");
}

if (height >= static_cast<uint32_t>(consensus.DF22MetachainHeight)) {
res = newVar->CheckKeys();
if (!res) {
return res;
}

const auto newExport = newVar->Export();
if (newExport.empty()) {
return Res::Err("Cannot export empty attribute map");
}
}

CDataStructureV0 key{AttributeTypes::Param, ParamIDs::Foundation, DFIPKeys::Members};
auto memberRemoval = newVar->GetValue(key, std::set<std::string>{});
Expand Down Expand Up @@ -167,6 +181,23 @@ Res CGovernanceConsensus::operator()(const CGovernanceHeightMessage &obj) const
return Res::Err("%s: %s", obj.govVar->GetName(), "Failed to get existing ATTRIBUTES");
}

if (height >= static_cast<uint32_t>(consensus.DF22MetachainHeight)) {
auto newVar = std::dynamic_pointer_cast<ATTRIBUTES>(obj.govVar);
if (!newVar) {
return Res::Err("Failed to cast Gov var to ATTRIBUTES");
}

auto res = newVar->CheckKeys();
if (!res) {
return res;
}

const auto newExport = newVar->Export();
if (newExport.empty()) {
return Res::Err("Cannot export empty attribute map");
}
}

auto storedGovVars = mnview.GetStoredVariablesRange(height, obj.startHeight);

Res res{};
Expand Down
8 changes: 8 additions & 0 deletions src/dfi/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,14 @@ class DeFiErrors {
return Res::Err(error);
}

static Res GovVarVariableInvalidKey(const std::string &key, const std::map<uint8_t, std::string> &keys) {
std::string error{"Unrecognised " + key + " argument provided, valid " + key + "s are:"};
for (const auto &pair : keys) {
error += ' ' + pair.second + ',';
}
return Res::Err(error);
}

static Res GovVarVariableUnsupportedType(const unsigned char type) {
return Res::Err("Unsupported type {%d}", type);
}
Expand Down
286 changes: 183 additions & 103 deletions src/dfi/govvariables/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,26 +107,36 @@ const std::map<std::string, uint8_t> &ATTRIBUTES::allowedParamIDs() {
return params;
}

const std::map<uint8_t, std::string> &ATTRIBUTES::allowedExportParamsIDs() {
static const std::map<uint8_t, std::string> params{
{ParamIDs::DFIP2201, "dfip2201" },
{ParamIDs::DFIP2203, "dfip2203" },
{ParamIDs::DFIP2206A, "dfip2206a" },
{ParamIDs::DFIP2206F, "dfip2206f" },
{ParamIDs::Feature, "feature" },
{ParamIDs::Foundation, "foundation"},
};
return params;
}

const std::map<uint8_t, std::string> &ATTRIBUTES::displayParamsIDs() {
static auto params = allowedExportParamsIDs();
params[ParamIDs::Auction] = "auction";
params[ParamIDs::Economy] = "economy";
params[ParamIDs::TokenID] = "token";
return params;
}

const std::map<std::string, uint8_t> &ATTRIBUTES::allowedLocksIDs() {
static const std::map<std::string, uint8_t> params{
{"token", ParamIDs::TokenID},
};
return params;
}

const std::map<uint8_t, std::string> &ATTRIBUTES::displayParamsIDs() {
const std::map<uint8_t, std::string> &ATTRIBUTES::displayLocksIDs() {
static const std::map<uint8_t, std::string> params{
{ParamIDs::DFIP2201, "dfip2201" },
{ParamIDs::DFIP2203, "dfip2203" },
{ParamIDs::DFIP2206A, "dfip2206a" },
// Note: DFIP2206F is currently in beta testing
// for testnet. May not be enabled on mainnet until testing is complete.
{ParamIDs::DFIP2206F, "dfip2206f" },
{ParamIDs::TokenID, "token" },
{ParamIDs::Economy, "economy" },
{ParamIDs::Feature, "feature" },
{ParamIDs::Auction, "auction" },
{ParamIDs::Foundation, "foundation"},
{ParamIDs::TokenID, "token"},
};
return params;
}
Expand Down Expand Up @@ -947,6 +957,98 @@ Res StoreGovVars(const CGovernanceHeightMessage &obj, CCustomCSView &view) {
return view.SetStoredVariables(storedGovVars, obj.startHeight);
}

static Res CheckValidAttrV0Key(const uint8_t type, const uint32_t typeId, const uint32_t typeKey) {
if (type == AttributeTypes::Param) {
if (typeId == ParamIDs::DFIP2201) {
if (typeKey != DFIPKeys::Active && typeKey != DFIPKeys::Premium && typeKey != DFIPKeys::MinSwap) {
return Res::Err("Unsupported type for DFIP2201 {%d}", typeKey);
}
} else if (typeId == ParamIDs::DFIP2203 || typeId == ParamIDs::DFIP2206F) {
if (typeKey != DFIPKeys::Active && typeKey != DFIPKeys::RewardPct && typeKey != DFIPKeys::BlockPeriod &&
typeKey != DFIPKeys::StartBlock) {
return Res::Err("Unsupported type for this DFIP {%d}", typeKey);
}
} else if (typeId == ParamIDs::DFIP2206A) {
if (typeKey != DFIPKeys::DUSDInterestBurn && typeKey != DFIPKeys::DUSDLoanBurn) {
return DeFiErrors::GovVarVariableUnsupportedDFIPType(typeKey);
}
} else if (typeId == ParamIDs::Feature) {
if (typeKey != DFIPKeys::GovUnset && typeKey != DFIPKeys::GovFoundation &&
typeKey != DFIPKeys::MNSetRewardAddress && typeKey != DFIPKeys::MNSetOperatorAddress &&
typeKey != DFIPKeys::MNSetOwnerAddress && typeKey != DFIPKeys::GovernanceEnabled &&
typeKey != DFIPKeys::ConsortiumEnabled && typeKey != DFIPKeys::CFPPayout &&
typeKey != DFIPKeys::EmissionUnusedFund && typeKey != DFIPKeys::MintTokens &&
typeKey != DFIPKeys::EVMEnabled && typeKey != DFIPKeys::ICXEnabled &&
typeKey != DFIPKeys::TransferDomain) {
return DeFiErrors::GovVarVariableUnsupportedFeatureType(typeKey);
}
} else if (typeId == ParamIDs::Foundation) {
if (typeKey != DFIPKeys::Members) {
return DeFiErrors::GovVarVariableUnsupportedFoundationType(typeKey);
}
} else {
return DeFiErrors::GovVarVariableUnsupportedParamType();
}
} else if (type == AttributeTypes::EVMType) {
if (typeId == EVMIDs::Block) {
if (typeKey != EVMKeys::Finalized && typeKey != EVMKeys::GasLimit && typeKey != EVMKeys::GasTarget) {
return DeFiErrors::GovVarVariableUnsupportedEVMType(typeKey);
}
} else {
return DeFiErrors::GovVarVariableUnsupportedGovType();
}
} else if (type == AttributeTypes::Governance) {
if (typeId == GovernanceIDs::Proposals) {
if (typeKey != GovernanceKeys::FeeRedistribution && typeKey != GovernanceKeys::FeeBurnPct &&
typeKey != GovernanceKeys::CFPFee && typeKey != GovernanceKeys::CFPApprovalThreshold &&
typeKey != GovernanceKeys::VOCFee && typeKey != GovernanceKeys::VOCApprovalThreshold &&
typeKey != GovernanceKeys::VOCEmergencyPeriod && typeKey != GovernanceKeys::VOCEmergencyFee &&
typeKey != GovernanceKeys::VOCEmergencyQuorum && typeKey != GovernanceKeys::Quorum &&
typeKey != GovernanceKeys::VotingPeriod && typeKey != GovernanceKeys::CFPMaxCycles) {
return DeFiErrors::GovVarVariableUnsupportedProposalType(typeKey);
}
} else {
return DeFiErrors::GovVarVariableUnsupportedGovType();
}
} else if (type == AttributeTypes::Transfer) {
if (typeId == TransferIDs::DVMToEVM) {
if (typeKey != TransferKeys::TransferEnabled && typeKey != TransferKeys::SrcFormats &&
typeKey != TransferKeys::DestFormats && typeKey != TransferKeys::NativeEnabled &&
typeKey != TransferKeys::DATEnabled && typeKey != TransferKeys::Disallowed) {
return DeFiErrors::GovVarVariableUnsupportedTransferType(typeKey);
}
} else if (typeId == TransferIDs::EVMToDVM) {
if (typeKey != TransferKeys::TransferEnabled && typeKey != TransferKeys::SrcFormats &&
typeKey != TransferKeys::DestFormats && typeKey != TransferKeys::AuthFormats &&
typeKey != TransferKeys::NativeEnabled && typeKey != TransferKeys::DATEnabled &&
typeKey != TransferKeys::Disallowed) {
return DeFiErrors::GovVarVariableUnsupportedTransferType(typeKey);
}
} else {
return DeFiErrors::GovVarVariableUnsupportedGovType();
}
} else if (type == AttributeTypes::Vaults) {
if (typeId == VaultIDs::DUSDVault) {
if (typeKey != VaultKeys::DUSDVaultEnabled) {
return DeFiErrors::GovVarVariableUnsupportedVaultsType(typeKey);
}
} else {
return DeFiErrors::GovVarVariableUnsupportedGovType();
}
} else if (type == AttributeTypes::Rules) {
if (typeId == RulesIDs::TXRules) {
if (typeKey != RulesKeys::CoreOPReturn && typeKey != RulesKeys::DVMOPReturn &&
typeKey != RulesKeys::EVMOPReturn) {
return DeFiErrors::GovVarVariableUnsupportedRulesType(typeKey);
}
} else {
return DeFiErrors::GovVarVariableUnsupportedGovType();
}
}

return Res::Ok();
}

Res ATTRIBUTES::ProcessVariable(const std::string &key,
const std::optional<UniValue> &value,
std::function<Res(const CAttributeType &, const CAttributeValue &)> applyVariable) {
Expand Down Expand Up @@ -1068,99 +1170,18 @@ Res ATTRIBUTES::ProcessVariable(const std::string &key,

typeKey = itype->second;

if (type == AttributeTypes::Param) {
if (typeId == ParamIDs::DFIP2201) {
if (typeKey != DFIPKeys::Active && typeKey != DFIPKeys::Premium && typeKey != DFIPKeys::MinSwap) {
return Res::Err("Unsupported type for DFIP2201 {%d}", typeKey);
}
} else if (typeId == ParamIDs::DFIP2203 || typeId == ParamIDs::DFIP2206F) {
if (typeKey != DFIPKeys::Active && typeKey != DFIPKeys::RewardPct && typeKey != DFIPKeys::BlockPeriod &&
typeKey != DFIPKeys::StartBlock) {
return Res::Err("Unsupported type for this DFIP {%d}", typeKey);
}
auto res = CheckValidAttrV0Key(type, typeId, typeKey);
if (!res) {
return res;
}

if (typeKey == DFIPKeys::BlockPeriod || typeKey == DFIPKeys::StartBlock) {
if (typeId == ParamIDs::DFIP2203) {
futureUpdated = true;
} else {
futureDUSDUpdated = true;
}
}
} else if (typeId == ParamIDs::DFIP2206A) {
if (typeKey != DFIPKeys::DUSDInterestBurn && typeKey != DFIPKeys::DUSDLoanBurn) {
return DeFiErrors::GovVarVariableUnsupportedDFIPType(typeKey);
}
} else if (typeId == ParamIDs::Feature) {
if (typeKey != DFIPKeys::GovUnset && typeKey != DFIPKeys::GovFoundation &&
typeKey != DFIPKeys::MNSetRewardAddress && typeKey != DFIPKeys::MNSetOperatorAddress &&
typeKey != DFIPKeys::MNSetOwnerAddress && typeKey != DFIPKeys::GovernanceEnabled &&
typeKey != DFIPKeys::ConsortiumEnabled && typeKey != DFIPKeys::CFPPayout &&
typeKey != DFIPKeys::EmissionUnusedFund && typeKey != DFIPKeys::MintTokens &&
typeKey != DFIPKeys::EVMEnabled && typeKey != DFIPKeys::ICXEnabled &&
typeKey != DFIPKeys::TransferDomain) {
return DeFiErrors::GovVarVariableUnsupportedFeatureType(typeKey);
}
} else if (typeId == ParamIDs::Foundation) {
if (typeKey != DFIPKeys::Members) {
return DeFiErrors::GovVarVariableUnsupportedFoundationType(typeKey);
}
} else {
return DeFiErrors::GovVarVariableUnsupportedParamType();
}
} else if (type == AttributeTypes::EVMType) {
if (typeId == EVMIDs::Block) {
if (typeKey != EVMKeys::Finalized && typeKey != EVMKeys::GasLimit && typeKey != EVMKeys::GasTarget) {
return DeFiErrors::GovVarVariableUnsupportedEVMType(typeKey);
}
} else {
return DeFiErrors::GovVarVariableUnsupportedGovType();
}
} else if (type == AttributeTypes::Governance) {
if (typeId == GovernanceIDs::Proposals) {
if (typeKey != GovernanceKeys::FeeRedistribution && typeKey != GovernanceKeys::FeeBurnPct &&
typeKey != GovernanceKeys::CFPFee && typeKey != GovernanceKeys::CFPApprovalThreshold &&
typeKey != GovernanceKeys::VOCFee && typeKey != GovernanceKeys::VOCApprovalThreshold &&
typeKey != GovernanceKeys::VOCEmergencyPeriod && typeKey != GovernanceKeys::VOCEmergencyFee &&
typeKey != GovernanceKeys::VOCEmergencyQuorum && typeKey != GovernanceKeys::Quorum &&
typeKey != GovernanceKeys::VotingPeriod && typeKey != GovernanceKeys::CFPMaxCycles) {
return DeFiErrors::GovVarVariableUnsupportedProposalType(typeKey);
}
} else {
return DeFiErrors::GovVarVariableUnsupportedGovType();
}
} else if (type == AttributeTypes::Transfer) {
if (typeId == TransferIDs::DVMToEVM) {
if (typeKey != TransferKeys::TransferEnabled && typeKey != TransferKeys::SrcFormats &&
typeKey != TransferKeys::DestFormats && typeKey != TransferKeys::NativeEnabled &&
typeKey != TransferKeys::DATEnabled && typeKey != TransferKeys::Disallowed) {
return DeFiErrors::GovVarVariableUnsupportedTransferType(typeKey);
}
} else if (typeId == TransferIDs::EVMToDVM) {
if (typeKey != TransferKeys::TransferEnabled && typeKey != TransferKeys::SrcFormats &&
typeKey != TransferKeys::DestFormats && typeKey != TransferKeys::AuthFormats &&
typeKey != TransferKeys::NativeEnabled && typeKey != TransferKeys::DATEnabled &&
typeKey != TransferKeys::Disallowed) {
return DeFiErrors::GovVarVariableUnsupportedTransferType(typeKey);
}
} else {
return DeFiErrors::GovVarVariableUnsupportedGovType();
}
} else if (type == AttributeTypes::Vaults) {
if (typeId == VaultIDs::DUSDVault) {
if (typeKey != VaultKeys::DUSDVaultEnabled) {
return DeFiErrors::GovVarVariableUnsupportedVaultsType(typeKey);
}
} else {
return DeFiErrors::GovVarVariableUnsupportedGovType();
}
} else if (type == AttributeTypes::Rules) {
if (typeId == RulesIDs::TXRules) {
if (typeKey != RulesKeys::CoreOPReturn && typeKey != RulesKeys::DVMOPReturn &&
typeKey != RulesKeys::EVMOPReturn) {
return DeFiErrors::GovVarVariableUnsupportedRulesType(typeKey);
if (type == AttributeTypes::Param && (typeId == ParamIDs::DFIP2203 || typeId == ParamIDs::DFIP2206F)) {
if (typeKey == DFIPKeys::BlockPeriod || typeKey == DFIPKeys::StartBlock) {
if (typeId == ParamIDs::DFIP2203) {
futureUpdated = true;
} else {
futureDUSDUpdated = true;
}
} else {
return DeFiErrors::GovVarVariableUnsupportedGovType();
}
}

Expand Down Expand Up @@ -1496,6 +1517,65 @@ std::set<uint32_t> attrsVersion27TokenHiddenSet = {
TokenKeys::Epitaph,
};

Res ATTRIBUTES::CheckKeys() const {
for (const auto &attribute : attributes) {
const auto attrV0 = std::get_if<CDataStructureV0>(&attribute.first);
if (!attrV0) {
return DeFiErrors::GovVarUnsupportedVersion();
}

// Check type
if (!displayTypes().count(attrV0->type)) {
return DeFiErrors::GovVarVariableInvalidKey("type", displayTypes());
}

// Check typeId
if (attrV0->type == AttributeTypes::Param) {
if (!allowedExportParamsIDs().count(attrV0->typeId)) {
return DeFiErrors::GovVarVariableInvalidKey("param", allowedExportParamsIDs());
}
} else if (attrV0->type == AttributeTypes::Locks) {
if (!displayLocksIDs().count(attrV0->typeId)) {
return DeFiErrors::GovVarVariableInvalidKey("locks", displayLocksIDs());
}
} else if (attrV0->type == AttributeTypes::EVMType) {
if (!displayEVMIDs().count(attrV0->typeId)) {
return DeFiErrors::GovVarVariableInvalidKey("evm", displayEVMIDs());
}
} else if (attrV0->type == AttributeTypes::Oracles) {
if (!displayOracleIDs().count(attrV0->typeId)) {
return DeFiErrors::GovVarVariableInvalidKey("oracles", displayOracleIDs());
}
} else if (attrV0->type == AttributeTypes::Governance) {
if (!displayGovernanceIDs().count(attrV0->typeId)) {
return DeFiErrors::GovVarVariableInvalidKey("governance", displayGovernanceIDs());
}
} else if (attrV0->type == AttributeTypes::Transfer) {
if (!displayTransferIDs().count(attrV0->typeId)) {
return DeFiErrors::GovVarVariableInvalidKey("transferdomain", displayTransferIDs());
}
} else if (attrV0->type == AttributeTypes::Vaults) {
if (!displayVaultIDs().count(attrV0->typeId)) {
return DeFiErrors::GovVarVariableInvalidKey("vaults", displayVaultIDs());
}
} else if (attrV0->type == AttributeTypes::Rules) {
if (!displayRulesIDs().count(attrV0->typeId)) {
return DeFiErrors::GovVarVariableInvalidKey("rules", displayRulesIDs());
}
}

// Check key - Locks and Oracles have height int keys so skip.
if (attrV0->type != AttributeTypes::Locks && attrV0->type != AttributeTypes::Oracles) {
auto res = CheckValidAttrV0Key(attrV0->type, attrV0->typeId, attrV0->key);
if (!res) {
return res;
}
}
}

return Res::Ok();
}

UniValue ATTRIBUTES::ExportFiltered(GovVarsFilter filter, const std::string &prefix) const {
UniValue ret(UniValue::VOBJ);
for (const auto &attribute : attributes) {
Expand Down
Loading