Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion src/bench/duplicate_inputs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static void DuplicateInputs(benchmark::State& state)
coinbaseTx.vin[0].prevout.SetNull();
coinbaseTx.vout.resize(1);
coinbaseTx.vout[0].scriptPubKey = SCRIPT_PUB;
coinbaseTx.vout[0].nValue = GetBlockSubsidy(nHeight, chainparams.GetConsensus());
coinbaseTx.vout[0].nValue = GetBlockSubsidy(*pcustomcsview, nHeight, chainparams.GetConsensus());
coinbaseTx.vin[0].scriptSig = CScript() << nHeight << OP_0;


Expand Down
5 changes: 4 additions & 1 deletion src/chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@

#include <chain.h>

#include <dfi/govvariables/attributes.h>
#include <dfi/masternodes.h>

/**
* CChain implementation
*/
Expand Down Expand Up @@ -144,7 +147,7 @@ int64_t GetBlockProofEquivalentTime(const CBlockIndex& to, const CBlockIndex& fr
r = from.nChainWork - to.nChainWork;
sign = -1;
}
r = r * arith_uint256(params.pos.nTargetSpacing) / GetBlockProof(tip);
r = r * arith_uint256(GetTargetSpacing(*pcustomcsview)) / GetBlockProof(tip);
if (r.bits() > 63) {
return sign * std::numeric_limits<int64_t>::max();
}
Expand Down
15 changes: 0 additions & 15 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,21 +146,6 @@ struct Params {
};
PoS pos;

uint32_t blocksPerDay() const {
static const uint32_t blocks = 60 * 60 * 24 / pos.nTargetSpacing;
return blocks;
}

uint32_t blocksCollateralizationRatioCalculation() const {
static const uint32_t blocks = 15 * 60 / pos.nTargetSpacing;
return blocks;
}

uint32_t blocksCollateralAuction() const {
static const uint32_t blocks = 6 * 60 * 60 / pos.nTargetSpacing;
return blocks;
}

