Skip to content
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
24 changes: 15 additions & 9 deletions qa/rpc-tests/dip3-deterministicmns.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,9 @@ def create_mn(self, node, idx, alias):
mn.is_protx = False
mn.p2p_port = p2p_port(mn.idx)

mn.mnkey = node.masternode('genkey')
blsKey = node.bls('generate')
mn.legacyMnkey = node.masternode('genkey')
mn.blsMnkey = blsKey['secret']
mn.collateral_address = node.getnewaddress()
mn.collateral_txid = node.sendtoaddress(mn.collateral_address, 1000)
rawtx = node.getrawtransaction(mn.collateral_txid, 1)
Expand All @@ -302,10 +304,12 @@ def create_mn_protx(self, node, idx, alias):
mn.is_protx = True
mn.p2p_port = p2p_port(mn.idx)

blsKey = node.bls('generate')
mn.ownerAddr = node.getnewaddress()
mn.operatorAddr = mn.ownerAddr
mn.operatorAddr = blsKey['public']
mn.votingAddr = mn.ownerAddr
mn.mnkey = node.dumpprivkey(mn.operatorAddr)
mn.legacyMnkey = node.masternode('genkey')
mn.blsMnkey = blsKey['secret']
mn.collateral_address = node.getnewaddress()

mn.collateral_txid = node.protx('register', mn.collateral_address, '1000', '127.0.0.1:%d' % mn.p2p_port, '0', mn.ownerAddr, mn.operatorAddr, mn.votingAddr, 0, mn.collateral_address)
Expand All @@ -323,7 +327,7 @@ def create_mn_protx(self, node, idx, alias):
def start_mn(self, mn):
while len(self.nodes) <= mn.idx:
self.nodes.append(None)
extra_args = ['-masternode=1', '-masternodeprivkey=%s' % mn.mnkey]
extra_args = ['-masternode=1', '-masternodeprivkey=%s' % mn.legacyMnkey, '-masternodeblsprivkey=%s' % mn.blsMnkey]
n = start_node(mn.idx, self.options.tmpdir, self.extra_args + extra_args, redirect_stderr=True)
self.nodes[mn.idx] = n
for i in range(0, self.num_nodes):
Expand All @@ -341,7 +345,7 @@ def upgrade_mn_protx(self, mn):
return mn

def test_protx_update_service(self, mn):
self.nodes[0].protx('update_service', mn.collateral_txid, '127.0.0.2:%d' % mn.p2p_port, '0')
self.nodes[0].protx('update_service', mn.collateral_txid, '127.0.0.2:%d' % mn.p2p_port, '0', mn.blsMnkey)
self.nodes[0].generate(1)
self.sync_all()
for node in self.nodes:
Expand All @@ -351,7 +355,7 @@ def test_protx_update_service(self, mn):
assert_equal(mn_list['%s-%d' % (mn.collateral_txid, mn.collateral_vout)]['address'], '127.0.0.2:%d' % mn.p2p_port)

# undo
self.nodes[0].protx('update_service', mn.collateral_txid, '127.0.0.1:%d' % mn.p2p_port, '0')
self.nodes[0].protx('update_service', mn.collateral_txid, '127.0.0.1:%d' % mn.p2p_port, '0', mn.blsMnkey)
self.nodes[0].generate(1)

def force_finish_mnsync(self, node):
Expand All @@ -374,7 +378,7 @@ def force_finish_mnsync_list(self, node):
time.sleep(0.1)

def write_mnconf_line(self, mn, f):
conf_line = "%s %s:%d %s %s %d\n" % (mn.alias, '127.0.0.1', mn.p2p_port, mn.mnkey, mn.collateral_txid, mn.collateral_vout)
conf_line = "%s %s:%d %s %s %d\n" % (mn.alias, '127.0.0.1', mn.p2p_port, mn.legacyMnkey, mn.collateral_txid, mn.collateral_vout)
f.write(conf_line)

def write_mnconf(self, mns):
Expand Down Expand Up @@ -594,12 +598,14 @@ def test_fail_create_protx(self, node):
# Try to create ProTx (should still fail)
address = node.getnewaddress()
key = node.getnewaddress()
assert_raises_jsonrpc(None, "bad-tx-type", node.protx, 'register', address, '1000', '127.0.0.1:10000', '0', key, key, key, 0, address)
blsKey = node.bls('generate')
assert_raises_jsonrpc(None, "bad-tx-type", node.protx, 'register', address, '1000', '127.0.0.1:10000', '0', key, blsKey['public'], key, 0, address)

