Skip to content

Commit 5fd451f

Browse files
gpdionisioFuzzbawls
authored andcommitted
implemented masternode_broadcast
1 parent 24b4b3e commit 5fd451f

File tree

9 files changed

+319
-71
lines changed

9 files changed

+319
-71
lines changed

src/activemasternode.cpp

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -106,12 +106,17 @@ void CActiveMasternode::ManageStatus()
106106
return;
107107
}
108108

109-
if (!Register(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage)) {
109+
CMasternodeBroadcast mnb;
110+
if (!CreateBroadcast(vin, service, keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage, mnb)) {
110111
notCapableReason = "Error on Register: " + errorMessage;
111-
LogPrintf("Register::ManageStatus() - %s\n", notCapableReason);
112+
LogPrintf("CActiveMasternode::ManageStatus() - %s\n", notCapableReason);
112113
return;
113114
}
114115

116+
//send to all peers
117+
LogPrintf("CActiveMasternode::ManageStatus() - Relay broadcast vin = %s\n", vin.ToString());
118+
mnb.Relay();
119+
115120
LogPrintf("CActiveMasternode::ManageStatus() - Is capable master node!\n");
116121
status = ACTIVE_MASTERNODE_STARTED;
117122

@@ -230,7 +235,7 @@ bool CActiveMasternode::SendMasternodePing(std::string& errorMessage)
230235
}
231236
}
232237

233-
bool CActiveMasternode::Register(std::string strService, std::string strKeyMasternode, std::string strTxHash, std::string strOutputIndex, std::string& errorMessage)
238+
bool CActiveMasternode::CreateBroadcast(std::string strService, std::string strKeyMasternode, std::string strTxHash, std::string strOutputIndex, std::string& errorMessage, CMasternodeBroadcast &mnb, bool fOffline)
234239
{
235240
CTxIn vin;
236241
CPubKey pubKeyCollateralAddress;
@@ -239,68 +244,56 @@ bool CActiveMasternode::Register(std::string strService, std::string strKeyMaste
239244
CKey keyMasternode;
240245

241246
//need correct blocks to send ping
242-
if (!masternodeSync.IsBlockchainSynced()) {
243-
errorMessage = GetStatus();
244-
LogPrintf("CActiveMasternode::Register() - %s\n", errorMessage);
247+
if (!fOffline && !masternodeSync.IsBlockchainSynced()) {
248+
errorMessage = "Sync in progress. Must wait until sync is complete to start Masternode";
249+
LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage);
245250
return false;
246251
}
247252

248253
if (!obfuScationSigner.SetKey(strKeyMasternode, errorMessage, keyMasternode, pubKeyMasternode)) {
249254
errorMessage = strprintf("Can't find keys for masternode %s - %s", strService, errorMessage);
250-
LogPrintf("CActiveMasternode::Register() - %s\n", errorMessage);
255+
LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage);
251256
return false;
252257
}
253258

254259
if (!GetMasterNodeVin(vin, pubKeyCollateralAddress, keyCollateralAddress, strTxHash, strOutputIndex)) {
255260
errorMessage = strprintf("Could not allocate vin %s:%s for masternode %s", strTxHash, strOutputIndex, strService);
256-
LogPrintf("CActiveMasternode::Register() - %s\n", errorMessage);
261+
LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage);
257262
return false;
258263
}
259264

260265
CService service = CService(strService);
261266

262267
// The service needs the correct default port to work properly
263-
if(!CMasternodeBroadcast::CheckDefaultPort(strService, errorMessage, "CActiveMasternode::Register()"))
268+
if(!CMasternodeBroadcast::CheckDefaultPort(strService, errorMessage, "CActiveMasternode::CreateBroadcast()"))
264269
return false;
265270

266271
addrman.Add(CAddress(service), CNetAddr("127.0.0.1"), 2 * 60 * 60);
267272

268-
return Register(vin, CService(strService), keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage);
273+
return CreateBroadcast(vin, CService(strService), keyCollateralAddress, pubKeyCollateralAddress, keyMasternode, pubKeyMasternode, errorMessage, mnb);
269274
}
270275

