- mn hash compatibility with 70103 - ignore some requests while syncing - fix locking/initializing in sync - do not ban for old mnw - split budget/governance messages/invs
This commit is contained in:
parent
d2c6b2a74e
commit
b4cb1e2610
@ -43,7 +43,7 @@ CGovernanceVote::CGovernanceVote(CTxIn vinMasternodeIn, uint256 nParentHashIn, i
|
|||||||
|
|
||||||
void CGovernanceVote::Relay()
|
void CGovernanceVote::Relay()
|
||||||
{
|
{
|
||||||
CInv inv(MSG_GOVERNANCE_VOTE, GetHash());
|
CInv inv(MSG_GOVERNANCE_OBJECT_VOTE, GetHash());
|
||||||
RelayInv(inv, MSG_GOVERNANCE_PEER_PROTO_VERSION);
|
RelayInv(inv, MSG_GOVERNANCE_PEER_PROTO_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,12 +103,23 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
|
|||||||
if(fLiteMode) return;
|
if(fLiteMode) return;
|
||||||
if(!masternodeSync.IsBlockchainSynced()) return;
|
if(!masternodeSync.IsBlockchainSynced()) return;
|
||||||
|
|
||||||
|
//
|
||||||
|
// REMOVE AFTER MIGRATION TO 12.1
|
||||||
|
//
|
||||||
|
if(pfrom->nVersion < 70201) return;
|
||||||
|
//
|
||||||
|
// END REMOVE
|
||||||
|
//
|
||||||
|
|
||||||
LOCK(cs_budget);
|
LOCK(cs_budget);
|
||||||
|
|
||||||
// GOVERANCE SYNCING FUNCTIONALITY
|
// GOVERANCE SYNCING FUNCTIONALITY
|
||||||
if (strCommand == NetMsgType::MNGOVERNANCESYNC)
|
if (strCommand == NetMsgType::MNGOVERNANCESYNC)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// ignore such request until we are fully synced
|
||||||
|
if (!masternodeSync.IsSynced()) return;
|
||||||
|
|
||||||
uint256 nProp;
|
uint256 nProp;
|
||||||
vRecv >> nProp;
|
vRecv >> nProp;
|
||||||
|
|
||||||
@ -169,15 +180,14 @@ void CGovernanceManager::ProcessMessage(CNode* pfrom, std::string& strCommand, C
|
|||||||
mapSeenGovernanceObjects.insert(make_pair(govobj.GetHash(), SEEN_OBJECT_IS_VALID));
|
mapSeenGovernanceObjects.insert(make_pair(govobj.GetHash(), SEEN_OBJECT_IS_VALID));
|
||||||
masternodeSync.AddedBudgetItem(govobj.GetHash());
|
masternodeSync.AddedBudgetItem(govobj.GetHash());
|
||||||
|
|
||||||
LogPrintf("Governance object - new! - %s\n", govobj.GetHash().ToString());
|
LogPrintf("MNGOVERNANCEOBJECT -- %s new\n", govobj.GetHash().ToString());
|
||||||
//We might have active votes for this proposal that are valid now
|
//We might have active votes for this proposal that are valid now
|
||||||
CheckOrphanVotes();
|
CheckOrphanVotes();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NEW GOVERNANCE OBJECT VOTE
|
// NEW GOVERNANCE OBJECT VOTE
|
||||||
else if (strCommand == NetMsgType::MNGOVERNANCEVOTE)
|
else if (strCommand == NetMsgType::MNGOVERNANCEOBJECTVOTE)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
CGovernanceVote vote;
|
CGovernanceVote vote;
|
||||||
@ -466,7 +476,7 @@ void CGovernanceManager::Sync(CNode* pfrom, uint256 nProp)
|
|||||||
|
|
||||||
std::map<uint256, CGovernanceVote>::iterator it2 = mapVotesByHash.begin();
|
std::map<uint256, CGovernanceVote>::iterator it2 = mapVotesByHash.begin();
|
||||||
while(it2 != mapVotesByHash.end()) {
|
while(it2 != mapVotesByHash.end()) {
|
||||||
pfrom->PushInventory(CInv(MSG_GOVERNANCE_VOTE, (*it2).first));
|
pfrom->PushInventory(CInv(MSG_GOVERNANCE_OBJECT_VOTE, (*it2).first));
|
||||||
nInvCount++;
|
nInvCount++;
|
||||||
++it2;
|
++it2;
|
||||||
}
|
}
|
||||||
|
52
src/main.cpp
52
src/main.cpp
@ -4686,12 +4686,6 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
|||||||
case MSG_MASTERNODE_WINNER:
|
case MSG_MASTERNODE_WINNER:
|
||||||
return mnpayments.mapMasternodePayeeVotes.count(inv.hash);
|
return mnpayments.mapMasternodePayeeVotes.count(inv.hash);
|
||||||
|
|
||||||
case MSG_GOVERNANCE_VOTE:
|
|
||||||
return governance.mapVotesByHash.count(inv.hash);
|
|
||||||
|
|
||||||
case MSG_GOVERNANCE_OBJECT:
|
|
||||||
return governance.mapObjects.count(inv.hash);
|
|
||||||
|
|
||||||
case MSG_MASTERNODE_ANNOUNCE:
|
case MSG_MASTERNODE_ANNOUNCE:
|
||||||
return mnodeman.mapSeenMasternodeBroadcast.count(inv.hash);
|
return mnodeman.mapSeenMasternodeBroadcast.count(inv.hash);
|
||||||
|
|
||||||
@ -4700,7 +4694,14 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
|
|||||||
|
|
||||||
case MSG_DSTX:
|
case MSG_DSTX:
|
||||||
return mapDarksendBroadcastTxes.count(inv.hash);
|
return mapDarksendBroadcastTxes.count(inv.hash);
|
||||||
|
|
||||||
|
case MSG_GOVERNANCE_OBJECT:
|
||||||
|
return governance.mapObjects.count(inv.hash);
|
||||||
|
|
||||||
|
case MSG_GOVERNANCE_OBJECT_VOTE:
|
||||||
|
return governance.mapVotesByHash.count(inv.hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't know what it is, just say we already got one
|
// Don't know what it is, just say we already got one
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -4861,26 +4862,6 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
|||||||
pushed = true;
|
pushed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pushed && inv.type == MSG_GOVERNANCE_VOTE) {
|
|
||||||
if(governance.mapVotesByHash.count(inv.hash)) {
|
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
|
||||||
ss.reserve(1000);
|
|
||||||
ss << governance.mapVotesByHash[inv.hash];
|
|
||||||
pfrom->PushMessage(NetMsgType::MNGOVERNANCEVOTE, ss);
|
|
||||||
pushed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pushed && inv.type == MSG_GOVERNANCE_OBJECT) {
|
|
||||||
if(governance.mapObjects.count(inv.hash)) {
|
|
||||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
|
||||||
ss.reserve(1000);
|
|
||||||
ss << governance.mapObjects[inv.hash];
|
|
||||||
pfrom->PushMessage(NetMsgType::MNGOVERNANCEOBJECT, ss);
|
|
||||||
pushed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pushed && inv.type == MSG_MASTERNODE_ANNOUNCE) {
|
if (!pushed && inv.type == MSG_MASTERNODE_ANNOUNCE) {
|
||||||
if(mnodeman.mapSeenMasternodeBroadcast.count(inv.hash)){
|
if(mnodeman.mapSeenMasternodeBroadcast.count(inv.hash)){
|
||||||
@ -4917,6 +4898,25 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pushed && inv.type == MSG_GOVERNANCE_OBJECT) {
|
||||||
|
if(governance.mapObjects.count(inv.hash)) {
|
||||||
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
ss.reserve(1000);
|
||||||
|
ss << governance.mapObjects[inv.hash];
|
||||||
|
pfrom->PushMessage(NetMsgType::MNGOVERNANCEOBJECT, ss);
|
||||||
|
pushed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pushed && inv.type == MSG_GOVERNANCE_OBJECT_VOTE) {
|
||||||
|
if(governance.mapVotesByHash.count(inv.hash)) {
|
||||||
|
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||||
|
ss.reserve(1000);
|
||||||
|
ss << governance.mapVotesByHash[inv.hash];
|
||||||
|
pfrom->PushMessage(NetMsgType::MNGOVERNANCEOBJECTVOTE, ss);
|
||||||
|
pushed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!pushed)
|
if (!pushed)
|
||||||
vNotFound.push_back(inv);
|
vNotFound.push_back(inv);
|
||||||
|
@ -194,7 +194,9 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand,
|
|||||||
|
|
||||||
|
|
||||||
if (strCommand == NetMsgType::MNWINNERSSYNC) { //Masternode Payments Request Sync
|
if (strCommand == NetMsgType::MNWINNERSSYNC) { //Masternode Payments Request Sync
|
||||||
if(fLiteMode) return; //disable all Darksend/Masternode related functionality
|
|
||||||
|
// ignore such request until we are fully synced
|
||||||
|
if (!masternodeSync.IsSynced()) return;
|
||||||
|
|
||||||
int nCountNeeded;
|
int nCountNeeded;
|
||||||
vRecv >> nCountNeeded;
|
vRecv >> nCountNeeded;
|
||||||
@ -220,32 +222,38 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand,
|
|||||||
|
|
||||||
if(!pCurrentBlockIndex) return;
|
if(!pCurrentBlockIndex) return;
|
||||||
|
|
||||||
if(mapMasternodePayeeVotes.count(winner.GetHash())){
|
// can't really verify it until masternode list is synced, reject it for now
|
||||||
LogPrint("mnpayments", "mnw - Already seen - %s bestHeight %d\n", winner.GetHash().ToString(), pCurrentBlockIndex->nHeight);
|
if (masternodeSync.RequestedMasternodeAssets < MASTERNODE_SYNC_MNW) return;
|
||||||
|
|
||||||
|
if(mapMasternodePayeeVotes.count(winner.GetHash())) {
|
||||||
|
LogPrint("mnpayments", "MNWINNER -- Already seen: hash=%s, nHeight=%d\n", winner.GetHash().ToString(), pCurrentBlockIndex->nHeight);
|
||||||
masternodeSync.AddedMasternodeWinner(winner.GetHash());
|
masternodeSync.AddedMasternodeWinner(winner.GetHash());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int nFirstBlock = pCurrentBlockIndex->nHeight - (mnodeman.CountEnabled()*1.25);
|
int nFirstBlock = pCurrentBlockIndex->nHeight - mnodeman.CountEnabled()*1.25;
|
||||||
if(winner.nBlockHeight < nFirstBlock || winner.nBlockHeight > pCurrentBlockIndex->nHeight+20){
|
if(winner.nBlockHeight < nFirstBlock || winner.nBlockHeight > pCurrentBlockIndex->nHeight+20) {
|
||||||
LogPrint("mnpayments", "mnw - winner out of range - FirstBlock %d Height %d bestHeight %d\n", nFirstBlock, winner.nBlockHeight, pCurrentBlockIndex->nHeight);
|
LogPrint("mnpayments", "MNWINNER -- winner out of range: nFirstBlock=%d, nBlockHeight=%d, nHeight=%d\n", nFirstBlock, winner.nBlockHeight, pCurrentBlockIndex->nHeight);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string strError = "";
|
std::string strError = "";
|
||||||
if(!winner.IsValid(pfrom, strError)){
|
if(!winner.IsValid(pfrom, pCurrentBlockIndex->nHeight, strError)) {
|
||||||
if(strError != "") LogPrint("mnpayments", "mnw - invalid message - %s\n", strError);
|
LogPrint("mnpayments", "MNWINNER -- invalid message, error: %s\n", strError);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!CanVote(winner.vinMasternode.prevout, winner.nBlockHeight)){
|
if(!CanVote(winner.vinMasternode.prevout, winner.nBlockHeight)){
|
||||||
LogPrintf("mnw - masternode already voted - %s\n", winner.vinMasternode.prevout.ToStringShort());
|
LogPrintf("MNWINNER -- masternode already voted: prevout=%s\n", winner.vinMasternode.prevout.ToStringShort());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!winner.SignatureValid()){
|
if(!winner.SignatureValid()) {
|
||||||
LogPrintf("mnw - invalid signature\n");
|
// do not ban for old mnw, MN simply might be not active anymore
|
||||||
if(masternodeSync.IsSynced()) Misbehaving(pfrom->GetId(), 20);
|
if(masternodeSync.IsSynced() && winner.nBlockHeight > pCurrentBlockIndex->nHeight) {
|
||||||
|
LogPrintf("MNWINNER -- invalid signature\n");
|
||||||
|
Misbehaving(pfrom->GetId(), 20);
|
||||||
|
}
|
||||||
// it could just be a non-synced masternode
|
// it could just be a non-synced masternode
|
||||||
mnodeman.AskForMN(pfrom, winner.vinMasternode);
|
mnodeman.AskForMN(pfrom, winner.vinMasternode);
|
||||||
return;
|
return;
|
||||||
@ -255,7 +263,7 @@ void CMasternodePayments::ProcessMessage(CNode* pfrom, std::string& strCommand,
|
|||||||
ExtractDestination(winner.payee, address1);
|
ExtractDestination(winner.payee, address1);
|
||||||
CBitcoinAddress address2(address1);
|
CBitcoinAddress address2(address1);
|
||||||
|
|
||||||
LogPrint("mnpayments", "mnw - winning vote - Addr %s Height %d bestHeight %d - %s\n", address2.ToString(), winner.nBlockHeight, pCurrentBlockIndex->nHeight, winner.vinMasternode.prevout.ToStringShort());
|
LogPrint("mnpayments", "MNWINNER -- winning vote: address=%s, nBlockHeight=%d, nHeight=%d, prevout=%s\n", address2.ToString(), winner.nBlockHeight, pCurrentBlockIndex->nHeight, winner.vinMasternode.prevout.ToStringShort());
|
||||||
|
|
||||||
if(AddWinningMasternode(winner)){
|
if(AddWinningMasternode(winner)){
|
||||||
winner.Relay();
|
winner.Relay();
|
||||||
@ -464,37 +472,34 @@ void CMasternodePayments::CheckAndRemove()
|
|||||||
LogPrintf("CMasternodePayments::CleanPaymentList() - %s mapSeenSyncMNW %lld\n", ToString(), masternodeSync.mapSeenSyncMNW.size());
|
LogPrintf("CMasternodePayments::CleanPaymentList() - %s mapSeenSyncMNW %lld\n", ToString(), masternodeSync.mapSeenSyncMNW.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CMasternodePaymentWinner::IsValid(CNode* pnode, std::string& strError)
|
bool CMasternodePaymentWinner::IsValid(CNode* pnode, int nValidationHeight, std::string& strError)
|
||||||
{
|
{
|
||||||
CMasternode* pmn = mnodeman.Find(vinMasternode);
|
CMasternode* pmn = mnodeman.Find(vinMasternode);
|
||||||
|
|
||||||
if(!pmn)
|
if(!pmn) {
|
||||||
{
|
strError = strprintf("Unknown Masternode: prevout=%s", vinMasternode.prevout.ToStringShort());
|
||||||
strError = strprintf("Unknown Masternode %s", vinMasternode.prevout.ToStringShort());
|
// Only ask if we are already synced and still have no idea about that Masternode
|
||||||
LogPrint("mnpayments", "CMasternodePaymentWinner::IsValid - %s\n", strError);
|
if (masternodeSync.IsSynced()) mnodeman.AskForMN(pnode, vinMasternode);
|
||||||
mnodeman.AskForMN(pnode, vinMasternode);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pmn->protocolVersion < MIN_MNW_PEER_PROTO_VERSION)
|
if(pmn->protocolVersion < MIN_MNW_PEER_PROTO_VERSION) {
|
||||||
{
|
strError = strprintf("Masternode protocol is too old: protocolVersion=%d, MIN_MNW_PEER_PROTO_VERSION=%d", pmn->protocolVersion, MIN_MNW_PEER_PROTO_VERSION);
|
||||||
strError = strprintf("Masternode protocol too old %d - req %d", pmn->protocolVersion, MIN_MNW_PEER_PROTO_VERSION);
|
|
||||||
LogPrint("mnpayments", "CMasternodePaymentWinner::IsValid - %s\n", strError);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = mnodeman.GetMasternodeRank(vinMasternode, nBlockHeight-100, MIN_MNW_PEER_PROTO_VERSION);
|
int nRank = mnodeman.GetMasternodeRank(vinMasternode, nBlockHeight - 100, MIN_MNW_PEER_PROTO_VERSION);
|
||||||
|
|
||||||
if(n > MNPAYMENTS_SIGNATURES_TOTAL)
|
if(nRank > MNPAYMENTS_SIGNATURES_TOTAL) {
|
||||||
{
|
// It's common to have masternodes mistakenly think they are in the top 10
|
||||||
//It's common to have masternodes mistakenly think they are in the top 10
|
// We don't want to print all of these messages in normal mode, debug mode should print though
|
||||||
// We don't want to print all of these messages, or punish them unless they're way off
|
strError = strprintf("Masternode is not in the top %d (%d)\n", MNPAYMENTS_SIGNATURES_TOTAL, nRank);
|
||||||
if(n > MNPAYMENTS_SIGNATURES_TOTAL*2)
|
// Only ban for new mnw which is out of bounds, for old mnw MN list itself might be way too much off
|
||||||
{
|
if(nRank > MNPAYMENTS_SIGNATURES_TOTAL*2 && nBlockHeight > nValidationHeight) {
|
||||||
strError = strprintf("Masternode not in the top %d (%d)", MNPAYMENTS_SIGNATURES_TOTAL, n);
|
LogPrintf("CMasternodePaymentWinner::IsValid -- Error: Masternode is not in the top %d (%d)\n", MNPAYMENTS_SIGNATURES_TOTAL*2, nRank);
|
||||||
LogPrint("mnpayments", "CMasternodePaymentWinner::IsValid - %s\n", strError);
|
Misbehaving(pnode->GetId(), 20);
|
||||||
if(masternodeSync.IsSynced()) Misbehaving(pnode->GetId(), 20);
|
|
||||||
}
|
}
|
||||||
|
// Still invalid however
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,7 +161,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
|
bool Sign(CKey& keyMasternode, CPubKey& pubKeyMasternode);
|
||||||
bool IsValid(CNode* pnode, std::string& strError);
|
bool IsValid(CNode* pnode, int nValidationHeight, std::string& strError);
|
||||||
bool SignatureValid();
|
bool SignatureValid();
|
||||||
void Relay();
|
void Relay();
|
||||||
|
|
||||||
|
@ -149,6 +149,8 @@ void CMasternodeSync::GetNextAsset()
|
|||||||
LogPrintf("CMasternodeSync::GetNextAsset - Sync has finished\n");
|
LogPrintf("CMasternodeSync::GetNextAsset - Sync has finished\n");
|
||||||
RequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
|
RequestedMasternodeAssets = MASTERNODE_SYNC_FINISHED;
|
||||||
uiInterface.NotifyAdditionalDataSyncProgressChanged(1);
|
uiInterface.NotifyAdditionalDataSyncProgressChanged(1);
|
||||||
|
//try to activate our masternode if possible
|
||||||
|
activeMasternode.ManageStatus();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
RequestedMasternodeAttempt = 0;
|
RequestedMasternodeAttempt = 0;
|
||||||
@ -253,20 +255,18 @@ void CMasternodeSync::Process()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// INITIAL SYNC SETUP / LOG REPORTING
|
// INITIAL SYNC SETUP / LOG REPORTING
|
||||||
{
|
double nSyncProgress = double(RequestedMasternodeAttempt + (RequestedMasternodeAssets - 1) * 8) / (8*4);
|
||||||
double nSyncProgress = double(RequestedMasternodeAttempt + (RequestedMasternodeAssets - 1) * 8) / (8*4);
|
LogPrintf("CMasternodeSync::Process() - tick %d RequestedMasternodeAttempt %d RequestedMasternodeAssets %d nSyncProgress %f\n", tick, RequestedMasternodeAttempt, RequestedMasternodeAssets, nSyncProgress);
|
||||||
LogPrintf("CMasternodeSync::Process() - tick %d RequestedMasternodeAttempt %d RequestedMasternodeAssets %d nSyncProgress %f\n", tick, RequestedMasternodeAttempt, RequestedMasternodeAssets, nSyncProgress);
|
uiInterface.NotifyAdditionalDataSyncProgressChanged(nSyncProgress);
|
||||||
uiInterface.NotifyAdditionalDataSyncProgressChanged(nSyncProgress);
|
|
||||||
|
|
||||||
if(RequestedMasternodeAssets == MASTERNODE_SYNC_INITIAL) GetNextAsset();
|
// sporks synced but blockchain is not, wait until we're almost at a recent block to continue
|
||||||
|
if(Params().NetworkIDString() != CBaseChainParams::REGTEST &&
|
||||||
|
!IsBlockchainSynced() && RequestedMasternodeAssets > MASTERNODE_SYNC_SPORKS) return;
|
||||||
|
|
||||||
// sporks synced but blockchain is not, wait until we're almost at a recent block to continue
|
TRY_LOCK(cs_vNodes, lockRecv);
|
||||||
if(Params().NetworkIDString() != CBaseChainParams::REGTEST &&
|
if(!lockRecv) return;
|
||||||
!IsBlockchainSynced() && RequestedMasternodeAssets > MASTERNODE_SYNC_SPORKS) return;
|
|
||||||
|
|
||||||
TRY_LOCK(cs_vNodes, lockRecv);
|
if(RequestedMasternodeAssets == MASTERNODE_SYNC_INITIAL) GetNextAsset();
|
||||||
if(!lockRecv) return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
{
|
{
|
||||||
@ -293,91 +293,103 @@ void CMasternodeSync::Process()
|
|||||||
{
|
{
|
||||||
// SPORK : ALWAYS ASK FOR SPORKS AS WE SYNC (we skip this mode now)
|
// SPORK : ALWAYS ASK FOR SPORKS AS WE SYNC (we skip this mode now)
|
||||||
|
|
||||||
if(!pnode->HasFulfilledRequest("spork-sync"))
|
if(!pnode->HasFulfilledRequest("spork-sync")) {
|
||||||
{
|
// only request once from each peer
|
||||||
pnode->FulfilledRequest("spork-sync");
|
pnode->FulfilledRequest("spork-sync");
|
||||||
|
|
||||||
// get current network sporks
|
// get current network sporks
|
||||||
pnode->PushMessage(NetMsgType::GETSPORKS);
|
pnode->PushMessage(NetMsgType::GETSPORKS);
|
||||||
|
|
||||||
// we always ask for sporks, so just skip this
|
// we always ask for sporks, so just skip this
|
||||||
if(RequestedMasternodeAssets == MASTERNODE_SYNC_SPORKS){
|
if(RequestedMasternodeAssets == MASTERNODE_SYNC_SPORKS) GetNextAsset();
|
||||||
GetNextAsset();
|
|
||||||
return;
|
continue; // always get sporks first, switch to the next node without waiting for the next tick
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MNLIST : SYNC MASTERNODE LIST FROM OTHER CONNECTED CLIENTS
|
// MNLIST : SYNC MASTERNODE LIST FROM OTHER CONNECTED CLIENTS
|
||||||
|
|
||||||
if(RequestedMasternodeAssets == MASTERNODE_SYNC_LIST)
|
if(RequestedMasternodeAssets == MASTERNODE_SYNC_LIST) {
|
||||||
{
|
// check for timeout first
|
||||||
if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
|
if(lastMasternodeList < GetTime() - MASTERNODE_SYNC_TIMEOUT) {
|
||||||
|
LogPrintf("CMasternodeSync::Process -- tick %d asset %d -- timeout\n", tick, RequestedMasternodeAssets);
|
||||||
// shall we move onto the next asset?
|
if(RequestedMasternodeAttempt == 0)
|
||||||
if(nMnCount > mnodeman.GetEstimatedMasternodes(pCurrentBlockIndex->nHeight)*0.9)
|
LogPrintf("CMasternodeSync::Process -- WARNING: failed to sync %s\n", GetAssetName());
|
||||||
{
|
|
||||||
GetNextAsset();
|
GetNextAsset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lastMasternodeList < GetTime() - MASTERNODE_SYNC_TIMEOUT){ //hasn't received a new item in the last five seconds, so we'll move to the
|
// check for data
|
||||||
|
// if we have enough masternodes in or list, switch to the next asset
|
||||||
|
/* Note: Is this activing up? It's probably related to int CMasternodeMan::GetEstimatedMasternodes(int nBlock)
|
||||||
|
Surely doesn't work right for testnet currently */
|
||||||
|
// try to fetch data from at least one peer though
|
||||||
|
if(RequestedMasternodeAssets > 0 && nMnCount > mnodeman.GetEstimatedMasternodes(pCurrentBlockIndex->nHeight)*0.9) {
|
||||||
|
LogPrintf("CMasternodeSync::Process -- tick %d asset %d -- found enough data\n", tick, RequestedMasternodeAssets);
|
||||||
GetNextAsset();
|
GetNextAsset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// requesting is the last thing we do (incase we needed to move to the next asset and we've requested from each peer already)
|
// only request once from each peer
|
||||||
|
|
||||||
if(pnode->HasFulfilledRequest("masternode-sync")) continue;
|
if(pnode->HasFulfilledRequest("masternode-sync")) continue;
|
||||||
pnode->FulfilledRequest("masternode-sync");
|
pnode->FulfilledRequest("masternode-sync");
|
||||||
|
|
||||||
//see if we've synced the masternode list
|
if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
|
||||||
/* note: Is this activing up? It's probably related to int CMasternodeMan::GetEstimatedMasternodes(int nBlock) */
|
|
||||||
|
|
||||||
mnodeman.DsegUpdate(pnode);
|
|
||||||
RequestedMasternodeAttempt++;
|
RequestedMasternodeAttempt++;
|
||||||
|
|
||||||
|
mnodeman.DsegUpdate(pnode);
|
||||||
|
|
||||||
return; //this will cause each peer to get one request each six seconds for the various assets we need
|
return; //this will cause each peer to get one request each six seconds for the various assets we need
|
||||||
}
|
}
|
||||||
|
|
||||||
// MNW : SYNC MASTERNODE WINNERS FROM OTHER CONNECTED CLIENTS
|
// MNW : SYNC MASTERNODE WINNERS FROM OTHER CONNECTED CLIENTS
|
||||||
|
|
||||||
if(RequestedMasternodeAssets == MASTERNODE_SYNC_MNW)
|
if(RequestedMasternodeAssets == MASTERNODE_SYNC_MNW) {
|
||||||
{
|
// check for timeout first
|
||||||
if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
|
// This might take a lot longer than MASTERNODE_SYNC_TIMEOUT minutes due to new blocks,
|
||||||
|
// but that should be OK and it should timeout eventually.
|
||||||
// Shall we move onto the next asset?
|
if(lastMasternodeWinner < GetTime() - MASTERNODE_SYNC_TIMEOUT) {
|
||||||
// --
|
LogPrintf("CMasternodeSync::Process -- tick %d asset %d -- timeout\n", tick, RequestedMasternodeAssets);
|
||||||
// This might take a lot longer than 2 minutes due to new blocks, but that's OK. It will eventually time out if needed
|
if(RequestedMasternodeAttempt == 0)
|
||||||
if(lastMasternodeWinner < GetTime() - MASTERNODE_SYNC_TIMEOUT){ //hasn't received a new item in the last five seconds, so we'll move to the
|
LogPrintf("CMasternodeSync::Process -- WARNING: failed to sync %s\n", GetAssetName());
|
||||||
GetNextAsset();
|
GetNextAsset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for data
|
||||||
// if mnpayments already has enough blocks and votes, move to the next asset
|
// if mnpayments already has enough blocks and votes, move to the next asset
|
||||||
if(mnpayments.IsEnoughData(nMnCount)) {
|
// try to fetch data from at least one peer though
|
||||||
|
if(RequestedMasternodeAssets > 0 && mnpayments.IsEnoughData(nMnCount)) {
|
||||||
|
LogPrintf("CMasternodeSync::Process -- tick %d asset %d -- found enough data\n", tick, RequestedMasternodeAssets);
|
||||||
GetNextAsset();
|
GetNextAsset();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// requesting is the last thing we do (incase we needed to move to the next asset and we've requested from each peer already)
|
// only request once from each peer
|
||||||
|
|
||||||
if(pnode->HasFulfilledRequest("masternode-winner-sync")) continue;
|
if(pnode->HasFulfilledRequest("masternode-winner-sync")) continue;
|
||||||
pnode->FulfilledRequest("masternode-winner-sync");
|
pnode->FulfilledRequest("masternode-winner-sync");
|
||||||
|
|
||||||
pnode->PushMessage(NetMsgType::MNWINNERSSYNC, nMnCount); //sync payees
|
if (pnode->nVersion < mnpayments.GetMinMasternodePaymentsProto()) continue;
|
||||||
RequestedMasternodeAttempt++;
|
RequestedMasternodeAttempt++;
|
||||||
|
|
||||||
|
pnode->PushMessage(NetMsgType::MNWINNERSSYNC, nMnCount); //sync payees
|
||||||
|
|
||||||
|
|
||||||
return; //this will cause each peer to get one request each six seconds for the various assets we need
|
return; //this will cause each peer to get one request each six seconds for the various assets we need
|
||||||
}
|
}
|
||||||
|
|
||||||
// GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS
|
// GOVOBJ : SYNC GOVERNANCE ITEMS FROM OUR PEERS
|
||||||
|
|
||||||
if(RequestedMasternodeAssets == MASTERNODE_SYNC_GOVERNANCE){
|
if(RequestedMasternodeAssets == MASTERNODE_SYNC_GOVERNANCE) {
|
||||||
if (pnode->nVersion < MSG_GOVERNANCE_PEER_PROTO_VERSION) continue;
|
// check for timeout first
|
||||||
|
if(lastBudgetItem < GetTime() - MASTERNODE_SYNC_TIMEOUT){
|
||||||
|
LogPrintf("CMasternodeSync::Process -- tick %d asset %d -- timeout\n", tick, RequestedMasternodeAssets);
|
||||||
|
if(RequestedMasternodeAttempt == 0)
|
||||||
|
LogPrintf("CMasternodeSync::Process -- WARNING: failed to sync %s\n", GetAssetName());
|
||||||
|
GetNextAsset();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for data
|
||||||
// shall we move onto the next asset
|
|
||||||
// if(countBudgetItemProp > 0 && countBudgetItemFin)
|
// if(countBudgetItemProp > 0 && countBudgetItemFin)
|
||||||
// {
|
// {
|
||||||
// if(governance.CountProposalInventoryItems() >= (sumBudgetItemProp / countBudgetItemProp)*0.9)
|
// if(governance.CountProposalInventoryItems() >= (sumBudgetItemProp / countBudgetItemProp)*0.9)
|
||||||
@ -390,24 +402,17 @@ void CMasternodeSync::Process()
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
//we'll start rejecting votes if we accidentally get set as synced too soon, this allows plenty of time
|
if (pnode->nVersion < MSG_GOVERNANCE_PEER_PROTO_VERSION) continue;
|
||||||
if(lastBudgetItem < GetTime() - MASTERNODE_SYNC_TIMEOUT){
|
|
||||||
GetNextAsset();
|
|
||||||
|
|
||||||
//try to activate our masternode if possible
|
|
||||||
activeMasternode.ManageStatus();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// requesting is the last thing we do, incase we needed to move to the next asset and we've requested from each peer already
|
|
||||||
|
|
||||||
|
// only request once from each peer
|
||||||
if(pnode->HasFulfilledRequest("governance-sync")) continue;
|
if(pnode->HasFulfilledRequest("governance-sync")) continue;
|
||||||
pnode->FulfilledRequest("governance-sync");
|
pnode->FulfilledRequest("governance-sync");
|
||||||
|
|
||||||
uint256 n = uint256();
|
if (pnode->nVersion < MSG_GOVERNANCE_PEER_PROTO_VERSION) continue;
|
||||||
pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, n); //sync masternode votes
|
|
||||||
RequestedMasternodeAttempt++;
|
RequestedMasternodeAttempt++;
|
||||||
|
|
||||||
|
pnode->PushMessage(NetMsgType::MNGOVERNANCESYNC, uint256()); //sync masternode votes
|
||||||
|
|
||||||
return; //this will cause each peer to get one request each six seconds for the various assets we need
|
return; //this will cause each peer to get one request each six seconds for the various assets we need
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -317,9 +317,20 @@ public:
|
|||||||
|
|
||||||
uint256 GetHash(){
|
uint256 GetHash(){
|
||||||
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION);
|
||||||
ss << vin;
|
//
|
||||||
ss << pubkey;
|
// REMOVE AFTER MIGRATION TO 12.1
|
||||||
ss << sigTime;
|
//
|
||||||
|
if(protocolVersion < 70201) {
|
||||||
|
ss << sigTime;
|
||||||
|
ss << pubkey;
|
||||||
|
} else {
|
||||||
|
//
|
||||||
|
// END REMOVE
|
||||||
|
//
|
||||||
|
ss << vin;
|
||||||
|
ss << pubkey;
|
||||||
|
ss << sigTime;
|
||||||
|
}
|
||||||
return ss.GetHash();
|
return ss.GetHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,6 +586,9 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
|
|||||||
|
|
||||||
} else if (strCommand == NetMsgType::DSEG) { //Get Masternode list or specific entry
|
} else if (strCommand == NetMsgType::DSEG) { //Get Masternode list or specific entry
|
||||||
|
|
||||||
|
// ignore such request until we are fully synced
|
||||||
|
if (!masternodeSync.IsSynced()) return;
|
||||||
|
|
||||||
CTxIn vin;
|
CTxIn vin;
|
||||||
vRecv >> vin;
|
vRecv >> vin;
|
||||||
|
|
||||||
|
@ -43,11 +43,11 @@ const char *GETSPORKS="getsporks";
|
|||||||
const char *MNWINNER="mnw";
|
const char *MNWINNER="mnw";
|
||||||
const char *MNWINNERSSYNC="mnget";
|
const char *MNWINNERSSYNC="mnget";
|
||||||
const char *MNSCANERROR="mn scan error"; // not implemented
|
const char *MNSCANERROR="mn scan error"; // not implemented
|
||||||
const char *MNGOVERNANCESYNC="mnvs";
|
const char *MNBUDGETSYNC="mnvs"; // depreciated since 12.1
|
||||||
const char *MNGOVERNANCEVOTE="mvote";
|
const char *MNBUDGETVOTE="mvote"; // depreciated since 12.1
|
||||||
const char *MNGOVERNANCEOBJECT="mprop";
|
const char *MNBUDGETPROPOSAL="mprop"; // depreciated since 12.1
|
||||||
const char *MNGOVERNANCEFINAL="fbs";
|
const char *MNBUDGETFINAL="fbs"; // depreciated since 12.1
|
||||||
const char *MNGOVERNANCEFINALVOTE="fbvote";
|
const char *MNBUDGETFINALVOTE="fbvote"; // depreciated since 12.1
|
||||||
const char *MNQUORUM="mn quorum"; // not implemented
|
const char *MNQUORUM="mn quorum"; // not implemented
|
||||||
const char *MNANNOUNCE="mnb";
|
const char *MNANNOUNCE="mnb";
|
||||||
const char *MNPING="mnp";
|
const char *MNPING="mnp";
|
||||||
@ -61,6 +61,9 @@ const char *DSTX="dstx";
|
|||||||
const char *DSQUEUE="dsq";
|
const char *DSQUEUE="dsq";
|
||||||
const char *DSEG="dseg";
|
const char *DSEG="dseg";
|
||||||
const char *SYNCSTATUSCOUNT="ssc";
|
const char *SYNCSTATUSCOUNT="ssc";
|
||||||
|
const char *MNGOVERNANCESYNC="govsync";
|
||||||
|
const char *MNGOVERNANCEOBJECT="govobj";
|
||||||
|
const char *MNGOVERNANCEOBJECTVOTE="govobjvote";
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char* ppszTypeName[] =
|
static const char* ppszTypeName[] =
|
||||||
@ -69,20 +72,23 @@ static const char* ppszTypeName[] =
|
|||||||
NetMsgType::TX,
|
NetMsgType::TX,
|
||||||
NetMsgType::BLOCK,
|
NetMsgType::BLOCK,
|
||||||
"filtered block", // Should never occur
|
"filtered block", // Should never occur
|
||||||
// Dash message types
|
// Dash message types
|
||||||
|
// NOTE: include non-implmented here, we must keep this list in sync with enum in protocol.h
|
||||||
NetMsgType::IX,
|
NetMsgType::IX,
|
||||||
NetMsgType::IXLOCKVOTE,
|
NetMsgType::IXLOCKVOTE,
|
||||||
NetMsgType::SPORK,
|
NetMsgType::SPORK,
|
||||||
NetMsgType::MNWINNER,
|
NetMsgType::MNWINNER,
|
||||||
NetMsgType::MNSCANERROR, // not implemented
|
NetMsgType::MNSCANERROR, // not implemented
|
||||||
NetMsgType::MNGOVERNANCEVOTE,
|
NetMsgType::MNBUDGETVOTE, // depreciated since 12.1
|
||||||
NetMsgType::MNGOVERNANCEOBJECT,
|
NetMsgType::MNBUDGETPROPOSAL, // depreciated since 12.1
|
||||||
NetMsgType::MNGOVERNANCEFINAL,
|
NetMsgType::MNBUDGETFINAL, // depreciated since 12.1
|
||||||
NetMsgType::MNGOVERNANCEFINALVOTE,
|
NetMsgType::MNBUDGETFINALVOTE, // depreciated since 12.1
|
||||||
NetMsgType::MNQUORUM, // not implemented
|
NetMsgType::MNQUORUM, // not implemented
|
||||||
NetMsgType::MNANNOUNCE,
|
NetMsgType::MNANNOUNCE,
|
||||||
NetMsgType::MNPING,
|
NetMsgType::MNPING,
|
||||||
NetMsgType::DSTX
|
NetMsgType::DSTX,
|
||||||
|
NetMsgType::MNGOVERNANCEOBJECT,
|
||||||
|
NetMsgType::MNGOVERNANCEOBJECTVOTE
|
||||||
};
|
};
|
||||||
|
|
||||||
/** All known message types. Keep this in the same order as the list of
|
/** All known message types. Keep this in the same order as the list of
|
||||||
@ -111,18 +117,14 @@ const static std::string allNetMessageTypes[] = {
|
|||||||
NetMsgType::FILTERCLEAR,
|
NetMsgType::FILTERCLEAR,
|
||||||
NetMsgType::REJECT,
|
NetMsgType::REJECT,
|
||||||
NetMsgType::SENDHEADERS,
|
NetMsgType::SENDHEADERS,
|
||||||
// Dash message types
|
// Dash message types
|
||||||
|
// NOTE: do NOT include non-implmented here, we want them to be "Unknown command" in ProcessMessage()
|
||||||
NetMsgType::IX,
|
NetMsgType::IX,
|
||||||
NetMsgType::IXLOCKVOTE,
|
NetMsgType::IXLOCKVOTE,
|
||||||
NetMsgType::SPORK,
|
NetMsgType::SPORK,
|
||||||
NetMsgType::GETSPORKS,
|
NetMsgType::GETSPORKS,
|
||||||
NetMsgType::MNWINNER,
|
NetMsgType::MNWINNER,
|
||||||
NetMsgType::MNWINNERSSYNC,
|
NetMsgType::MNWINNERSSYNC,
|
||||||
NetMsgType::MNGOVERNANCESYNC,
|
|
||||||
NetMsgType::MNGOVERNANCEVOTE,
|
|
||||||
NetMsgType::MNGOVERNANCEOBJECT,
|
|
||||||
NetMsgType::MNGOVERNANCEFINAL,
|
|
||||||
NetMsgType::MNGOVERNANCEFINALVOTE,
|
|
||||||
NetMsgType::MNANNOUNCE,
|
NetMsgType::MNANNOUNCE,
|
||||||
NetMsgType::MNPING,
|
NetMsgType::MNPING,
|
||||||
NetMsgType::DSACCEPT,
|
NetMsgType::DSACCEPT,
|
||||||
@ -134,7 +136,10 @@ const static std::string allNetMessageTypes[] = {
|
|||||||
NetMsgType::DSTX,
|
NetMsgType::DSTX,
|
||||||
NetMsgType::DSQUEUE,
|
NetMsgType::DSQUEUE,
|
||||||
NetMsgType::DSEG,
|
NetMsgType::DSEG,
|
||||||
NetMsgType::SYNCSTATUSCOUNT
|
NetMsgType::SYNCSTATUSCOUNT,
|
||||||
|
NetMsgType::MNGOVERNANCESYNC,
|
||||||
|
NetMsgType::MNGOVERNANCEOBJECT,
|
||||||
|
NetMsgType::MNGOVERNANCEOBJECTVOTE
|
||||||
};
|
};
|
||||||
const static std::vector<std::string> allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes));
|
const static std::vector<std::string> allNetMessageTypesVec(allNetMessageTypes, allNetMessageTypes+ARRAYLEN(allNetMessageTypes));
|
||||||
|
|
||||||
|
@ -220,6 +220,7 @@ extern const char *REJECT;
|
|||||||
extern const char *SENDHEADERS;
|
extern const char *SENDHEADERS;
|
||||||
|
|
||||||
// Dash message types
|
// Dash message types
|
||||||
|
// NOTE: do NOT declare non-implmented here, we don't want them to be exposed to the outside
|
||||||
// TODO: add description
|
// TODO: add description
|
||||||
extern const char *IX;
|
extern const char *IX;
|
||||||
extern const char *IXLOCKVOTE;
|
extern const char *IXLOCKVOTE;
|
||||||
@ -227,11 +228,6 @@ extern const char *SPORK;
|
|||||||
extern const char *GETSPORKS;
|
extern const char *GETSPORKS;
|
||||||
extern const char *MNWINNER;
|
extern const char *MNWINNER;
|
||||||
extern const char *MNWINNERSSYNC;
|
extern const char *MNWINNERSSYNC;
|
||||||
extern const char *MNGOVERNANCESYNC;
|
|
||||||
extern const char *MNGOVERNANCEVOTE;
|
|
||||||
extern const char *MNGOVERNANCEOBJECT;
|
|
||||||
extern const char *MNGOVERNANCEFINAL;
|
|
||||||
extern const char *MNGOVERNANCEFINALVOTE;
|
|
||||||
extern const char *MNANNOUNCE;
|
extern const char *MNANNOUNCE;
|
||||||
extern const char *MNPING;
|
extern const char *MNPING;
|
||||||
extern const char *DSACCEPT;
|
extern const char *DSACCEPT;
|
||||||
@ -244,6 +240,9 @@ extern const char *DSTX;
|
|||||||
extern const char *DSQUEUE;
|
extern const char *DSQUEUE;
|
||||||
extern const char *DSEG;
|
extern const char *DSEG;
|
||||||
extern const char *SYNCSTATUSCOUNT;
|
extern const char *SYNCSTATUSCOUNT;
|
||||||
|
extern const char *MNGOVERNANCESYNC;
|
||||||
|
extern const char *MNGOVERNANCEOBJECT;
|
||||||
|
extern const char *MNGOVERNANCEOBJECTVOTE;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Get a vector of all valid message types (see above) */
|
/* Get a vector of all valid message types (see above) */
|
||||||
@ -343,17 +342,21 @@ enum {
|
|||||||
MSG_FILTERED_BLOCK,
|
MSG_FILTERED_BLOCK,
|
||||||
MSG_TXLOCK_REQUEST,
|
MSG_TXLOCK_REQUEST,
|
||||||
MSG_TXLOCK_VOTE,
|
MSG_TXLOCK_VOTE,
|
||||||
|
// Dash message types
|
||||||
|
// NOTE: declare non-implmented here, we must keep this enum consistent and backwards compatible
|
||||||
MSG_SPORK,
|
MSG_SPORK,
|
||||||
MSG_MASTERNODE_WINNER,
|
MSG_MASTERNODE_WINNER,
|
||||||
MSG_MASTERNODE_SCANNING_ERROR, // not implemented
|
MSG_MASTERNODE_SCANNING_ERROR, // not implemented
|
||||||
MSG_GOVERNANCE_VOTE,
|
MSG_BUDGET_VOTE, // depreciated since 12.1
|
||||||
MSG_GOVERNANCE_OBJECT,
|
MSG_BUDGET_PROPOSAL, // depreciated since 12.1
|
||||||
MSG_BUDGET_FINALIZED,
|
MSG_BUDGET_FINALIZED, // depreciated since 12.1
|
||||||
MSG_BUDGET_FINALIZED_VOTE,
|
MSG_BUDGET_FINALIZED_VOTE, // depreciated since 12.1
|
||||||
MSG_MASTERNODE_QUORUM, // not implemented
|
MSG_MASTERNODE_QUORUM, // not implemented
|
||||||
MSG_MASTERNODE_ANNOUNCE,
|
MSG_MASTERNODE_ANNOUNCE,
|
||||||
MSG_MASTERNODE_PING,
|
MSG_MASTERNODE_PING,
|
||||||
MSG_DSTX
|
MSG_DSTX,
|
||||||
|
MSG_GOVERNANCE_OBJECT,
|
||||||
|
MSG_GOVERNANCE_OBJECT_VOTE
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BITCOIN_PROTOCOL_H
|
#endif // BITCOIN_PROTOCOL_H
|
||||||
|
Loading…
Reference in New Issue
Block a user