diff --git a/src/masternodes/govvariables/attributes.cpp b/src/masternodes/govvariables/attributes.cpp index 36851f3b9c..3cc7de6fca 100644 --- a/src/masternodes/govvariables/attributes.cpp +++ b/src/masternodes/govvariables/attributes.cpp @@ -133,20 +133,20 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value UniValue univalue; auto typeKey = itype->second; - CValueV0 valueV0; + CAttributeValue attribValue; if (type == AttributeTypes::Token) { if (typeKey == TokenKeys::PaybackDFI) { if (value != "true" && value != "false") { return Res::Err("Payback DFI value must be either \"true\" or \"false\""); } - valueV0 = value == "true"; + attribValue = value == "true"; } else if (typeKey == TokenKeys::PaybackDFIFeePCT) { auto res = VerifyPct(value); if (!res) { return std::move(res); } - valueV0 = *res.val; + attribValue = *res.val; } else { return Res::Err("Unrecognised key"); } @@ -157,7 +157,7 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value if (!res) { return std::move(res); } - valueV0 = *res.val; + attribValue = *res.val; } else { return Res::Err("Unrecognised key"); } @@ -167,19 +167,19 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value if (value != "true" && value != "false") { return Res::Err("DFIP2201 actve value must be either \"true\" or \"false\""); } - valueV0 = value == "true"; + attribValue = value == "true"; } else if (typeKey == DFIP2201Keys::Premium) { auto res = VerifyPct(value); if (!res) { return std::move(res); } - valueV0 = *res.val; + attribValue = *res.val; } else if (typeKey == DFIP2201Keys::MinSwap) { auto res = VerifyFloat(value); if (!res) { return std::move(res); } - valueV0 = *res.val; + attribValue = *res.val; } else { return Res::Err("Unrecognised key"); } @@ -189,7 +189,7 @@ Res ATTRIBUTES::ProcessVariable(const std::string& key, const std::string& value } if (applyVariable) { - return applyVariable(CDataStructureV0{type, typeId, typeKey}, valueV0); + return applyVariable(CDataStructureV0{type, typeId, typeKey}, attribValue); } return Res::Ok(); } @@ -223,10 +223,6 @@ UniValue ATTRIBUTES::Export() const { if (!attrV0) { continue; } - auto valV0 = boost::get(&attribute.second); - if (!valV0) { - continue; - } try { const std::string id = attrV0->type == AttributeTypes::Param ? displayParamsIDs.at(attrV0->typeId) : KeyBuilder(attrV0->typeId); auto key = KeyBuilder(displayVersions.at(VersionTypes::v0), @@ -234,9 +230,9 @@ UniValue ATTRIBUTES::Export() const { id, displayKeys.at(attrV0->type).at(attrV0->key)); - if (auto bool_val = boost::get(valV0)) { + if (auto bool_val = boost::get(&attribute.second)) { ret.pushKV(key, *bool_val ? "true" : "false"); - } else if (auto amount = boost::get(valV0)) { + } else if (auto amount = boost::get(&attribute.second)) { auto uvalue = ValueFromAmount(*amount); ret.pushKV(key, KeyBuilder(uvalue.get_real())); } @@ -257,30 +253,26 @@ Res ATTRIBUTES::Validate(const CCustomCSView & view) const if (!attrV0) { return Res::Err("Unsupported version"); } - auto valV0 = boost::get(&attribute.second); - if (!valV0) { - return Res::Err("Unsupported value"); - } if (attrV0->type == AttributeTypes::Token) { uint32_t tokenId = attrV0->typeId; if (!view.GetLoanTokenByID(DCT_ID{tokenId})) { return Res::Err("No such loan token (%d)", tokenId); } if (attrV0->key == TokenKeys::PaybackDFI) { - if (!boost::get(valV0)) { + if (!boost::get(&attribute.second)) { return Res::Err("Unsupported value"); } continue; } if (attrV0->key == TokenKeys::PaybackDFIFeePCT) { - if (!boost::get(valV0)) { + if (!boost::get(&attribute.second)) { return Res::Err("Unsupported value"); } continue; } } if (attrV0->type == AttributeTypes::Poolpairs) { - if (!boost::get(valV0)) { + if (!boost::get(&attribute.second)) { return Res::Err("Unsupported value"); } uint32_t poolId = attrV0->typeId; @@ -317,12 +309,10 @@ Res ATTRIBUTES::Apply(CCustomCSView & mnview, const uint32_t height) auto tokenId = attrV0->key == PoolKeys::TokenAFeePCT ? pool->idTokenA : pool->idTokenB; - if (auto valV0 = boost::get(&attribute.second)) { - auto valuePct = boost::get(*valV0); - auto res = mnview.SetDexFeePct(DCT_ID{poolId}, tokenId, valuePct); - if (!res) { - return res; - } + auto valuePct = boost::get(attribute.second); + auto res = mnview.SetDexFeePct(DCT_ID{poolId}, tokenId, valuePct); + if (!res) { + return res; } } } diff --git a/src/masternodes/govvariables/attributes.h b/src/masternodes/govvariables/attributes.h index fc746e8ee6..caeed5553d 100644 --- a/src/masternodes/govvariables/attributes.h +++ b/src/masternodes/govvariables/attributes.h @@ -38,8 +38,6 @@ enum PoolKeys : uint8_t { TokenBFeePCT = 'b', }; -using CValueV0 = boost::variant; - struct CDataStructureV0 { uint8_t type; uint32_t typeId; @@ -71,15 +69,8 @@ struct CDataStructureV1 { bool operator<(const CDataStructureV1& o) const { return false; } }; -struct CValueV1 { - ADD_SERIALIZE_METHODS; - - template - inline void SerializationOp(Stream& s, Operation ser_action) {} -}; - using CAttributeType = boost::variant; -using CAttributeValue = boost::variant; +using CAttributeValue = boost::variant; class ATTRIBUTES : public GovVariable, public AutoRegistrator { @@ -98,6 +89,17 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator + T GetValue(const CAttributeType& key, T value) { + auto it = attributes.find(key); + if (it != attributes.end()) { + if (auto val = boost::get(&it->second)) { + value = *val; + } + } + return std::move(value); + } + ADD_OVERRIDE_VECTOR_SERIALIZE_METHODS ADD_OVERRIDE_SERIALIZE_METHODS(CDataStream) diff --git a/src/masternodes/mn_checks.cpp b/src/masternodes/mn_checks.cpp index 9bf291eb71..a304bb07db 100644 --- a/src/masternodes/mn_checks.cpp +++ b/src/masternodes/mn_checks.cpp @@ -1344,26 +1344,13 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor } Res operator()(const CSmartContractMessage& obj) const { - const auto pAttributes = mnview.GetAttributes(); - if (!pAttributes) { + const auto attributes = mnview.GetAttributes(); + if (!attributes) { return Res::Err("DFIP2201 smart contract is not enabled"); } - const auto& attrs = pAttributes->attributes; CDataStructureV0 activeKey{AttributeTypes::Param, ParamIDs::DFIP2201, DFIP2201Keys::Active}; - try { - const auto& value = attrs.at(activeKey); - auto valueV0 = boost::get(&value); - - if (!valueV0) { - throw std::out_of_range(""); - } - - const auto active = boost::get(valueV0); - if (!active || !*active) { - throw std::out_of_range(""); - } - } catch (const std::out_of_range&) { + if (!attributes->GetValue(activeKey, false)) { return Res::Err("DFIP2201 smart contract is not enabled"); } @@ -1393,16 +1380,7 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor } CDataStructureV0 minSwapKey{AttributeTypes::Param, ParamIDs::DFIP2201, DFIP2201Keys::MinSwap}; - CAmount minSwap{0}; - try { - const auto& value = attrs.at(minSwapKey); - auto valueV0 = boost::get(&value); - if (valueV0) { - if (auto storedMinSwap = boost::get(valueV0)) { - minSwap = *storedMinSwap; - } - } - } catch (const std::out_of_range&) {} + auto minSwap = attributes->GetValue(minSwapKey, CAmount{0}); if (minSwap && amount < minSwap) { return Res::Err("Below minimum swapable amount, must be at least " + ValueFromAmount(minSwap).getValStr() + " BTC"); @@ -1431,26 +1409,17 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor return std::move(resVal); } - CDataStructureV0 feePctKey{AttributeTypes::Param, ParamIDs::DFIP2201, DFIP2201Keys::Premium}; - CAmount feePct{2500000}; - try { - const auto& value = attrs.at(feePctKey); - auto valueV0 = boost::get(&value); - if (valueV0) { - if (auto storedFeePct = boost::get(valueV0)) { - feePct = *storedFeePct; - } - } - } catch (const std::out_of_range&) {} + CDataStructureV0 premiumKey{AttributeTypes::Param, ParamIDs::DFIP2201, DFIP2201Keys::Premium}; + auto premium = attributes->GetValue(premiumKey, CAmount{2500000}); - const auto& btcPrice = MultiplyAmounts(resVal.val.get(), feePct + COIN); + const auto& btcPrice = MultiplyAmounts(*resVal.val, premium + COIN); resVal = mnview.GetValidatedIntervalPrice(dfiUsd, useNextPrice, requireLivePrice); if (!resVal) { return std::move(resVal); } - const auto totalDFI = MultiplyAmounts(DivideAmounts(btcPrice, resVal.val.get()), amount); + const auto totalDFI = MultiplyAmounts(DivideAmounts(btcPrice, *resVal.val), amount); res = mnview.SubBalance(Params().GetConsensus().smartContracts.begin()->second, {{0}, totalDFI}); if (!res) { @@ -2828,22 +2797,10 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor auto allowDFIPayback = false; std::map attrs; auto tokenDUSD = mnview.GetToken("DUSD"); - if (tokenDUSD) { - const auto pAttributes = mnview.GetAttributes(); - if (pAttributes) { - attrs = pAttributes->attributes; - CDataStructureV0 activeKey{AttributeTypes::Token, tokenDUSD->first.v, TokenKeys::PaybackDFI}; - try { - const auto& value = attrs.at(activeKey); - auto valueV0 = boost::get(&value); - if (valueV0) { - const auto active = boost::get(valueV0); - if (active != nullptr && *active) { - allowDFIPayback = true; - } - } - } catch (const std::out_of_range&) {} - } + auto attributes = mnview.GetAttributes(); + if (tokenDUSD && attributes) { + CDataStructureV0 activeKey{AttributeTypes::Token, tokenDUSD->first.v, TokenKeys::PaybackDFI}; + allowDFIPayback = attributes->GetValue(activeKey, false); } for (const auto& kv : obj.amounts.balances) @@ -2867,17 +2824,9 @@ class CCustomTxApplyVisitor : public CCustomTxVisitor } // Apply penalty - CAmount penalty{99000000}; // Update from Gov var CDataStructureV0 penaltyKey{AttributeTypes::Token, tokenDUSD->first.v, TokenKeys::PaybackDFIFeePCT}; - try { - const auto& value = attrs.at(penaltyKey); - auto valueV0 = boost::get(&value); - if (valueV0) { - if (auto storedPenalty = boost::get(valueV0)) { - penalty = COIN - *storedPenalty; - } - } - } catch (const std::out_of_range&) {} + auto penalty = COIN - attributes->GetValue(penaltyKey, COIN / 100); + dfiUSDPrice = MultiplyAmounts(*resVal.val, penalty); // Set tokenId to DUSD