/**
* Minimum blocks including miner confirmation of the total of 2016 blocks in a retargeting period,
* (nTargetTimespan / nTargetSpacing) which is also used for BIP9 deployments.
Expand Down
13 changes: 8 additions & 5 deletions src/dfi/anchors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <chainparams.h>
#include <consensus/validation.h>
#include <dfi/govvariables/attributes.h>
#include <dfi/masternodes.h>
#include <key.h>
#include <logging.h>
Expand Down Expand Up @@ -848,12 +849,14 @@ bool ContextualValidateAnchor(const CAnchorData &anchor, CBlockIndex &anchorBloc
return error("%s: Post-fork anchor marker missing or incorrect.", __func__);
}

const auto frequency = pcustomcsview->GetAnchorFrequency();

// Only anchor by specified frequency
if (anchorCreationHeight % Params().GetConsensus().mn.anchoringFrequency != 0) {
if (anchorCreationHeight % frequency != 0) {
return error("%s: Anchor height does not meet frequency rule. Height %ld, frequency %d",
__func__,
anchorCreationHeight,
Params().GetConsensus().mn.anchoringFrequency);
frequency);
}

// Make sure height exist
Expand Down Expand Up @@ -883,7 +886,7 @@ bool ContextualValidateAnchor(const CAnchorData &anchor, CBlockIndex &anchorBloc
}

// Get start anchor height
int anchorHeight = static_cast<int>(anchorCreationHeight) - Params().GetConsensus().mn.anchoringFrequency;
int anchorHeight = static_cast<uint64_t>(anchorCreationHeight) - frequency;

// Recreate the creation height of the anchor
int64_t timeDepth = Params().GetConsensus().mn.anchoringTimeDepth;
Expand All @@ -900,12 +903,12 @@ bool ContextualValidateAnchor(const CAnchorData &anchor, CBlockIndex &anchorBloc
}

// Wind back further by anchoring frequency
while (anchorHeight > 0 && anchorHeight % Params().GetConsensus().mn.anchoringFrequency != 0) {
while (anchorHeight > 0 && anchorHeight % frequency != 0) {
--anchorHeight;
}

// Check heights match
if (static_cast<int>(anchor.height) != anchorHeight) {
if (anchor.height != anchorHeight) {
return error(
"%s: Anchor height mismatch. Anchor height %d calculated height %d", __func__, anchor.height, anchorHeight);
}
Expand Down
15 changes: 15 additions & 0 deletions src/dfi/consensus/governance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ Res CGovernanceConsensus::operator()(const CGovernanceMessage &obj) const {
if (newExport.empty()) {
return Res::Err("Cannot export empty attribute map");
}

if (height >= static_cast<uint32_t>(consensus.DF24Height)) {
if (res = CheckTimeRelatedVars(*newVar); !res) {
return res;
}
}
}

CDataStructureV0 foundationMembers{AttributeTypes::Param, ParamIDs::Foundation, DFIPKeys::Members};
Expand Down Expand Up @@ -165,6 +171,9 @@ Res CGovernanceConsensus::operator()(const CGovernanceUnsetHeightMessage &obj) c
if (auto res = authCheck.CanSetGov(keys); !res) {
return res;
}
if (auto res = CheckTimeRelatedVars(keys); !res) {
return res;
}
}

auto var = mnview.GetVariable(name);
Expand Down Expand Up @@ -266,6 +275,12 @@ Res CGovernanceConsensus::operator()(const CGovernanceHeightMessage &obj) const
if (res = authCheck.CanSetGov(*newVar); !res) {
return res;
}

if (height >= static_cast<uint32_t>(consensus.DF24Height)) {
if (res = CheckTimeRelatedVars(*newVar); !res) {
return res;
}
}
}

auto storedGovVars = mnview.GetStoredVariablesRange(height, obj.startHeight);
Expand Down
20 changes: 15 additions & 5 deletions src/dfi/consensus/icxorders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,12 @@ Res CICXOrdersConsensus::operator()(const CICXMakeOfferMessage &obj) const {
return Res::Err("order with creation tx " + makeoffer.orderTx.GetHex() + " does not exists!");
}

auto expiry = static_cast<int>(height) < consensus.DF10EunosPayaHeight ? CICXMakeOffer::DEFAULT_EXPIRY
: CICXMakeOffer::EUNOSPAYA_DEFAULT_EXPIRY;
const auto attributes = mnview.GetAttributes();
const CDataStructureV0 key{AttributeTypes::Param, ParamIDs::ICX, DFIPKeys::OfferDefaultExpiry};
const auto defaultExpiry = attributes->GetValue(key, CICXMakeOffer::EUNOSPAYA_DEFAULT_EXPIRY);

auto expiry =
static_cast<int>(height) < consensus.DF10EunosPayaHeight ? CICXMakeOffer::DEFAULT_EXPIRY : defaultExpiry;

if (makeoffer.expiry < expiry) {
return Res::Err("offer expiry must be greater than %d!", expiry - 1);
Expand Down Expand Up @@ -198,6 +202,8 @@ Res CICXOrdersConsensus::operator()(const CICXSubmitDFCHTLCMessage &obj) const {
return Res::Err("dfc htlc already submitted!");
}

const auto attributes = mnview.GetAttributes();

CScript srcAddr;
if (order->orderType == CICXOrder::TYPE_INTERNAL) {
// check auth
Expand All @@ -212,7 +218,8 @@ Res CICXOrdersConsensus::operator()(const CICXSubmitDFCHTLCMessage &obj) const {
if (static_cast<int>(height) < consensus.DF10EunosPayaHeight) {
timeout = CICXSubmitDFCHTLC::MINIMUM_TIMEOUT;
} else {
timeout = CICXSubmitDFCHTLC::EUNOSPAYA_MINIMUM_TIMEOUT;
const CDataStructureV0 key{AttributeTypes::Param, ParamIDs::ICX, DFIPKeys::SubmitMinTimeout};
timeout = attributes->GetValue(key, CICXSubmitDFCHTLC::EUNOSPAYA_MINIMUM_TIMEOUT);
}

if (submitdfchtlc.timeout < timeout) {
Expand Down Expand Up @@ -297,7 +304,8 @@ Res CICXOrdersConsensus::operator()(const CICXSubmitDFCHTLCMessage &obj) const {
timeout = CICXSubmitDFCHTLC::MINIMUM_2ND_TIMEOUT;
btcBlocksInDfi = CICXSubmitEXTHTLC::BTC_BLOCKS_IN_DFI_BLOCKS;
} else {
timeout = CICXSubmitDFCHTLC::EUNOSPAYA_MINIMUM_2ND_TIMEOUT;
const CDataStructureV0 key{AttributeTypes::Param, ParamIDs::ICX, DFIPKeys::SubmitMin2ndTimeout};
timeout = attributes->GetValue(key, CICXSubmitDFCHTLC::EUNOSPAYA_MINIMUM_2ND_TIMEOUT);
btcBlocksInDfi = CICXSubmitEXTHTLC::BTC_BLOCKS_IN_DFI_BLOCKS;
}

Expand Down Expand Up @@ -382,7 +390,9 @@ Res CICXOrdersConsensus::operator()(const CICXSubmitEXTHTLCMessage &obj) const {
btcBlocksInDfi = CICXSubmitEXTHTLC::BTC_BLOCKS_IN_DFI_BLOCKS;
} else {
timeout = CICXSubmitEXTHTLC::EUNOSPAYA_MINIMUM_2ND_TIMEOUT;
btcBlocksInDfi = CICXSubmitEXTHTLC::EUNOSPAYA_BTC_BLOCKS_IN_DFI_BLOCKS;
const auto attributes = mnview.GetAttributes();
const CDataStructureV0 key{AttributeTypes::Param, ParamIDs::ICX, DFIPKeys::SubmitBTCBlocksInDFI};
btcBlocksInDfi = attributes->GetValue(key, CICXSubmitEXTHTLC::EUNOSPAYA_BTC_BLOCKS_IN_DFI_BLOCKS);
}

if (submitexthtlc.timeout < timeout) {
Expand Down
2 changes: 1 addition & 1 deletion src/dfi/consensus/masternodes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Res CMasternodesConsensus::CheckMasternodeCreationTx() const {
const auto height = txCtx.GetHeight();
const auto &tx = txCtx.GetTransaction();

if (tx.vout.size() < 2 || tx.vout[0].nValue < GetMnCreationFee(height) || tx.vout[0].nTokenId != DCT_ID{0} ||
if (tx.vout.size() < 2 || tx.vout[0].nValue < GetMnCreationFee() || tx.vout[0].nTokenId != DCT_ID{0} ||
tx.vout[1].nValue != GetMnCollateralAmount(height) || tx.vout[1].nTokenId != DCT_ID{0}) {
return Res::Err("malformed tx vouts (wrong creation fee or collateral amount)");
}
Expand Down
76 changes: 76 additions & 0 deletions src/dfi/consensus/txvisitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,82 @@ Res AuthManager::CanSetGov(const ATTRIBUTES &var) {
return Res::Ok();
}

static Res CheckTimeRelatedVarsInternal(const std::set<CDataStructureV0> &pendingKeys) {
std::set<CDataStructureV0> checkingKeys;
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::BlockTime, DFIPKeys::EmissionReduction});
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::BlockTime, DFIPKeys::TargetSpacing});
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::BlockTime, DFIPKeys::TargetTimespan});
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::Anchors, DFIPKeys::Frequency});
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::Anchors, DFIPKeys::TeamChange});
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::Masternodes, DFIPKeys::ActivationDelay});
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::Masternodes, DFIPKeys::ResignDelay});
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::ICX, DFIPKeys::OrderDefaultExpiry});
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::ICX, DFIPKeys::OfferDefaultExpiry});
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::ICX, DFIPKeys::OfferRefundTimeout});
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::ICX, DFIPKeys::SubmitMinTimeout});
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::ICX, DFIPKeys::SubmitMin2ndTimeout});
checkingKeys.insert(CDataStructureV0{AttributeTypes::Param, ParamIDs::ICX, DFIPKeys::SubmitBTCBlocksInDFI});

std::set<CDataStructureV0> intersection;
for (const auto &key : checkingKeys) {
if (pendingKeys.find(key) != pendingKeys.end()) {
intersection.insert(key);
}
}

if (intersection.empty() || intersection == checkingKeys) {
return Res::Ok();
}

return Res::Err(
"Param Time vars must be changed together. BlockTime: EmissionReduction, TargetSpacing, TargetTimespan. "
"Anchors: Frequency, TeamChange. Masternodes: ActivationDelay, ResignDelay. ICX: OrderDefaultExpiry, "
"OfferDefaultExpiry, OfferRefundTimeout, SubmitMinTimeout, SubmitMin2ndTimeout, SubmitBTCBlocksInDFI");
}

Res CheckTimeRelatedVars(const ATTRIBUTES &var) {
std::set<CDataStructureV0> pendingKeys;
var.ForEach(
[&](const CDataStructureV0 &attr, const CAttributeValue &) {
if (attr.type != AttributeTypes::Param) {
return false;
}
pendingKeys.insert(attr);
return true;
},
CDataStructureV0{AttributeTypes::Param});

if (const auto res = CheckTimeRelatedVarsInternal(pendingKeys); !res) {
return res;
}
return Res::Ok();
}

Res CheckTimeRelatedVars(const std::vector<std::string> &keys) {
if (keys.empty()) {
return Res::Err("No keys to check");
}
std::set<CDataStructureV0> pendingKeys;
for (const auto &key : keys) {
const auto res = ATTRIBUTES::ProcessVariable(key, std::nullopt, [&](const auto &attribute, const auto &) {
const auto attr = std::get_if<CDataStructureV0>(&attribute);
if (!attr) {
return Res::Err("Attribute type check failed");
}
pendingKeys.insert(*attr);
return Res::Ok();
});
if (!res) {
return res;
}
}

if (const auto res = CheckTimeRelatedVarsInternal(pendingKeys); !res) {
return res;
}
return Res::Ok();
}

Res AuthManager::HasGovOrFoundationAuth() {
if (HasFoundationAuth() || HasGovernanceAuth()) {
return Res::Ok();
Expand Down
2 changes: 2 additions & 0 deletions src/dfi/consensus/txvisitor.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ Res HasAuth(const CTransaction &tx,
AuthStrategy strategy = AuthStrategy::DirectPubKeyMatch,
AuthFlags::Type flags = AuthFlags::None);
Res GetERC55AddressFromAuth(const CTransaction &tx, const CCoinsViewCache &coins, CScript &script);
Res CheckTimeRelatedVars(const std::vector<std::string> &keys);
Res CheckTimeRelatedVars(const ATTRIBUTES &var);

class CCustomTxVisitor {
protected:
Expand Down
16 changes: 16 additions & 0 deletions src/dfi/errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,22 @@ class DeFiErrors {
return Res::Err("Unsupported key for Rules {%d}", type);
}

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

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

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

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

static Res GovVarVariableUnsupportedParamType() { return Res::Err("Unsupported Param ID"); }

static Res GovVarVariableUnsupportedGovType() { return Res::Err("Unsupported Governance ID"); }
Expand Down
Loading