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

Feature gate transferdomain. #2175

Merged
merged 4 commits into from
Jul 14, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,7 @@ void SetupCommonArgActivationParams(Consensus::Params &consensus) {
UpdateHeightValidation("Changi Intermediate", "-changiintermediateheight", consensus.ChangiIntermediateHeight);
UpdateHeightValidation("Changi Intermediate2", "-changiintermediate2height", consensus.ChangiIntermediateHeight2);
UpdateHeightValidation("Changi Intermediate3", "-changiintermediate3height", consensus.ChangiIntermediateHeight3);
UpdateHeightValidation("Changi Intermediate4", "-changiintermediate4height", consensus.ChangiIntermediateHeight4);

if (gArgs.GetBoolArg("-simulatemainnet", false)) {
consensus.pos.nTargetTimespan = 5 * 60; // 5 min == 10 blocks
Expand Down
1 change: 1 addition & 0 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,7 @@ void SetupServerArgs()
gArgs.AddArg("-changiintermediateheight", "Changi Intermediate fork activation height (regtest only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-changiintermediate2height", "Changi Intermediate2 fork activation height (regtest only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-changiintermediate3height", "Changi Intermediate3 fork activation height (regtest only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-changiintermediate4height", "Changi Intermediate4 fork activation height (regtest only)", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::CHAINPARAMS);
gArgs.AddArg("-jellyfish_regtest", "Configure the regtest network for jellyfish testing", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS);
gArgs.AddArg("-regtest-skip-loan-collateral-validation", "Skip loan collateral check for jellyfish testing", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS);
gArgs.AddArg("-regtest-minttoken-simulate-mainnet", "Simulate mainnet for minttokens on regtest - default behavior on regtest is to allow anyone to mint mintable tokens for ease of testing", ArgsManager::ALLOW_ANY | ArgsManager::DEBUG_ONLY, OptionsCategory::OPTIONS);
Expand Down
16 changes: 16 additions & 0 deletions src/masternodes/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,10 @@ class DeFiErrors {
return Res::Err("Unsupported key for Governance Proposal section - {%d}", type);
}

static Res GovVarVariableUnsupportedTransferType(const unsigned char type) {
return Res::Err("Unsupported key for Transfer Domain {%d}", type);
}

static Res GovVarVariableUnsupportedParamType() {
return Res::Err("Unsupported Param ID");
}
Expand Down Expand Up @@ -410,6 +414,10 @@ class DeFiErrors {
return Res::Err("tx must have at least one input from account owner");
}

static Res TransferDomainNotEnabled() {
return Res::Err("Cannot create tx, transfer domain is not enabled");
}

static Res TransferDomainEVMNotEnabled() {
return Res::Err("Cannot create tx, EVM is not enabled");
}
Expand All @@ -426,6 +434,14 @@ class DeFiErrors {
return Res::Err("For transferdomain, only DFI token is currently supported");
}

static Res TransferDomainEVMDVMNotEnabled() {
return Res::Err("EVM to DVM is not currently enabled");
}

static Res TransferDomainDVMEVMNotEnabled() {
return Res::Err("DVM to EVM is not currently enabled");
}

static Res TransferDomainETHSourceAddress() {
return Res::Err("Src address must be an ETH address in case of \"EVM\" domain");
}
Expand Down
87 changes: 71 additions & 16 deletions src/masternodes/govvariables/attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,27 +51,29 @@ const std::map<uint8_t, std::string> &ATTRIBUTES::displayVersions() {

const std::map<std::string, uint8_t> &ATTRIBUTES::allowedTypes() {
static const std::map<std::string, uint8_t> types{
{"locks", AttributeTypes::Locks },
{"oracles", AttributeTypes::Oracles },
{"params", AttributeTypes::Param },
{"poolpairs", AttributeTypes::Poolpairs },
{"token", AttributeTypes::Token },
{"gov", AttributeTypes::Governance},
{"consortium", AttributeTypes::Consortium},
{"locks", AttributeTypes::Locks },
{"oracles", AttributeTypes::Oracles },
{"params", AttributeTypes::Param },
{"poolpairs", AttributeTypes::Poolpairs },
{"token", AttributeTypes::Token },
{"gov", AttributeTypes::Governance},
{"consortium", AttributeTypes::Consortium},
{"transferdomain", AttributeTypes::Transfer },
};
return types;
}

const std::map<uint8_t, std::string> &ATTRIBUTES::displayTypes() {
static const std::map<uint8_t, std::string> types{
{AttributeTypes::Live, "live" },
{AttributeTypes::Locks, "locks" },
{AttributeTypes::Oracles, "oracles" },
{AttributeTypes::Param, "params" },
{AttributeTypes::Poolpairs, "poolpairs" },
{AttributeTypes::Token, "token" },
{AttributeTypes::Governance, "gov" },
{AttributeTypes::Consortium, "consortium"},
{AttributeTypes::Live, "live" },
{AttributeTypes::Locks, "locks" },
{AttributeTypes::Oracles, "oracles" },
{AttributeTypes::Param, "params" },
{AttributeTypes::Poolpairs, "poolpairs" },
{AttributeTypes::Token, "token" },
{AttributeTypes::Governance, "gov" },
{AttributeTypes::Consortium, "consortium" },
{AttributeTypes::Transfer, "transferdomain"},
};
return types;
}
Expand Down Expand Up @@ -142,6 +144,20 @@ const std::map<uint8_t, std::string> &ATTRIBUTES::displayGovernanceIDs() {
return params;
}

const std::map<std::string, uint8_t> &ATTRIBUTES::allowedTransferIDs() {
static const std::map<std::string, uint8_t> params{
{"allowed", TransferIDs::Edges},
};
return params;
}

const std::map<uint8_t, std::string> &ATTRIBUTES::displayTransferIDs() {
static const std::map<uint8_t, std::string> params{
{TransferIDs::Edges, "allowed"},
};
return params;
}

const std::map<uint8_t, std::map<std::string, uint8_t>> &ATTRIBUTES::allowedKeys() {
static const std::map<uint8_t, std::map<std::string, uint8_t>> keys{
{AttributeTypes::Token,
Expand Down Expand Up @@ -197,6 +213,7 @@ const std::map<uint8_t, std::map<std::string, uint8_t>> &ATTRIBUTES::allowedKeys
{"emission-unused-fund", DFIPKeys::EmissionUnusedFund},
{"mint-tokens-to-address", DFIPKeys::MintTokens},
{"allow-dusd-loops", DFIPKeys::AllowDUSDLoops},
{"transferdomain", DFIPKeys::TransferDomain},
}},
{AttributeTypes::Governance,
{
Expand All @@ -213,6 +230,11 @@ const std::map<uint8_t, std::map<std::string, uint8_t>> &ATTRIBUTES::allowedKeys
{"voting_period", GovernanceKeys::VotingPeriod},
{"cfp_max_cycles", GovernanceKeys::CFPMaxCycles},
}},
{AttributeTypes::Transfer,
{
{"evm-dvm", TransferKeys::EVM_DVM},
{"dvm-evm", TransferKeys::DVM_EVM},
}},
};
return keys;
}
Expand Down Expand Up @@ -275,6 +297,7 @@ const std::map<uint8_t, std::map<uint8_t, std::string>> &ATTRIBUTES::displayKeys
{DFIPKeys::EmissionUnusedFund, "emission-unused-fund"},
{DFIPKeys::MintTokens, "mint-tokens-to-address"},
{DFIPKeys::AllowDUSDLoops, "allow-dusd-loops"},
{DFIPKeys::TransferDomain, "transferdomain"},
}},
{AttributeTypes::Live,
{
Expand Down Expand Up @@ -310,6 +333,11 @@ const std::map<uint8_t, std::map<uint8_t, std::string>> &ATTRIBUTES::displayKeys
{GovernanceKeys::VotingPeriod, "voting_period"},
{GovernanceKeys::CFPMaxCycles, "cfp_max_cycles"},
}},
{AttributeTypes::Transfer,
{
{TransferKeys::EVM_DVM, "evm-dvm"},
{TransferKeys::DVM_EVM, "dvm-evm"},
}},
};
return keys;
}
Expand Down Expand Up @@ -604,6 +632,7 @@ const std::map<uint8_t, std::map<uint8_t, std::function<ResVal<CAttributeValue>(
{DFIPKeys::EmissionUnusedFund, VerifyBool},
{DFIPKeys::MintTokens, VerifyBool},
{DFIPKeys::AllowDUSDLoops, VerifyBool},
{DFIPKeys::TransferDomain, VerifyBool},
}},
{AttributeTypes::Locks,
{
Expand All @@ -628,6 +657,11 @@ const std::map<uint8_t, std::map<uint8_t, std::function<ResVal<CAttributeValue>(
{GovernanceKeys::VotingPeriod, VerifyUInt32},
{GovernanceKeys::CFPMaxCycles, VerifyUInt32},
}},
{AttributeTypes::Transfer,
{
{TransferKeys::EVM_DVM, VerifyBool},
{TransferKeys::DVM_EVM, VerifyBool},
}},
};
return parsers;
}
Expand Down Expand Up @@ -747,6 +781,12 @@ Res ATTRIBUTES::ProcessVariable(const std::string &key,
return DeFiErrors::GovVarVariableInvalidKey("governance", allowedGovernanceIDs());
}
typeId = id->second;
} else if (type == AttributeTypes::Transfer) {
auto id = allowedTransferIDs().find(keys[2]);
if (id == allowedTransferIDs().end()) {
return DeFiErrors::GovVarVariableInvalidKey("transferdomain", allowedTransferIDs());
}
typeId = id->second;
} else {
auto id = VerifyInt32(keys[2]);
if (!id) {
Expand Down Expand Up @@ -815,7 +855,7 @@ Res ATTRIBUTES::ProcessVariable(const std::string &key,
typeKey != DFIPKeys::ConsortiumEnabled && typeKey != DFIPKeys::CFPPayout &&
typeKey != DFIPKeys::EmissionUnusedFund && typeKey != DFIPKeys::MintTokens &&
typeKey != DFIPKeys::EVMEnabled && typeKey != DFIPKeys::ICXEnabled &&
typeKey != DFIPKeys::AllowDUSDLoops) {
typeKey != DFIPKeys::AllowDUSDLoops && typeKey != DFIPKeys::TransferDomain) {
return DeFiErrors::GovVarVariableUnsupportedFeatureType(typeKey);
}
} else if (typeId == ParamIDs::Foundation) {
Expand All @@ -837,6 +877,13 @@ Res ATTRIBUTES::ProcessVariable(const std::string &key,
} else {
return DeFiErrors::GovVarVariableUnsupportedGovType();
}
} else if (type == AttributeTypes::Transfer) {
if (typeId == TransferIDs::Edges) {
if (typeKey != TransferKeys::DVM_EVM && typeKey != TransferKeys::EVM_DVM)
return DeFiErrors::GovVarVariableUnsupportedTransferType(typeKey);
} else {
return DeFiErrors::GovVarVariableUnsupportedGovType();
}
}

attrV0 = CDataStructureV0{type, typeId, typeKey};
Expand Down Expand Up @@ -1145,6 +1192,8 @@ UniValue ATTRIBUTES::ExportFiltered(GovVarsFilter filter, const std::string &pre
id = displayOracleIDs().at(attrV0->typeId);
} else if (attrV0->type == AttributeTypes::Governance) {
id = displayGovernanceIDs().at(attrV0->typeId);
} else if (attrV0->type == AttributeTypes::Transfer) {
id = displayTransferIDs().at(attrV0->typeId);
} else {
id = KeyBuilder(attrV0->typeId);
}
Expand Down Expand Up @@ -1556,6 +1605,12 @@ Res ATTRIBUTES::Validate(const CCustomCSView &view) const {
}
break;

case AttributeTypes::Transfer:
if (view.GetLastHeight() < Params().GetConsensus().NextNetworkUpgradeHeight) {
return Res::Err("Cannot be set before NextNetworkUpgrade");
}
break;

default:
return Res::Err("Unrecognised type (%d)", attrV0->type);
}
Expand Down
13 changes: 13 additions & 0 deletions src/masternodes/govvariables/attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum AttributeTypes : uint8_t {
Locks = 'L',
Governance = 'g',
Consortium = 'c',
Transfer = 'b',
};