271-
bool CActiveMasternode::Register(CTxIn vin, CService service, CKey keyCollateralAddress, CPubKey pubKeyCollateralAddress, CKey keyMasternode, CPubKey pubKeyMasternode, std::string& errorMessage)
276+
bool CActiveMasternode::CreateBroadcast(CTxIn vin, CService service, CKey keyCollateralAddress, CPubKey pubKeyCollateralAddress, CKey keyMasternode, CPubKey pubKeyMasternode, std::string& errorMessage, CMasternodeBroadcast &mnb)
272277
{
273-
CMasternodeBroadcast mnb;
278+
// wait for reindex and/or import to finish
279+
if (fImporting || fReindex) return false;
280+
274281
CMasternodePing mnp(vin);
275282
if (!mnp.Sign(keyMasternode, pubKeyMasternode)) {
276283
errorMessage = strprintf("Failed to sign ping, vin: %s", vin.ToString());
277-
LogPrintf("CActiveMasternode::Register() - %s\n", errorMessage);
284+
LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage);
285+
mnb = CMasternodeBroadcast();
278286
return false;
279287
}
280-
mnodeman.mapSeenMasternodePing.insert(make_pair(mnp.GetHash(), mnp));
281288

282-
LogPrintf("CActiveMasternode::Register() - Adding to Masternode list\n service: %s\n vin: %s\n", service.ToString(), vin.ToString());
283289
mnb = CMasternodeBroadcast(service, vin, pubKeyCollateralAddress, pubKeyMasternode, PROTOCOL_VERSION);
284290
mnb.lastPing = mnp;
285291
if (!mnb.Sign(keyCollateralAddress)) {
286292
errorMessage = strprintf("Failed to sign broadcast, vin: %s", vin.ToString());
287-
LogPrintf("CActiveMasternode::Register() - %s\n", errorMessage);
293+
LogPrintf("CActiveMasternode::CreateBroadcast() - %s\n", errorMessage);
294+
mnb = CMasternodeBroadcast();
288295
return false;
289296
}
290-
mnodeman.mapSeenMasternodeBroadcast.insert(make_pair(mnb.GetHash(), mnb));
291-
masternodeSync.AddedMasternodeList(mnb.GetHash());
292-
293-
CMasternode* pmn = mnodeman.Find(vin);
294-
if (pmn == NULL) {
295-
CMasternode mn(mnb);
296-
mnodeman.Add(mn);
297-
} else {
298-
pmn->UpdateFromNewBroadcast(mnb);
299-
}
300-
301-
//send to all peers
302-
LogPrintf("CActiveMasternode::Register() - RelayElectionEntry vin = %s\n", vin.ToString());
303-
mnb.Relay();
304297