def test_success_create_protx(self, node):
address = node.getnewaddress()
key = node.getnewaddress()
txid = node.protx('register', address, '1000', '127.0.0.1:10000', '0', key, key, key, 0, address)
blsKey = node.bls('generate')
txid = node.protx('register', address, '1000', '127.0.0.1:10000', '0', key, blsKey['public'], key, 0, address)
rawtx = node.getrawtransaction(txid, 1)
self.mine_double_spend(node, rawtx['vin'], address, use_mnmerkleroot_from_tip=True)
self.sync_all()
Expand Down
16 changes: 5 additions & 11 deletions src/activemasternode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ void CActiveDeterministicMasternodeManager::Init()

CDeterministicMNList mnList = deterministicMNManager->GetListAtChainTip();

CDeterministicMNCPtr dmn = mnList.GetMNByOperatorKey(activeMasternodeInfo.keyIDOperator);
CDeterministicMNCPtr dmn = mnList.GetMNByOperatorKey(*activeMasternodeInfo.blsPubKeyOperator);
if (!dmn) {
// MN not appeared on the chain yet
return;
Expand Down Expand Up @@ -234,7 +234,7 @@ bool CActiveLegacyMasternodeManager::SendMasternodePing(CConnman& connman)
mnp.nSentinelVersion = nSentinelVersion;
mnp.fSentinelIsCurrent =
(abs(GetAdjustedTime() - nSentinelPingTime) < MASTERNODE_SENTINEL_PING_MAX_SECONDS);
if(!mnp.Sign(activeMasternodeInfo.keyOperator, activeMasternodeInfo.keyIDOperator)) {
if(!mnp.Sign(activeMasternodeInfo.legacyKeyOperator, activeMasternodeInfo.legacyKeyIDOperator)) {
LogPrintf("CActiveLegacyMasternodeManager::SendMasternodePing -- ERROR: Couldn't sign Masternode Ping\n");
return false;
}
Expand Down Expand Up @@ -351,11 +351,11 @@ void CActiveLegacyMasternodeManager::ManageStateRemote()
return;

LogPrint("masternode", "CActiveLegacyMasternodeManager::ManageStateRemote -- Start status = %s, type = %s, pinger enabled = %d, keyIDOperator = %s\n",
GetStatus(), GetTypeString(), fPingerEnabled, activeMasternodeInfo.keyIDOperator.ToString());
GetStatus(), GetTypeString(), fPingerEnabled, activeMasternodeInfo.legacyKeyIDOperator.ToString());

mnodeman.CheckMasternode(activeMasternodeInfo.keyIDOperator, true);
mnodeman.CheckMasternode(activeMasternodeInfo.legacyKeyIDOperator, true);
masternode_info_t infoMn;
if(mnodeman.GetMasternodeInfo(activeMasternodeInfo.keyIDOperator, infoMn)) {
if(mnodeman.GetMasternodeInfo(activeMasternodeInfo.legacyKeyIDOperator, infoMn)) {
if(infoMn.nProtocolVersion != PROTOCOL_VERSION) {
nState = ACTIVE_MASTERNODE_NOT_CAPABLE;
strNotCapableReason = "Invalid protocol version";
Expand All @@ -376,12 +376,6 @@ void CActiveLegacyMasternodeManager::ManageStateRemote()
}
auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(infoMn.outpoint.hash);
if (dmn) {
if (dmn->pdmnState->keyIDOperator != infoMn.keyIDOperator) {
nState = ACTIVE_MASTERNODE_NOT_CAPABLE;
strNotCapableReason = strprintf("Masternode collateral is a ProTx and masternode key does not match key from -masternodeprivkey");
LogPrintf("CActiveLegacyMasternodeManager::ManageStateRemote -- %s: %s\n", GetStateString(), strNotCapableReason);
return;
}
if (dmn->pdmnState->addr != infoMn.addr) {
nState = ACTIVE_MASTERNODE_NOT_CAPABLE;
strNotCapableReason = strprintf("Masternode collateral is a ProTx and ProTx address does not match local address");
Expand Down
7 changes: 5 additions & 2 deletions src/activemasternode.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,11 @@ extern CActiveDeterministicMasternodeManager* activeMasternodeManager;

struct CActiveMasternodeInfo {
// Keys for the active Masternode
CKeyID keyIDOperator;
CKey keyOperator;
CKeyID legacyKeyIDOperator;
CKey legacyKeyOperator;

std::unique_ptr<CBLSPublicKey> blsPubKeyOperator;
std::unique_ptr<CBLSSecretKey> blsKeyOperator;

// Initialized while registering Masternode
COutPoint outpoint;
Expand Down
24 changes: 12 additions & 12 deletions src/evo/deterministicmns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ std::string CDeterministicMNState::ToString() const
}

return strprintf("CDeterministicMNState(nRegisteredHeight=%d, nLastPaidHeight=%d, nPoSePenalty=%d, nPoSeRevivedHeight=%d, nPoSeBanHeight=%d, nRevocationReason=%d, "
"keyIDOwner=%s, keyIDOperator=%s, keyIDVoting=%s, addr=%s, nProtocolVersion=%d, payoutAddress=%s, operatorRewardAddress=%s)",
"keyIDOwner=%s, pubKeyOperator=%s, keyIDVoting=%s, addr=%s, nProtocolVersion=%d, payoutAddress=%s, operatorRewardAddress=%s)",
nRegisteredHeight, nLastPaidHeight, nPoSePenalty, nPoSeRevivedHeight, nPoSeBanHeight, nRevocationReason,
keyIDOwner.ToString(), keyIDOperator.ToString(), keyIDVoting.ToString(), addr.ToStringIPPort(false), nProtocolVersion, payoutAddress, operatorRewardAddress);
keyIDOwner.ToString(), pubKeyOperator.ToString(), keyIDVoting.ToString(), addr.ToStringIPPort(false), nProtocolVersion, payoutAddress, operatorRewardAddress);
}

void CDeterministicMNState::ToJson(UniValue& obj) const
Expand All @@ -49,7 +49,7 @@ void CDeterministicMNState::ToJson(UniValue& obj) const
obj.push_back(Pair("PoSeBanHeight", nPoSeBanHeight));
obj.push_back(Pair("revocationReason", nRevocationReason));
obj.push_back(Pair("keyIDOwner", keyIDOwner.ToString()));
obj.push_back(Pair("keyIDOperator", keyIDOperator.ToString()));
obj.push_back(Pair("pubKeyOperator", pubKeyOperator.ToString()));
obj.push_back(Pair("keyIDVoting", keyIDVoting.ToString()));
obj.push_back(Pair("addr", addr.ToStringIPPort(false)));
obj.push_back(Pair("protocolVersion", nProtocolVersion));
Expand Down Expand Up @@ -132,10 +132,10 @@ CDeterministicMNCPtr CDeterministicMNList::GetValidMN(const uint256& proTxHash)
return dmn;
}

CDeterministicMNCPtr CDeterministicMNList::GetMNByOperatorKey(const CKeyID& keyID)
CDeterministicMNCPtr CDeterministicMNList::GetMNByOperatorKey(const CBLSPublicKey& pubKey)
{
for (const auto& p : mnMap) {
if (p.second->pdmnState->keyIDOperator == keyID) {
if (p.second->pdmnState->pubKeyOperator == pubKey) {
return p.second;
}
}
Expand Down Expand Up @@ -256,7 +256,7 @@ void CDeterministicMNList::AddMN(const CDeterministicMNCPtr &dmn)
mnMap = mnMap.set(dmn->proTxHash, dmn);
AddUniqueProperty(dmn, dmn->pdmnState->addr);
AddUniqueProperty(dmn, dmn->pdmnState->keyIDOwner);
AddUniqueProperty(dmn, dmn->pdmnState->keyIDOperator);
AddUniqueProperty(dmn, dmn->pdmnState->pubKeyOperator);
}

void CDeterministicMNList::UpdateMN(const uint256 &proTxHash, const CDeterministicMNStateCPtr &pdmnState)
Expand All @@ -270,7 +270,7 @@ void CDeterministicMNList::UpdateMN(const uint256 &proTxHash, const CDeterminist

UpdateUniqueProperty(dmn, oldState->addr, pdmnState->addr);
UpdateUniqueProperty(dmn, oldState->keyIDOwner, pdmnState->keyIDOwner);
UpdateUniqueProperty(dmn, oldState->keyIDOperator, pdmnState->keyIDOperator);
UpdateUniqueProperty(dmn, oldState->pubKeyOperator, pdmnState->pubKeyOperator);
}

void CDeterministicMNList::RemoveMN(const uint256& proTxHash)
Expand All @@ -279,7 +279,7 @@ void CDeterministicMNList::RemoveMN(const uint256& proTxHash)
assert(dmn != nullptr);
DeleteUniqueProperty(dmn, dmn->pdmnState->addr);
DeleteUniqueProperty(dmn, dmn->pdmnState->keyIDOwner);
DeleteUniqueProperty(dmn, dmn->pdmnState->keyIDOperator);
DeleteUniqueProperty(dmn, dmn->pdmnState->pubKeyOperator);
mnMap = mnMap.erase(proTxHash);
}

Expand Down Expand Up @@ -387,7 +387,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C

if (newList.HasUniqueProperty(proTx.addr))
return _state.DoS(100, false, REJECT_CONFLICT, "bad-protx-dup-addr");
if (newList.HasUniqueProperty(proTx.keyIDOwner) || newList.HasUniqueProperty(proTx.keyIDOperator))
if (newList.HasUniqueProperty(proTx.keyIDOwner) || newList.HasUniqueProperty(proTx.pubKeyOperator))
return _state.DoS(100, false, REJECT_CONFLICT, "bad-protx-dup-key");

auto dmn = std::make_shared<CDeterministicMN>(tx.GetHash(), proTx);
Expand Down Expand Up @@ -426,7 +426,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C

if (newState->nPoSeBanHeight != -1) {
// only revive when all keys are set
if (!newState->keyIDOperator.IsNull() && !newState->keyIDVoting.IsNull() && !newState->keyIDOwner.IsNull()) {
if (newState->pubKeyOperator.IsValid() && !newState->keyIDVoting.IsNull() && !newState->keyIDOwner.IsNull()) {
newState->nPoSeBanHeight = -1;
newState->nPoSeRevivedHeight = nHeight;

Expand All @@ -450,12 +450,12 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C
return _state.DoS(100, false, REJECT_INVALID, "bad-protx-hash");
}
auto newState = std::make_shared<CDeterministicMNState>(*dmn->pdmnState);
if (newState->keyIDOperator != proTx.keyIDOperator) {
if (newState->pubKeyOperator != proTx.pubKeyOperator) {
// reset all operator related fields and put MN into PoSe-banned state in case the operator key changes
newState->ResetOperatorFields();
newState->BanIfNotBanned(nHeight);
}
newState->keyIDOperator = proTx.keyIDOperator;
newState->pubKeyOperator = proTx.pubKeyOperator;
newState->keyIDVoting = proTx.keyIDVoting;
newState->scriptPayout = proTx.scriptPayout;

Expand Down
13 changes: 7 additions & 6 deletions src/evo/deterministicmns.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include "providertx.h"
#include "dbwrapper.h"
#include "sync.h"
#include "bls/bls.h"

#include "immer/map.hpp"
#include "immer/map_transient.hpp"
Expand All @@ -30,7 +31,7 @@ class CDeterministicMNState
uint16_t nRevocationReason{CProUpRevTx::REASON_NOT_SPECIFIED};

CKeyID keyIDOwner;
CKeyID keyIDOperator;
CBLSPublicKey pubKeyOperator;
CKeyID keyIDVoting;
CService addr;
int32_t nProtocolVersion;
Expand All @@ -42,7 +43,7 @@ class CDeterministicMNState
CDeterministicMNState(const CProRegTx& proTx)
{
keyIDOwner = proTx.keyIDOwner;
keyIDOperator = proTx.keyIDOperator;
pubKeyOperator = proTx.pubKeyOperator;
keyIDVoting = proTx.keyIDVoting;
addr = proTx.addr;
nProtocolVersion = proTx.nProtocolVersion;
Expand All @@ -63,7 +64,7 @@ class CDeterministicMNState
READWRITE(nPoSeBanHeight);
READWRITE(nRevocationReason);
READWRITE(keyIDOwner);
READWRITE(keyIDOperator);
READWRITE(pubKeyOperator);
READWRITE(keyIDVoting);
READWRITE(addr);
READWRITE(nProtocolVersion);
Expand All @@ -73,7 +74,7 @@ class CDeterministicMNState

void ResetOperatorFields()
{
keyIDOperator.SetNull();
pubKeyOperator = CBLSPublicKey();
addr = CService();
nProtocolVersion = 0;
scriptOperatorPayout = CScript();
Expand All @@ -95,7 +96,7 @@ class CDeterministicMNState
nPoSeBanHeight == rhs.nPoSeBanHeight &&
nRevocationReason == rhs.nRevocationReason &&
keyIDOwner == rhs.keyIDOwner &&
keyIDOperator == rhs.keyIDOperator &&
pubKeyOperator == rhs.pubKeyOperator &&
keyIDVoting == rhs.keyIDVoting &&
addr == rhs.addr &&
nProtocolVersion == rhs.nProtocolVersion &&
Expand Down Expand Up @@ -257,7 +258,7 @@ class CDeterministicMNList
}
CDeterministicMNCPtr GetMN(const uint256& proTxHash) const;
CDeterministicMNCPtr GetValidMN(const uint256& proTxHash) const;
CDeterministicMNCPtr GetMNByOperatorKey(const CKeyID& keyID);
CDeterministicMNCPtr GetMNByOperatorKey(const CBLSPublicKey& pubKey);
CDeterministicMNCPtr GetMNPayee() const;

/**
Expand Down
Loading