enum ParamIDs : uint8_t {
Expand All @@ -46,6 +47,10 @@ enum GovernanceIDs : uint8_t {
Proposals = 'b',
};

enum TransferIDs : uint8_t {
Edges = 'a',
};

enum EconomyKeys : uint8_t {
PaybackDFITokens = 'a',
PaybackTokens = 'b',
Expand Down Expand Up @@ -89,6 +94,7 @@ enum DFIPKeys : uint8_t {
EVMEnabled = 'u',
ICXEnabled = 'v',
AllowDUSDLoops = 'w',
TransferDomain = 'x',
};

enum GovernanceKeys : uint8_t {
Expand Down Expand Up @@ -138,6 +144,11 @@ enum PoolKeys : uint8_t {
TokenBFeeDir = 'd',
};

enum TransferKeys : uint8_t {
DVM_EVM = 'a',
EVM_DVM = 'b',
};

struct CDataStructureV0 {
uint8_t type;
uint32_t typeId;
Expand Down Expand Up @@ -424,6 +435,7 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
static const std::map<uint8_t, std::string> &displayOracleIDs();
static const std::map<uint8_t, std::string> &displayConsortiumIDs();
static const std::map<uint8_t, std::string> &displayGovernanceIDs();
static const std::map<uint8_t, std::string> &displayTransferIDs();
static const std::map<uint8_t, std::map<uint8_t, std::string>> &displayKeys();

Res RefundFuturesContracts(CCustomCSView &mnview,
Expand All @@ -447,6 +459,7 @@ class ATTRIBUTES : public GovVariable, public AutoRegistrator<GovVariable, ATTRI
static const std::map<std::string, uint8_t> &allowedOracleIDs();
static const std::map<std::string, uint8_t> &allowedConsortiumIDs();
static const std::map<std::string, uint8_t> &allowedGovernanceIDs();
static const std::map<std::string, uint8_t> &allowedTransferIDs();
static const std::map<uint8_t, std::map<std::string, uint8_t>> &allowedKeys();
static const std::map<uint8_t, std::map<uint8_t, std::function<ResVal<CAttributeValue>(const std::string &)>>>
&parseValue();
Expand Down
44 changes: 42 additions & 2 deletions src/masternodes/mn_checks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4018,11 +4018,18 @@ static Res ValidateTransferDomainScripts(const CScript &srcScript, const CScript
return DeFiErrors::TransferDomainUnknownEdge();
}

struct TransferDomainLiveConfig {
bool dvmToEvm;
bool evmTodvm;
};

Res ValidateTransferDomainEdge(const CTransaction &tx,
const TransferDomainLiveConfig &transferdomainConfig,
uint32_t height,
const CCoinsViewCache &coins,
const Consensus::Params &consensus,
CTransferDomainItem src, CTransferDomainItem dst) {
CTransferDomainItem src,
CTransferDomainItem dst) {

// TODO: Remove code branch on stable.
if (height < static_cast<uint32_t>(consensus.ChangiIntermediateHeight3)) {
Expand All @@ -4040,13 +4047,25 @@ Res ValidateTransferDomainEdge(const CTransaction &tx,
return DeFiErrors::TransferDomainIncorrectToken();

if (src.domain == static_cast<uint8_t>(VMDomain::DVM) && dst.domain == static_cast<uint8_t>(VMDomain::EVM)) {
if (height >= static_cast<uint32_t>(consensus.ChangiIntermediateHeight4)) {
if (!transferdomainConfig.dvmToEvm) {
return DeFiErrors::TransferDomainDVMEVMNotEnabled();
}
}

// DVM to EVM
auto res = ValidateTransferDomainScripts(src.address, dst.address, VMDomainEdge::DVMToEVM);
if (!res) return res;

return HasAuth(tx, coins, src.address);

} else if (src.domain == static_cast<uint8_t>(VMDomain::EVM) && dst.domain == static_cast<uint8_t>(VMDomain::DVM)) {
if (height >= static_cast<uint32_t>(consensus.ChangiIntermediateHeight4)) {
if (!transferdomainConfig.evmTodvm) {
return DeFiErrors::TransferDomainEVMDVMNotEnabled();
}
}

// EVM to DVM
auto res = ValidateTransferDomainScripts(src.address, dst.address, VMDomainEdge::EVMToDVM);
if (!res) return res;
Expand All @@ -4069,14 +4088,24 @@ Res ValidateTransferDomain(const CTransaction &tx,
return DeFiErrors::TransferDomainEVMNotEnabled();
}

if (!IsTransferDomainEnabled(height, mnview, consensus)) {
return DeFiErrors::TransferDomainNotEnabled();
}

if (height >= static_cast<uint32_t>(consensus.ChangiIntermediateHeight4)) {
if (obj.transfers.size() < 1) {
return DeFiErrors::TransferDomainInvalid();
}
}

CDataStructureV0 evm_dvm{AttributeTypes::Transfer, TransferIDs::Edges, TransferKeys::EVM_DVM};
CDataStructureV0 dvm_evm{AttributeTypes::Transfer, TransferIDs::Edges, TransferKeys::DVM_EVM};
const auto attributes = mnview.GetAttributes();
assert(attributes);
TransferDomainLiveConfig transferdomainConfig{attributes->GetValue(dvm_evm, false), attributes->GetValue(evm_dvm, false)};

for (const auto &[src, dst] : obj.transfers) {
auto res = ValidateTransferDomainEdge(tx, height, coins, consensus, src, dst);
auto res = ValidateTransferDomainEdge(tx, transferdomainConfig, height, coins, consensus, src, dst);
if (!res) return res;
}

Expand Down Expand Up @@ -5088,3 +5117,14 @@ bool IsEVMEnabled(const int height, const CCustomCSView &view, const Consensus::
assert(attributes);
return attributes->GetValue(enabledKey, false);
}

bool IsTransferDomainEnabled(const int height, const CCustomCSView &view, const Consensus::Params &consensus) {
if (height < consensus.NextNetworkUpgradeHeight) {
return false;
}

const CDataStructureV0 enabledKey{AttributeTypes::Param, ParamIDs::Feature, DFIPKeys::TransferDomain};
auto attributes = view.GetAttributes();
assert(attributes);
return attributes->GetValue(enabledKey, false);
}
1 change: 1 addition & 0 deletions src/masternodes/mn_checks.h
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ bool IsTestNetwork();
bool IsMainNetwork();
bool IsICXEnabled(const int height, const CCustomCSView &view, const Consensus::Params &consensus);
bool IsEVMEnabled(const int height, const CCustomCSView &view, const Consensus::Params &consensus);
bool IsTransferDomainEnabled(const int height, const CCustomCSView &view, const Consensus::Params &consensus);
Res HasAuth(const CTransaction &tx, const CCoinsViewCache &coins, const CScript &auth, AuthStrategy strategy = AuthStrategy::DirectPubKeyMatch);
Res ValidateTransferDomain(const CTransaction &tx,
uint32_t height,
Expand Down
Loading