305298
/*
306299
* IT'S SAFE TO REMOVE THIS IN FURTHER VERSIONS
@@ -350,6 +343,9 @@ bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secr
350343

351344
bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex)
352345
{
346+
// wait for reindex and/or import to finish
347+
if (fImporting || fReindex) return false;
348+
353349
// Find possible candidates
354350
TRY_LOCK(pwalletMain->cs_wallet, fWallet);
355351
if (!fWallet) return false;
@@ -399,6 +395,9 @@ bool CActiveMasternode::GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secr
399395
// Extract Masternode vin information from output
400396
bool CActiveMasternode::GetVinFromOutput(COutput out, CTxIn& vin, CPubKey& pubkey, CKey& secretKey)
401397
{
398+
// wait for reindex and/or import to finish
399+
if (fImporting || fReindex) return false;
400+
402401
CScript pubScript;
403402

404403
vin = CTxIn(out.tx->GetHash(), out.i);

src/activemasternode.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ class CActiveMasternode
3030
/// Ping Masternode
3131
bool SendMasternodePing(std::string& errorMessage);
3232

33-
/// Register any Masternode
34-
bool Register(CTxIn vin, CService service, CKey key, CPubKey pubKey, CKey keyMasternode, CPubKey pubKeyMasternode, std::string& errorMessage);
33+
/// Create Masternode broadcast, needs to be relayed manually after that
34+
bool CreateBroadcast(CTxIn vin, CService service, CKey key, CPubKey pubKey, CKey keyMasternode, CPubKey pubKeyMasternode, std::string& errorMessage, CMasternodeBroadcast &mnb);
3535

3636
/// Get 10000 PIV input that can be used for the Masternode
3737
bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey, std::string strTxHash, std::string strOutputIndex);
@@ -58,8 +58,8 @@ class CActiveMasternode
5858
void ManageStatus();
5959
std::string GetStatus();
6060

61-
/// Register remote Masternode
62-
bool Register(std::string strService, std::string strKey, std::string strTxHash, std::string strOutputIndex, std::string& errorMessage);
61+
/// Create Masternode broadcast, needs to be relayed manually after that
62+
bool CreateBroadcast(std::string strService, std::string strKey, std::string strTxHash, std::string strOutputIndex, std::string& errorMessage, CMasternodeBroadcast &mnb, bool fOffline = false);
6363

6464
/// Get 10000 PIV input that can be used for the Masternode
6565
bool GetMasterNodeVin(CTxIn& vin, CPubKey& pubkey, CKey& secretKey);

src/masternode.cpp

Lines changed: 48 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,11 @@ void CMasternode::Check(bool forceCheck)
208208
return;
209209
}
210210

211+
if(lastPing.sigTime - sigTime < MASTERNODE_MIN_MNP_SECONDS){
212+
activeState = MASTERNODE_PRE_ENABLED;
213+
return;
214+
}
215+
211216
if (!unitTest) {
212217
CValidationState state;
213218
CMutableTransaction tx = CMutableTransaction();
@@ -480,6 +485,10 @@ bool CMasternodeBroadcast::CheckAndUpdate(int& nDos)
480485
return false;
481486
}
482487

488+
// incorrect ping or its sigTime
489+
if(lastPing == CMasternodePing() || !lastPing.CheckAndUpdate(nDos, false, true))
490+
return false;
491+
483492
std::string strMessage;
484493
if(protocolVersion < 70913) {
485494
std::string vchPubKey(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end());
@@ -535,19 +544,20 @@ bool CMasternodeBroadcast::CheckAndUpdate(int& nDos)
535544
CMasternode* pmn = mnodeman.Find(vin);
536545

537546
// no such masternode, nothing to update
538-
if (pmn == NULL)
539-
return true;
540-
else {
541-
// this broadcast older than we have, it's bad.
542-
if (pmn->sigTime > sigTime) {
543-
LogPrint("masternode","mnb - Bad sigTime %d for Masternode %s (existing broadcast is at %d)\n",
544-
sigTime, vin.prevout.hash.ToString(), pmn->sigTime);
545-
return false;
546-
}
547-
// masternode is not enabled yet/already, nothing to update
548-
if (!pmn->IsEnabled()) return true;
547+
if (pmn == NULL) return true;
548+
549+
// this broadcast is older or equal than the one that we already have - it's bad and should never happen
550+
// unless someone is doing something fishy
551+
// (mapSeenMasternodeBroadcast in CMasternodeMan::ProcessMessage should filter legit duplicates)
552+
if(pmn->sigTime >= sigTime) {
553+
LogPrintf("CMasternodeBroadcast::CheckAndUpdate - Bad sigTime %d for Masternode %20s %105s (existing broadcast is at %d)\n",
554+
sigTime, addr.ToString(), vin.ToString(), pmn->sigTime);
555+
return false;
549556
}
550557

558+
// masternode is not enabled yet/already, nothing to update
559+
if (!pmn->IsEnabled()) return true;
560+
551561
// mn.pubkey = pubkey, IsVinAssociatedWithPubkey is validated once below,
552562
// after that they just need to match
553563
if (pmn->pubKeyCollateralAddress == pubKeyCollateralAddress && !pmn->IsBroadcastedWithin(MASTERNODE_MIN_MNB_SECONDS)) {
@@ -570,6 +580,9 @@ bool CMasternodeBroadcast::CheckInputsAndAdd(int& nDoS)
570580
if (fMasterNode && vin.prevout == activeMasternode.vin.prevout && pubKeyMasternode == activeMasternode.pubKeyMasternode)
571581
return true;
572582

583+
// incorrect ping or its sigTime
584+
if(lastPing == CMasternodePing() || !lastPing.CheckAndUpdate(nDoS, false, true)) return false;
585+
573586
// search existing Masternode list
574587
CMasternode* pmn = mnodeman.Find(vin);
575588

@@ -669,12 +682,12 @@ bool CMasternodeBroadcast::Sign(CKey& keyCollateralAddress)
669682
}
670683

671684
if (!obfuScationSigner.SignMessage(strMessage, errorMessage, sig, keyCollateralAddress)) {
672-
LogPrint("masternode","CMasternodeBroadcast::Sign() - Error: %s\n", errorMessage);
685+
LogPrintf("CMasternodeBroadcast::Sign() - Error: %s\n", errorMessage);
673686
return false;
674687
}
675688

676689
if (!obfuScationSigner.VerifyMessage(pubKeyCollateralAddress, sig, strMessage, errorMessage)) {
677-
LogPrint("masternode","CMasternodeBroadcast::Sign() - Error: %s\n", errorMessage);
690+
LogPrintf("CMasternodeBroadcast::Sign() - Error: %s\n", errorMessage);
678691
return false;
679692
}
680693

@@ -687,7 +700,7 @@ bool CMasternodeBroadcast::VerifySignature()
687700
std::string strMessage;
688701
if(protocolVersion < 70913) {
689702
std::string vchPubKey(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end());
690-
std::string vchPubKey2(pubKeyCollateralAddress.begin(), pubKeyCollateralAddress.end());
703+
std::string vchPubKey2(pubKeyMasternode.begin(), pubKeyMasternode.end());
691704
strMessage = addr.ToString() + boost::lexical_cast<std::string>(sigTime) + vchPubKey + vchPubKey2 + boost::lexical_cast<std::string>(protocolVersion);
692705
} else {
693706
strMessage = addr.ToString() + boost::lexical_cast<std::string>(sigTime) + pubKeyCollateralAddress.GetID().ToString() + pubKeyMasternode.GetID().ToString() + boost::lexical_cast<std::string>(protocolVersion);
@@ -739,7 +752,19 @@ bool CMasternodePing::Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode)
739752
return true;
740753
}
741754

742-
bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled)
755+
bool CMasternodePing::VerifySignature(CPubKey& pubKeyMasternode, int &nDos) {
756+
std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast<std::string>(sigTime);
757+
std::string errorMessage = "";
758+
759+
if(!obfuScationSigner.VerifyMessage(pubKeyMasternode, vchSig, strMessage, errorMessage)){
760+
LogPrintf("CMasternodePing::VerifySignature - Got bad Masternode ping signature %s Error: %s\n", vin.ToString(), errorMessage);
761+
nDos = 33;
762+
return false;
763+
}
764+
return true;
765+
}
766+
767+
bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled, bool fCheckSigTimeOnly)
743768
{
744769
if (sigTime > GetAdjustedTime() + 60 * 60) {
745770
LogPrint("masternode","CMasternodePing::CheckAndUpdate - Signature rejected, too far into the future %s\n", vin.prevout.hash.ToString());
@@ -753,7 +778,13 @@ bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled)
753778
return false;
754779
}
755780

756-
LogPrint("masternode","CMasternodePing::CheckAndUpdate - New Ping - %s - %lli\n", blockHash.ToString(), sigTime);
781+
if(fCheckSigTimeOnly) {
782+
CMasternode* pmn = mnodeman.Find(vin);
783+
if(pmn) return VerifySignature(pmn->pubKeyMasternode, nDos);
784+
return true;
785+
}
786+
787+
LogPrint("masternode", "CMasternodePing::CheckAndUpdate - New Ping - %s - %s - %lli\n", GetHash().ToString(), blockHash.ToString(), sigTime);
757788

758789
// see if we have this Masternode
759790
CMasternode* pmn = mnodeman.Find(vin);
@@ -764,14 +795,8 @@ bool CMasternodePing::CheckAndUpdate(int& nDos, bool fRequireEnabled)
764795
// update only if there is no known ping for this masternode or
765796
// last ping was more then MASTERNODE_MIN_MNP_SECONDS-60 ago comparing to this one
766797
if (!pmn->IsPingedWithin(MASTERNODE_MIN_MNP_SECONDS - 60, sigTime)) {
767-
std::string strMessage = vin.ToString() + blockHash.ToString() + boost::lexical_cast<std::string>(sigTime);
768-
769-
std::string errorMessage = "";
770-
if (!obfuScationSigner.VerifyMessage(pmn->pubKeyMasternode, vchSig, strMessage, errorMessage)) {
771-
LogPrint("masternode","CMasternodePing::CheckAndUpdate - Got bad Masternode address signature %s\n", vin.prevout.hash.ToString());
772-
nDos = 33;
798+
if (!VerifySignature(pmn->pubKeyMasternode, nDos))
773799
return false;
774-
}
775800

776801
BlockMap::iterator mi = mapBlockIndex.find(blockHash);
777802
if (mi != mapBlockIndex.end() && (*mi).second) {

src/masternode.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,9 @@ class CMasternodePing
5959
READWRITE(vchSig);
6060
}
6161

62-
bool CheckAndUpdate(int& nDos, bool fRequireEnabled = true);
62+
bool CheckAndUpdate(int& nDos, bool fRequireEnabled = true, bool fCheckSigTimeOnly = false);
6363
bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
64+
bool VerifySignature(CPubKey& pubKeyMasternode, int &nDos);
6465
void Relay();
6566

6667
uint256 GetHash()

src/masternodeman.cpp

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,20 +1148,18 @@ void CMasternodeMan::Remove(CTxIn vin)
11481148

11491149
void CMasternodeMan::UpdateMasternodeList(CMasternodeBroadcast mnb)
11501150
{
1151-
LOCK(cs);
1152-
mapSeenMasternodePing.insert(std::make_pair(mnb.lastPing.GetHash(), mnb.lastPing));
1153-
mapSeenMasternodeBroadcast.insert(std::make_pair(mnb.GetHash(), mnb));
1151+
mapSeenMasternodePing.insert(make_pair(mnb.lastPing.GetHash(), mnb.lastPing));
1152+
mapSeenMasternodeBroadcast.insert(make_pair(mnb.GetHash(), mnb));
1153+
masternodeSync.AddedMasternodeList(mnb.GetHash());
11541154

1155-
LogPrint("masternode","CMasternodeMan::UpdateMasternodeList -- masternode=%s\n", mnb.vin.prevout.ToStringShort());
1155+
LogPrint("masternode","CMasternodeMan::UpdateMasternodeList() - addr: %s\n vin: %s\n", mnb.addr.ToString(), mnb.vin.ToString());
11561156

11571157
CMasternode* pmn = Find(mnb.vin);
11581158
if (pmn == NULL) {
11591159
CMasternode mn(mnb);
1160-
if (Add(mn)) {
1161-
masternodeSync.AddedMasternodeList(mnb.GetHash());
1162-
}
1163-
} else if (pmn->UpdateFromNewBroadcast(mnb)) {
1164-
masternodeSync.AddedMasternodeList(mnb.GetHash());
1160+
Add(mn);
1161+
} else {
1162+
pmn->UpdateFromNewBroadcast(mnb);
11651163
}
11661164
}
11671165

src/masternodeman.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,8 @@ class CMasternodeMan
153153

154154
void Remove(CTxIn vin);
155155

156+
int GetEstimatedMasternodes(int nBlock);
157+
156158
/// Update masternode list and maps using provided CMasternodeBroadcast
157159
void UpdateMasternodeList(CMasternodeBroadcast mnb);
158160
};

0 commit comments

Comments
 (0)