Skip to content

Commit

Permalink
Harden spork15 on testnet (#2586)
Browse files Browse the repository at this point in the history
* Replace IsDeterministicMNsSporkActive with IsDIP3Active

IsDIP3Active will now use a fixed parameter from consensus params.
Values for DIP0003Height/DIP0003Hash need to be updated when spork15
activates on mainnet.

Also enforce correct block hash on testnet/mainnet for DIP3 activation
block.

* Remove SPORK_15_DETERMINISTIC_MNS_ENABLED

* Replace all uses of IsDeterministicMNsSporkActive with IsDIP3Active

* Remove DIP3 upgrade-path tests and directly start with DIP3 enabled tests

* Make -masternodeprivkey non-mandatory

This code will vanish later.
  • Loading branch information
codablock authored and UdjinM6 committed Dec 28, 2018
1 parent 361900e commit 0c9fb69
Show file tree
Hide file tree
Showing 27 changed files with 226 additions and 533 deletions.
505 changes: 95 additions & 410 deletions qa/rpc-tests/dip3-deterministicmns.py

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions src/activemasternode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ void CActiveDeterministicMasternodeManager::Init()

if (!fMasternodeMode) return;

if (!deterministicMNManager->IsDeterministicMNsSporkActive()) return;
if (!deterministicMNManager->IsDIP3Active()) return;

// Check that our local network configuration is correct
if (!fListen) {
Expand Down Expand Up @@ -133,7 +133,7 @@ void CActiveDeterministicMasternodeManager::UpdatedBlockTip(const CBlockIndex* p

if (!fMasternodeMode) return;

if (!deterministicMNManager->IsDeterministicMNsSporkActive(pindexNew->nHeight)) return;
if (!deterministicMNManager->IsDIP3Active(pindexNew->nHeight)) return;

if (state == MASTERNODE_READY) {
auto mnList = deterministicMNManager->GetListForBlock(pindexNew->GetBlockHash());
Expand Down Expand Up @@ -190,7 +190,7 @@ bool CActiveDeterministicMasternodeManager::GetLocalAddress(CService& addrRet)

void CActiveLegacyMasternodeManager::ManageState(CConnman& connman)
{
if (deterministicMNManager->IsDeterministicMNsSporkActive()) return;
if (deterministicMNManager->IsDIP3Active()) return;

LogPrint("masternode", "CActiveLegacyMasternodeManager::ManageState -- Start\n");
if (!fMasternodeMode) {
Expand Down Expand Up @@ -272,7 +272,7 @@ std::string CActiveLegacyMasternodeManager::GetTypeString() const

bool CActiveLegacyMasternodeManager::SendMasternodePing(CConnman& connman)
{
if (deterministicMNManager->IsDeterministicMNsSporkActive()) return false;
if (deterministicMNManager->IsDIP3Active()) return false;

if (!fPingerEnabled) {
LogPrint("masternode", "CActiveLegacyMasternodeManager::SendMasternodePing -- %s: masternode ping service is disabled, skipping...\n", GetStateString());
Expand Down Expand Up @@ -326,7 +326,7 @@ void CActiveLegacyMasternodeManager::DoMaintenance(CConnman& connman)

void CActiveLegacyMasternodeManager::ManageStateInitial(CConnman& connman)
{
if (deterministicMNManager->IsDeterministicMNsSporkActive()) return;
if (deterministicMNManager->IsDIP3Active()) return;

LogPrint("masternode", "CActiveLegacyMasternodeManager::ManageStateInitial -- status = %s, type = %s, pinger enabled = %d\n", GetStatus(), GetTypeString(), fPingerEnabled);

Expand Down Expand Up @@ -409,7 +409,7 @@ void CActiveLegacyMasternodeManager::ManageStateInitial(CConnman& connman)

void CActiveLegacyMasternodeManager::ManageStateRemote()
{
if (deterministicMNManager->IsDeterministicMNsSporkActive()) return;
if (deterministicMNManager->IsDIP3Active()) return;

LogPrint("masternode", "CActiveLegacyMasternodeManager::ManageStateRemote -- Start status = %s, type = %s, pinger enabled = %d, keyIDOperator = %s\n",
GetStatus(), GetTypeString(), fPingerEnabled, activeMasternodeInfo.legacyKeyIDOperator.ToString());
Expand Down
8 changes: 8 additions & 0 deletions src/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ class CMainParams : public CChainParams {
consensus.BIP65Height = 619382; // 00000000000076d8fcea02ec0963de4abfd01e771fec0863f960c2c64fe6f357
consensus.BIP66Height = 245817; // 00000000000b1fa2dfa312863570e13fae9ca7b5566cb27e55422620b469aefa
consensus.DIP0001Height = 782208;
consensus.DIP0003Height = 1000000000; // TODO update after DIP3 is deployed
consensus.DIP0003Hash = uint256(); // TODO update after DIP3 is deployed
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 20
consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day
consensus.nPowTargetSpacing = 2.5 * 60; // Dash: 2.5 minutes
Expand Down Expand Up @@ -366,6 +368,8 @@ class CTestNetParams : public CChainParams {
consensus.BIP65Height = 2431; // 0000039cf01242c7f921dcb4806a5994bc003b48c1973ae0c89b67809c2bb2ab
consensus.BIP66Height = 2075; // 0000002acdd29a14583540cb72e1c5cc83783560e38fa7081495d474fe1671f7
consensus.DIP0001Height = 5500;
consensus.DIP0003Height = 7300;
consensus.DIP0003Hash = uint256S("00000055ebc0e974ba3a3fb785c5ad4365a39637d4df168169ee80d313612f8f");
consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 20
consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day
consensus.nPowTargetSpacing = 2.5 * 60; // Dash: 2.5 minutes
Expand Down Expand Up @@ -511,6 +515,8 @@ class CDevNetParams : public CChainParams {
consensus.BIP65Height = 1; // BIP65 activated immediately on devnet
consensus.BIP66Height = 1; // BIP66 activated immediately on devnet
consensus.DIP0001Height = 2; // DIP0001 activated immediately on devnet
consensus.DIP0003Height = 2; // DIP0003 activated immediately on devnet
consensus.DIP0003Hash = uint256();
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 1
consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day
consensus.nPowTargetSpacing = 2.5 * 60; // Dash: 2.5 minutes
Expand Down Expand Up @@ -661,6 +667,8 @@ class CRegTestParams : public CChainParams {
consensus.BIP65Height = 1351; // BIP65 activated on regtest (Used in rpc activation tests)
consensus.BIP66Height = 1251; // BIP66 activated on regtest (Used in rpc activation tests)
consensus.DIP0001Height = 2000;
consensus.DIP0003Height = 500;
consensus.DIP0003Hash = uint256();
consensus.powLimit = uint256S("7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"); // ~uint256(0) >> 1
consensus.nPowTargetTimespan = 24 * 60 * 60; // Dash: 1 day
consensus.nPowTargetSpacing = 2.5 * 60; // Dash: 2.5 minutes
Expand Down
3 changes: 3 additions & 0 deletions src/consensus/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ struct Params {
int BIP66Height;
/** Block height at which DIP0001 becomes active */
int DIP0001Height;
/** Block height at which DIP0003 becomes active */
int DIP0003Height;
uint256 DIP0003Hash;
/**
* Minimum blocks including miner confirmation of the total of nMinerConfirmationWindow blocks in a retargeting period,
* (nPowTargetTimespan / nPowTargetSpacing) which is also used for BIP9 deployments.
Expand Down
26 changes: 13 additions & 13 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#include "chainparams.h"
#include "core_io.h"
#include "script/standard.h"
#include "spork.h"
#include "validation.h"
#include "validationinterface.h"

Expand Down Expand Up @@ -465,8 +464,14 @@ bool CDeterministicMNManager::ProcessBlock(const CBlock& block, const CBlockInde
__func__, nHeight, newList.GetAllMNsCount());
}

if (nHeight == GetSpork15Value()) {
LogPrintf("CDeterministicMNManager::%s -- spork15 is active now. nHeight=%d\n", __func__, nHeight);
const auto& consensusParams = Params().GetConsensus();
if (nHeight == consensusParams.DIP0003Height) {
if (!consensusParams.DIP0003Hash.IsNull() && consensusParams.DIP0003Hash != pindex->GetBlockHash()) {
LogPrintf("CDeterministicMNManager::%s -- DIP3 activation block has wrong hash: hash=%s, expected=%s, nHeight=%d\n", __func__,
pindex->GetBlockHash().ToString(), consensusParams.DIP0003Hash.ToString(), nHeight);
return _state.DoS(100, false, REJECT_INVALID, "bad-dip3-block");
}
LogPrintf("CDeterministicMNManager::%s -- DIP3 is active now. nHeight=%d\n", __func__, nHeight);
}

CleanupCache(nHeight);
Expand All @@ -485,8 +490,9 @@ bool CDeterministicMNManager::UndoBlock(const CBlock& block, const CBlockIndex*
evoDb.Erase(std::make_pair(DB_LIST_SNAPSHOT, blockHash));
mnListsCache.erase(blockHash);

if (nHeight == GetSpork15Value()) {
LogPrintf("CDeterministicMNManager::%s -- spork15 is not active anymore. nHeight=%d\n", __func__, nHeight);
const auto& consensusParams = Params().GetConsensus();
if (nHeight == consensusParams.DIP0003Height) {
LogPrintf("CDeterministicMNManager::%s -- DIP3 is not active anymore. nHeight=%d\n", __func__, nHeight);
}

return true;
Expand Down Expand Up @@ -834,11 +840,6 @@ bool CDeterministicMNManager::HasMNCollateralAtChainTip(const COutPoint& outpoin
return dmn != nullptr;
}

int64_t CDeterministicMNManager::GetSpork15Value()
{
return sporkManager.GetSporkValue(SPORK_15_DETERMINISTIC_MNS_ENABLED);
}

bool CDeterministicMNManager::IsProTxWithCollateral(const CTransactionRef& tx, uint32_t n)
{
if (tx->nVersion != 3 || tx->nType != TRANSACTION_PROVIDER_REGISTER) {
Expand All @@ -861,16 +862,15 @@ bool CDeterministicMNManager::IsProTxWithCollateral(const CTransactionRef& tx, u
return true;
}

bool CDeterministicMNManager::IsDeterministicMNsSporkActive(int nHeight)
bool CDeterministicMNManager::IsDIP3Active(int nHeight)
{
LOCK(cs);

if (nHeight == -1) {
nHeight = tipHeight;
}

int64_t spork15Value = GetSpork15Value();
return nHeight >= spork15Value;
return nHeight >= Params().GetConsensus().DIP0003Height;
}

void CDeterministicMNManager::CleanupCache(int nHeight)
Expand Down
3 changes: 1 addition & 2 deletions src/evo/deterministicmns.h
Original file line number Diff line number Diff line change
Expand Up @@ -486,10 +486,9 @@ class CDeterministicMNManager
// Test if given TX is a ProRegTx which also contains the collateral at index n
bool IsProTxWithCollateral(const CTransactionRef& tx, uint32_t n);

bool IsDeterministicMNsSporkActive(int nHeight = -1);
bool IsDIP3Active(int nHeight = -1);

private:
int64_t GetSpork15Value();
void CleanupCache(int nHeight);
};

Expand Down
4 changes: 2 additions & 2 deletions src/evo/providertx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ bool CheckProRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValid
return state.DoS(10, false, REJECT_DUPLICATE, "bad-protx-dup-key");
}

if (!deterministicMNManager->IsDeterministicMNsSporkActive(pindexPrev->nHeight)) {
if (!deterministicMNManager->IsDIP3Active(pindexPrev->nHeight)) {
if (ptx.keyIDOwner != ptx.keyIDVoting) {
return state.DoS(10, false, REJECT_INVALID, "bad-protx-key-not-same");
}
Expand Down Expand Up @@ -330,7 +330,7 @@ bool CheckProUpRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVal
}
}

if (!deterministicMNManager->IsDeterministicMNsSporkActive(pindexPrev->nHeight)) {
if (!deterministicMNManager->IsDIP3Active(pindexPrev->nHeight)) {
if (dmn->pdmnState->keyIDOwner != ptx.keyIDVoting) {
return state.DoS(10, false, REJECT_INVALID, "bad-protx-key-not-same");
}
Expand Down
2 changes: 1 addition & 1 deletion src/governance-object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -572,7 +572,7 @@ bool CGovernanceObject::IsValidLocally(std::string& strError, bool& fMissingMast
}

// Check that we have a valid MN signature
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
if (deterministicMNManager->IsDIP3Active()) {
if (!CheckSignature(infoMn.blsPubKeyOperator)) {
strError = "Invalid masternode signature for: " + strOutpoint + ", pubkey id = " + infoMn.blsPubKeyOperator.ToString();
return false;
Expand Down
2 changes: 1 addition & 1 deletion src/governance-vote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ bool CGovernanceVote::IsValid(bool useVotingKey) const
if (useVotingKey) {
return CheckSignature(infoMn.keyIDVoting);
} else {
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
if (deterministicMNManager->IsDIP3Active()) {
return CheckSignature(infoMn.blsPubKeyOperator);
} else {
return CheckSignature(infoMn.legacyKeyIDOperator);
Expand Down
8 changes: 4 additions & 4 deletions src/governance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ void CGovernanceManager::DoMaintenance(CConnman& connman)
{
if (fLiteMode || !masternodeSync.IsSynced() || ShutdownRequested()) return;

if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
if (deterministicMNManager->IsDIP3Active()) {
ClearPreDIP3Votes();
RemoveInvalidProposalVotes();
}
Expand Down Expand Up @@ -1302,7 +1302,7 @@ void CGovernanceManager::UpdatedBlockTip(const CBlockIndex* pindex, CConnman& co
nCachedBlockHeight = pindex->nHeight;
LogPrint("gobject", "CGovernanceManager::UpdatedBlockTip -- nCachedBlockHeight: %d\n", nCachedBlockHeight);

if (deterministicMNManager->IsDeterministicMNsSporkActive(pindex->nHeight)) {
if (deterministicMNManager->IsDIP3Active(pindex->nHeight)) {
ClearPreDIP3Votes();
RemoveInvalidProposalVotes();
}
Expand Down Expand Up @@ -1401,10 +1401,10 @@ void CGovernanceManager::RemoveInvalidProposalVotes()
unsigned int CGovernanceManager::GetMinVoteTime()
{
LOCK(cs_main);
if (!deterministicMNManager->IsDeterministicMNsSporkActive()) {
if (!deterministicMNManager->IsDIP3Active()) {
return 0;
}
int64_t dip3SporkHeight = sporkManager.GetSporkValue(SPORK_15_DETERMINISTIC_MNS_ENABLED);
int64_t dip3SporkHeight = Params().GetConsensus().DIP0003Height;
return chainActive[dip3SporkHeight]->nTime;
}

Expand Down
2 changes: 1 addition & 1 deletion src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1947,7 +1947,7 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)

LogPrintf(" keyIDOperator: %s\n", CBitcoinAddress(activeMasternodeInfo.legacyKeyIDOperator).ToString());
} else {
return InitError(_("You must specify a masternodeprivkey in the configuration. Please see documentation for help."));
//return InitError(_("You must specify a masternodeprivkey in the configuration. Please see documentation for help."));
}

std::string strMasterNodeBLSPrivKey = GetArg("-masternodeblsprivkey", "");
Expand Down
10 changes: 5 additions & 5 deletions src/instantx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ void CInstantSend::Vote(CTxLockCandidate& txLockCandidate, CConnman& connman)
LogPrint("instantsend", "CInstantSend::Vote -- Can't calculate rank for masternode %s\n", activeMasternodeInfo.outpoint.ToStringShort());
continue;
}
if (!deterministicMNManager->IsDeterministicMNsSporkActive()) {
if (!deterministicMNManager->IsDIP3Active()) {
// not used until spork15 activation
quorumModifierHash = uint256();
}
Expand Down Expand Up @@ -1043,7 +1043,7 @@ bool CTxLockVote::IsValid(CNode* pnode, CConnman& connman) const
LogPrint("instantsend", "CTxLockVote::IsValid -- invalid masternodeProTxHash %s\n", masternodeProTxHash.ToString());
return false;
}
} else if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
} else if (deterministicMNManager->IsDIP3Active()) {
LogPrint("instantsend", "CTxLockVote::IsValid -- missing masternodeProTxHash while DIP3 is active\n");
return false;
}
Expand All @@ -1069,7 +1069,7 @@ bool CTxLockVote::IsValid(CNode* pnode, CConnman& connman) const
LogPrint("instantsend", "CTxLockVote::IsValid -- invalid quorumModifierHash %s, expected %s\n", quorumModifierHash.ToString(), expectedQuorumModifierHash.ToString());
return false;
}
} else if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
} else if (deterministicMNManager->IsDIP3Active()) {
LogPrint("instantsend", "CTxLockVote::IsValid -- missing quorumModifierHash while DIP3 is active\n");
return false;
}
Expand Down Expand Up @@ -1112,7 +1112,7 @@ bool CTxLockVote::CheckSignature() const
return false;
}

if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
if (deterministicMNManager->IsDIP3Active()) {
uint256 hash = GetSignatureHash();

CBLSSignature sig;
Expand Down Expand Up @@ -1148,7 +1148,7 @@ bool CTxLockVote::Sign()
{
std::string strError;

if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
if (deterministicMNManager->IsDIP3Active()) {
uint256 hash = GetSignatureHash();

CBLSSignature sig = activeMasternodeInfo.blsKeyOperator->Sign(hash);
Expand Down
2 changes: 1 addition & 1 deletion src/instantx.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ class CTxLockVote
READWRITE(txHash);
READWRITE(outpoint);
READWRITE(outpointMasternode);
if (deterministicMNManager->IsDeterministicMNsSporkActive()) {
if (deterministicMNManager->IsDIP3Active()) {
// Starting with spork15 activation, the proTxHash and quorumModifierHash is included. When we bump to >= 70214, we can remove
// the surrounding if. We might also remove outpointMasternode as well later
READWRITE(quorumModifierHash);
Expand Down
Loading

0 comments on commit 0c9fb69

Please sign in to comment.