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

Parameterised block time #2955

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
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
Loading