diff --git a/src/infinitynodelockreward.cpp b/src/infinitynodelockreward.cpp index c4bbc881b6..d26564d1a6 100644 --- a/src/infinitynodelockreward.cpp +++ b/src/infinitynodelockreward.cpp @@ -44,7 +44,7 @@ bool CLockRewardRequest::Sign(const CKey& keyInfinitynode, const CPubKey& pubKey } if(!CMessageSigner::VerifyMessage(pubKeyInfinitynode, vchSig, strMessage, strError)) { - LogPrintf("CMasternodePing::Sign -- VerifyMessage() failed, error: %s\n", strError); + LogPrintf("CLockRewardRequest::Sign -- VerifyMessage() failed, error: %s\n", strError); return false; } @@ -59,7 +59,7 @@ bool CLockRewardRequest::CheckSignature(CPubKey& pubKeyInfinitynode, int &nDos) std::string strError = ""; if(!CMessageSigner::VerifyMessage(pubKeyInfinitynode, vchSig, strMessage, strError)) { - LogPrintf("CMasternodePing::CheckSignature -- Got bad Infinitynode LockReward signature, ID=%s, error: %s\n", + LogPrintf("CLockRewardRequest::CheckSignature -- Got bad Infinitynode LockReward signature, ID=%s, error: %s\n", burnTxIn.prevout.ToStringShort(), strError); /*TODO: set ban value befor release*/ nDos = 0; @@ -81,7 +81,7 @@ bool CLockRewardRequest::IsValid(CNode* pnode, int nValidationHeight, std::strin return false; } - int nDos = 0; + int nDos = 20; CMetadata meta = infnodemeta.Find(inf.getMetaID()); std::string metaPublicKey = meta.getMetaPublicKey(); std::vector tx_data = DecodeBase64(metaPublicKey.c_str()); @@ -161,9 +161,6 @@ bool CInfinityNodeLockReward::GetLockRewardRequest(const uint256& reqHash, CLock return true; } -/* - * find old request which has the same nRewardHeight, burnTxIn, nSINtype, nLoop inferior => remove it - */ void CInfinityNodeLockReward::RemoveLockRewardRequest(const CLockRewardRequest& lockRewardRequest) { AssertLockHeld(cs); @@ -181,18 +178,30 @@ void CInfinityNodeLockReward::RemoveLockRewardRequest(const CLockRewardRequest& } } -bool CInfinityNodeLockReward::ProcessLockRewardRequest(CNode* pfrom, CLockRewardRequest& lockRewardRequestRet, CConnman& connman, int nBlockHeight) +/* + * STEP 1: get a new LockRewardRequest, check it and send verify message + * + * STEP 1.1 check LockRewardRequest is valid or NOT + * - the nHeight of request cannot be lower than current height + * - the nHeight of request cannot so far in future ( currentHeight + Params().GetConsensus().nInfinityNodeCallLockRewardDeepth + 2) + * - the LockRewardRequest must be valid + * + from (nHeight, SINtype) => find candidate + * + CTxIn of request and CTxIn of candidate must be identical + * + Find publicKey of Candidate in metadata and check the signature in request + */ +bool CInfinityNodeLockReward::CheckLockRewardRequest(CNode* pfrom, CLockRewardRequest& lockRewardRequestRet, CConnman& connman, int nBlockHeight) { AssertLockHeld(cs); if(lockRewardRequestRet.nRewardHeight > nBlockHeight + Params().GetConsensus().nInfinityNodeCallLockRewardDeepth + 2 || lockRewardRequestRet.nRewardHeight < nBlockHeight){ - LogPrintf("CInfinityNodeLockReward::ProcessLockRewardRequest -- LockRewardRequest for invalid height: %d, current height: %d\n", lockRewardRequestRet.nRewardHeight, nBlockHeight); + LogPrintf("CInfinityNodeLockReward::CheckLockRewardRequest -- LockRewardRequest for invalid height: %d, current height: %d\n", + lockRewardRequestRet.nRewardHeight, nBlockHeight); return false; } std::string strError = ""; if(!lockRewardRequestRet.IsValid(pfrom, nBlockHeight, strError, connman)){ - LogPrintf("CInfinityNodeLockReward::ProcessLockRewardRequest -- LockRewardRequest is invalid. ERROR: %s\n",strError); + LogPrintf("CInfinityNodeLockReward::CheckLockRewardRequest -- LockRewardRequest is invalid. ERROR: %s\n",strError); return false; } @@ -200,7 +209,68 @@ bool CInfinityNodeLockReward::ProcessLockRewardRequest(CNode* pfrom, CLockReward } /* - * send verify request to Candidate A at IP(addr) for Request(lockRewardRequestRet) + * STEP 1: get a new LockRewardRequest, check it and send verify message + * + * STEP 1.2 verify candidate + */ + +bool CInfinityNodeLockReward::VerifyLockRewardCandidate(CLockRewardRequest& lockRewardRequestRet, CConnman& connman) +{ + AssertLockHeld(cs); + //step 1.2.1: chech if mypeer is good candidate to make Musig + CInfinitynode infRet; + if(!infnodeman.Get(infinitynodePeer.burntx, infRet)){ + LogPrintf("CInfinityNodeLockReward::VerifyLockRewardCandidate -- Can not identify mypeer in list, height: %d\n"); + return false; + } + + int nScore; + + if(!infnodeman.getNodeScoreAtHeight(infinitynodePeer.burntx, lockRewardRequestRet.nRewardHeight - 101, nScore)) { + LogPrintf("CMasternodePaymentVote::VerifyLockRewardCandidate -- Can't calculate score for Infinitynode %s\n", + infinitynodePeer.burntx.ToStringShort()); + return false; + } + + //step 1.2.2: if my score is in Top, i will verify that candidate is online at IP + + //step 1.2.2.1: get InfCandidate from request + CInfinitynode infCandidate; + if(!infnodeman.Get(lockRewardRequestRet.burnTxIn.prevout, infCandidate)){ + LogPrintf("CInfinityNodeLockReward::VerifyLockRewardCandidate -- Cannot identify candidate in list\n"); + return false; + } + + CMetadata metaCandidate = infnodemeta.Find(infCandidate.getMetaID()); + if(metaCandidate.getMetadataHeight() == 0){ + LogPrintf("CInfinityNodeLockReward::VerifyLockRewardCandidate -- Cannot get metadata of candidate %s\n", infCandidate.getBurntxOutPoint().ToStringShort()); + return false; + } + + CService candidateService = metaCandidate.getService(); + if(!SendVerifyRequest(CAddress(candidateService, NODE_NETWORK), infinitynodePeer.burntx, lockRewardRequestRet, connman)){ + LogPrintf("CInfinityNodeLockReward::VerifyLockRewardCandidate -- Cannot send verify message to candidate %s\n", infCandidate.getBurntxOutPoint().ToStringShort()); + return false; + } + + return true; + //TODO: + /* + if(nScore < Params().GetConsensus().nInfinityNodeLockRewardTop) { + //step 2.1: verify node which send the request is online at IP in metadata + //SendVerifyRequest() + //step 2.2: send commitment + return true; + } else { + LogPrintf("CMasternodePaymentVote::VerifyLockRewardCandidate -- I am not in Top score\n"); + return false; + }*/ +} + +/* + * STEP 1: get a new LockRewardRequest, check it and send verify message + * + * STEP 1.3 send verify request to Candidate A at IP(addr) for Request(lockRewardRequestRet) */ bool CInfinityNodeLockReward::SendVerifyRequest(const CAddress& addr, COutPoint myPeerBurnTx, CLockRewardRequest& lockRewardRequestRet, CConnman& connman) { @@ -209,14 +279,14 @@ bool CInfinityNodeLockReward::SendVerifyRequest(const CAddress& addr, COutPoint std::string strMessage = strprintf("%s%d%s", myPeerBurnTx.ToString(), vrequest.nonce, lockRewardRequestRet.GetHash().ToString()); if(!CMessageSigner::SignMessage(strMessage, vrequest.vchSig1, infinitynodePeer.keyInfinitynode)) { - LogPrintf("CInfinityNodeLockReward::SendVerifyReply -- SignMessage() failed\n"); + LogPrintf("CInfinityNodeLockReward::SendVerifyRequest -- SignMessage() failed\n"); return false; } std::string strError; if(!CMessageSigner::VerifyMessage(infinitynodePeer.pubKeyInfinitynode, vrequest.vchSig1, strMessage, strError)) { - LogPrintf("CInfinityNodeLockReward::SendVerifyReply -- VerifyMessage() failed, error: %s\n", strError); + LogPrintf("CInfinityNodeLockReward::SendVerifyRequest -- VerifyMessage() failed, error: %s\n", strError); return false; } @@ -233,69 +303,90 @@ bool CInfinityNodeLockReward::SendVerifyRequest(const CAddress& addr, COutPoint return true; } -bool CInfinityNodeLockReward::ProcessLockRewardCommitment(CLockRewardRequest& lockRewardRequestRet, CConnman& connman) +/* + * STEP 2: get a verify message, check and try to answer the message + * + * check: + * - VerifyRequest was sent from Top Node + * - Signature of VerifyRequest is correct + * answer: + * - create the 2nd signature - my signature and send back to node + * processVerifyRequestReply: + * - check 2nd signature + * - disconnect to node ( Candidate ) + */ +//TODO: ban pnode if false +bool CInfinityNodeLockReward::SendVerifyReply(CNode* pnode, CVerifyRequest& vrequest, CConnman& connman) { + // only Infinitynode will answer the verify requrest + if(!fInfinityNode) {return false;} + AssertLockHeld(cs); - //step 1: chech if mypeer is good candidate to make Musig - CInfinitynode infRet; - if(!infnodeman.Get(infinitynodePeer.burntx, infRet)){ - LogPrintf("CInfinityNodeLockReward::ProcessLockRewardCommitment -- Can not identify mypeer in list, height: %d\n"); + + //step 2.0 get publicKey of sender and check signature + infinitynode_info_t infoInf; + if(!infnodeman.GetInfinitynodeInfo(vrequest.vin1.prevout, infoInf)){ + LogPrintf("CInfinityNodeLockReward::SendVerifyReply -- Cannot find sender from list %s\n"); return false; } - int nScore; + CMetadata metaSender = infnodemeta.Find(infoInf.metadataID); + if (metaSender.getMetadataHeight() == 0){ + LogPrintf("CInfinityNodeLockReward::SendVerifyReply -- Cannot find sender from list %s\n"); + return false; + } - if(!infnodeman.getNodeScoreAtHeight(infinitynodePeer.burntx, lockRewardRequestRet.nRewardHeight - 101, nScore)) { - LogPrintf("CMasternodePaymentVote::ProcessLockRewardCommitment -- Can't calculate score for Infinitynode %s\n", - infinitynodePeer.burntx.ToStringShort()); + std::string metaPublicKey = metaSender.getMetaPublicKey(); + std::vector tx_data = DecodeBase64(metaPublicKey.c_str()); + CPubKey pubKey(tx_data.begin(), tx_data.end()); + + std::string strError; + std::string strMessage = strprintf("%s%d%s", vrequest.vin1.prevout.ToString(), vrequest.nonce, vrequest.nHashRequest.ToString()); + if(!CMessageSigner::VerifyMessage(pubKey, vrequest.vchSig1, strMessage, strError)) { + LogPrintf("CInfinityNodeLockReward::SendVerifyReply -- VerifyMessage() failed, error: %s, message: \n", strError, strMessage); return false; } - //step 2: if my score is in Top, i can send commitment to build Musig - if(nScore < Params().GetConsensus().nInfinityNodeLockRewardTop) { - //step 2.1: verify node which send the request is online at IP in metadata - //SendVerifyRequest() - //step 2.2: send commitment - return true; - } else { - LogPrintf("CMasternodePaymentVote::ProcessLockRewardCommitment -- I am not in Top score\n"); + //step 2.1 check if sender in Top (skip this step for now) + + //step 2.2 sign a new message and send it back to sender + vrequest.addr = infinitynodePeer.service; + vrequest.vin2 = CTxIn(infinitynodePeer.burntx); + std::string strMessage2 = strprintf("%s%d%s%s%s", vrequest.addr.ToString(false), vrequest.nonce, vrequest.nHashRequest.ToString(), + vrequest.vin1.prevout.ToStringShort(), vrequest.vin2.prevout.ToStringShort()); + + if(!CMessageSigner::SignMessage(strMessage2, vrequest.vchSig2, infinitynodePeer.keyInfinitynode)) { + LogPrintf("CInfinityNodeLockReward::ProcessVerifyReply -- SignMessage() failed\n"); + return false; + } + + if(!CMessageSigner::VerifyMessage(infinitynodePeer.pubKeyInfinitynode, vrequest.vchSig2, strMessage2, strError)) { + LogPrintf("CInfinityNodeLockReward::ProcessVerifyReply -- VerifyMessage() failed, error: %s\n", strError); return false; } + + connman.PushMessage(pnode, CNetMsgMaker(pnode->GetSendVersion()).Make(NetMsgType::INFVERIFY, vrequest)); + return true; } -void CInfinityNodeLockReward::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman) +/* + * STEP 3: check return VerifyRequest, if it is OK then + * - send the commitment + * - disconect node + */ +bool CInfinityNodeLockReward::CheckVerifyReply(CNode* pnode, CVerifyRequest& vrequest) { - if(fLiteMode) return; // disable all SIN specific functionality - if (strCommand == NetMsgType::INFLOCKREWARDINIT) { - CLockRewardRequest lockReq; - vRecv >> lockReq; - //dont ask pfrom for this Request anymore - uint256 nHash = lockReq.GetHash(); - pfrom->setAskFor.erase(nHash); - { - LOCK(cs); - if(mapLockRewardRequest.count(nHash)) return; - if(!ProcessLockRewardRequest(pfrom, lockReq, connman, nCachedBlockHeight)){ - return; - } - LogPrintf("CInfinityNodeLockReward::ProcessMessage -- add new LockRewardRequest from %d\n",pfrom->GetId()); - if(AddLockRewardRequest(lockReq)){ - lockReq.Relay(connman); - if(!ProcessLockRewardCommitment(lockReq, connman)){ - LogPrintf("CInfinityNodeLockReward::ProcessMessage -- can not send commitment. May be i am not in Top score.\n"); - return; - } - } - return; - } - } + pnode->fDisconnect = true; } +/* + * STEP 0: create LockRewardRequest if i am a candidate at nHeight + */ bool CInfinityNodeLockReward::ProcessBlock(int nBlockHeight, CConnman& connman) { if(fLiteMode || !fInfinityNode) return false; - //step 1: Check if this InfinitynodePeer is a candidate at nBlockHeight + //step 0.1: Check if this InfinitynodePeer is a candidate at nBlockHeight CInfinitynode infRet; if(!infnodeman.Get(infinitynodePeer.burntx, infRet)){ LogPrintf("CInfinityNodeLockReward::ProcessBlock -- Can not identify mypeer in list, height: %d\n", nBlockHeight); @@ -308,10 +399,9 @@ bool CInfinityNodeLockReward::ProcessBlock(int nBlockHeight, CConnman& connman) return false; } - // we know that nRewardHeight >= nCachedBlockHeight + Params().GetConsensus().nInfinityNodeCallLockRewardLoop + //step 0.2 we know that nRewardHeight >= nCachedBlockHeight + Params().GetConsensus().nInfinityNodeCallLockRewardLoop int loop = (Params().GetConsensus().nInfinityNodeCallLockRewardDeepth / (nRewardHeight - nCachedBlockHeight)) - 1; CLockRewardRequest newRequest(nRewardHeight, infRet.getBurntxOutPoint(), infRet.getSINType(), loop); - // SIGN MESSAGE TO NETWORK WITH OUR MASTERNODE KEYS if (newRequest.Sign(infinitynodePeer.keyInfinitynode, infinitynodePeer.pubKeyInfinitynode)) { LOCK(cs); if (AddLockRewardRequest(newRequest)) { @@ -323,6 +413,49 @@ bool CInfinityNodeLockReward::ProcessBlock(int nBlockHeight, CConnman& connman) return true; } +void CInfinityNodeLockReward::ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman) +{ + if(fLiteMode) return; // disable all SIN specific functionality + if (strCommand == NetMsgType::INFLOCKREWARDINIT) { + CLockRewardRequest lockReq; + vRecv >> lockReq; + //dont ask pfrom for this Request anymore + uint256 nHash = lockReq.GetHash(); + pfrom->setAskFor.erase(nHash); + { + LOCK(cs); + if(mapLockRewardRequest.count(nHash)) return; + if(!CheckLockRewardRequest(pfrom, lockReq, connman, nCachedBlockHeight)){ + return; + } + LogPrintf("CInfinityNodeLockReward::ProcessMessage -- add new LockRewardRequest from %d\n",pfrom->GetId()); + if(AddLockRewardRequest(lockReq)){ + lockReq.Relay(connman); + if(!VerifyLockRewardCandidate(lockReq, connman)){ + LogPrintf("CInfinityNodeLockReward::ProcessMessage -- can not send commitment. May be i am not in Top score.\n"); + return; + } + } + return; + } + } else if (strCommand == NetMsgType::INFVERIFY) { + CVerifyRequest vrequest; + vRecv >> vrequest; + + pfrom->setAskFor.erase(vrequest.GetHash()); + { + LOCK(cs); + if(!vrequest.vchSig1.empty() && vrequest.vchSig2.empty()) { + SendVerifyReply(pfrom, vrequest, connman); + } + if(!vrequest.vchSig1.empty() && !vrequest.vchSig2.empty()) { + CheckVerifyReply(pfrom, vrequest); + } + return; + } + } +} + void CInfinityNodeLockReward::UpdatedBlockTip(const CBlockIndex *pindex, CConnman& connman) { if(!pindex) return; diff --git a/src/infinitynodelockreward.h b/src/infinitynodelockreward.h index 340d99a7f8..e7bd634483 100644 --- a/src/infinitynodelockreward.h +++ b/src/infinitynodelockreward.h @@ -180,16 +180,13 @@ class CInfinityNodeLockReward /*TODO: Verify node at IP*/ bool SendVerifyRequest(const CAddress& addr, COutPoint myPeerBurnTx, CLockRewardRequest& lockRewardRequestRet, CConnman& connman); - /* - void SendVerifyReply(CNode* pnode, CMasternodeVerification& mnv, CConnman& connman); - void ProcessVerifyReply(CNode* pnode, CMasternodeVerification& mnv); - void ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerification& mnv); - */ + bool SendVerifyReply(CNode* pnode, CVerifyRequest& vrequest, CConnman& connman); + bool CheckVerifyReply(CNode* pnode, CVerifyRequest& vrequest); //process consensus request message bool getCkeyForRequest(uint256 nRequest); - bool ProcessLockRewardRequest(CNode* pfrom, CLockRewardRequest& lockRewardRequestRet, CConnman& connman, int nBlockHeight); - bool ProcessLockRewardCommitment(CLockRewardRequest& lockRewardRequestRet, CConnman& connman); + bool CheckLockRewardRequest(CNode* pfrom, CLockRewardRequest& lockRewardRequestRet, CConnman& connman, int nBlockHeight); + bool VerifyLockRewardCandidate(CLockRewardRequest& lockRewardRequestRet, CConnman& connman); /*call in UpdatedBlockTip*/ bool ProcessBlock(int nBlockHeight, CConnman& connman); /*call in processing.cpp when node receive INV*/ diff --git a/src/infinitynodeman.cpp b/src/infinitynodeman.cpp index 1193fc842f..80215c332e 100644 --- a/src/infinitynodeman.cpp +++ b/src/infinitynodeman.cpp @@ -909,267 +909,6 @@ bool CInfinitynodeMan::getNodeScoreAtHeight(const COutPoint& outpoint, int nBloc return false; } -/* -void CInfinitynodeMan::SendVerifyReply(CNode* pnode, CMasternodeVerification& mnv, CConnman& connman) -{ - AssertLockHeld(cs_main); - - // only masternodes can sign this, why would someone ask regular node? - if(!fMasterNode) { - // do not ban, malicious node might be using my IP - // and trying to confuse the node which tries to verify it - return; - } - - if(netfulfilledman.HasFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-reply")) { - // peer should not ask us that often - LogPrintf("MasternodeMan::SendVerifyReply -- ERROR: peer already asked me recently, peer=%d\n", pnode->GetId()); - Misbehaving(pnode->GetId(), 20); - return; - } - - uint256 blockHash; - if(!GetBlockHash(blockHash, mnv.nBlockHeight)) { - LogPrintf("MasternodeMan::SendVerifyReply -- can't get block hash for unknown block height %d, peer=%d\n", mnv.nBlockHeight, pnode->GetId()); - return; - } - - std::string strMessage = strprintf("%s%d%s", activeMasternode.service.ToString(false), mnv.nonce, blockHash.ToString()); - - if(!CMessageSigner::SignMessage(strMessage, mnv.vchSig1, activeMasternode.keyMasternode)) { - LogPrintf("MasternodeMan::SendVerifyReply -- SignMessage() failed\n"); - return; - } - - std::string strError; - - if(!CMessageSigner::VerifyMessage(activeMasternode.pubKeyMasternode, mnv.vchSig1, strMessage, strError)) { - LogPrintf("MasternodeMan::SendVerifyReply -- VerifyMessage() failed, error: %s\n", strError); - return; - } - - connman.PushMessage(pnode, CNetMsgMaker(pnode->GetSendVersion()).Make(NetMsgType::MNVERIFY, mnv)); - netfulfilledman.AddFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-reply"); -} - -void CInfinitynodeMan::ProcessVerifyReply(CNode* pnode, CMasternodeVerification& mnv) -{ - AssertLockHeld(cs_main); - - std::string strError; - - // did we even ask for it? if that's the case we should have matching fulfilled request - if(!netfulfilledman.HasFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-request")) { - LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: we didn't ask for verification of %s, peer=%d\n", pnode->addr.ToString(), pnode->GetId()); - Misbehaving(pnode->GetId(), 20); - return; - } - - // Received nonce for a known address must match the one we sent - if(mWeAskedForVerification[pnode->addr].nonce != mnv.nonce) { - LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: wrong nounce: requested=%d, received=%d, peer=%d\n", - mWeAskedForVerification[pnode->addr].nonce, mnv.nonce, pnode->GetId()); - Misbehaving(pnode->GetId(), 20); - return; - } - - // Received nBlockHeight for a known address must match the one we sent - if(mWeAskedForVerification[pnode->addr].nBlockHeight != mnv.nBlockHeight) { - LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: wrong nBlockHeight: requested=%d, received=%d, peer=%d\n", - mWeAskedForVerification[pnode->addr].nBlockHeight, mnv.nBlockHeight, pnode->GetId()); - Misbehaving(pnode->GetId(), 20); - return; - } - - uint256 blockHash; - if(!GetBlockHash(blockHash, mnv.nBlockHeight)) { - // this shouldn't happen... - LogPrintf("MasternodeMan::ProcessVerifyReply -- can't get block hash for unknown block height %d, peer=%d\n", mnv.nBlockHeight, pnode->GetId()); - return; - } - - // we already verified this address, why node is spamming? - if(netfulfilledman.HasFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-done")) { - LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: already verified %s recently\n", pnode->addr.ToString()); - Misbehaving(pnode->GetId(), 20); - return; - } - - { - LOCK(cs); - - CMasternode* prealMasternode = NULL; - std::vector vpMasternodesToBan; - std::string strMessage1 = strprintf("%s%d%s", pnode->addr.ToString(false), mnv.nonce, blockHash.ToString()); - for (auto& mnpair : mapMasternodes) { - if(CAddress(mnpair.second.addr, NODE_NETWORK) == pnode->addr) { - if(CMessageSigner::VerifyMessage(mnpair.second.pubKeyMasternode, mnv.vchSig1, strMessage1, strError)) { - // found it! - prealMasternode = &mnpair.second; - if(!mnpair.second.IsPoSeVerified()) { - mnpair.second.DecreasePoSeBanScore(); - } - netfulfilledman.AddFulfilledRequest(pnode->addr, strprintf("%s", NetMsgType::MNVERIFY)+"-done"); - - // we can only broadcast it if we are an activated masternode - if(activeMasternode.outpoint == COutPoint()) continue; - // update ... - mnv.addr = mnpair.second.addr; - mnv.vin1 = mnpair.second.vin; - mnv.vin2 = CTxIn(activeMasternode.outpoint); - std::string strMessage2 = strprintf("%s%d%s%s%s", mnv.addr.ToString(false), mnv.nonce, blockHash.ToString(), - mnv.vin1.prevout.ToStringShort(), mnv.vin2.prevout.ToStringShort()); - // ... and sign it - if(!CMessageSigner::SignMessage(strMessage2, mnv.vchSig2, activeMasternode.keyMasternode)) { - LogPrintf("MasternodeMan::ProcessVerifyReply -- SignMessage() failed\n"); - return; - } - - std::string strError; - - if(!CMessageSigner::VerifyMessage(activeMasternode.pubKeyMasternode, mnv.vchSig2, strMessage2, strError)) { - LogPrintf("MasternodeMan::ProcessVerifyReply -- VerifyMessage() failed, error: %s\n", strError); - return; - } - - mWeAskedForVerification[pnode->addr] = mnv; - mapSeenMasternodeVerification.insert(std::make_pair(mnv.GetHash(), mnv)); - mnv.Relay(); - - } else { - vpMasternodesToBan.push_back(&mnpair.second); - } - } - } - // no real masternode found?... - if(!prealMasternode) { - // this should never be the case normally, - // only if someone is trying to game the system in some way or smth like that - LogPrintf("CMasternodeMan::ProcessVerifyReply -- ERROR: no real masternode found for addr %s\n", pnode->addr.ToString()); - Misbehaving(pnode->GetId(), 20); - return; - } - LogPrintf("CMasternodeMan::ProcessVerifyReply -- verified real masternode %s for addr %s\n", - prealMasternode->vin.prevout.ToStringShort(), pnode->addr.ToString()); - // increase ban score for everyone else - for (auto* pmn : vpMasternodesToBan) { - pmn->IncreasePoSeBanScore(); - LogPrint(BCLog::MASTERNODE, "CMasternodeMan::ProcessVerifyReply -- increased PoSe ban score for %s addr %s, new score %d\n", - prealMasternode->vin.prevout.ToStringShort(), pnode->addr.ToString(), pmn->nPoSeBanScore); - } - if(!vpMasternodesToBan.empty()) - LogPrintf("CMasternodeMan::ProcessVerifyReply -- PoSe score increased for %d fake masternodes, addr %s\n", - (int)vpMasternodesToBan.size(), pnode->addr.ToString()); - } -} - -void CInfinitynodeMan::ProcessVerifyBroadcast(CNode* pnode, const CMasternodeVerification& mnv) -{ - AssertLockHeld(cs_main); - - std::string strError; - - if(mapSeenMasternodeVerification.find(mnv.GetHash()) != mapSeenMasternodeVerification.end()) { - // we already have one - return; - } - mapSeenMasternodeVerification[mnv.GetHash()] = mnv; - - // we don't care about history - if(mnv.nBlockHeight < nCachedBlockHeight - MAX_POSE_BLOCKS) { - LogPrint(BCLog::MASTERNODE, "CMasternodeMan::ProcessVerifyBroadcast -- Outdated: current block %d, verification block %d, peer=%d\n", - nCachedBlockHeight, mnv.nBlockHeight, pnode->GetId()); - return; - } - - if(mnv.vin1.prevout == mnv.vin2.prevout) { - LogPrint(BCLog::MASTERNODE, "CMasternodeMan::ProcessVerifyBroadcast -- ERROR: same vins %s, peer=%d\n", - mnv.vin1.prevout.ToStringShort(), pnode->GetId()); - // that was NOT a good idea to cheat and verify itself, - // ban the node we received such message from - Misbehaving(pnode->GetId(), 100); - return; - } - - uint256 blockHash; - if(!GetBlockHash(blockHash, mnv.nBlockHeight)) { - // this shouldn't happen... - LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- Can't get block hash for unknown block height %d, peer=%d\n", mnv.nBlockHeight, pnode->GetId()); - return; - } - - int nRank; - - if (!GetMasternodeRank(mnv.vin2.prevout, nRank, mnv.nBlockHeight, MIN_POSE_PROTO_VERSION)) { - LogPrint(BCLog::MASTERNODE, "CMasternodeMan::ProcessVerifyBroadcast -- Can't calculate rank for masternode %s\n", - mnv.vin2.prevout.ToStringShort()); - return; - } - - if(nRank > MAX_POSE_RANK) { - LogPrint(BCLog::MASTERNODE, "CMasternodeMan::ProcessVerifyBroadcast -- Masternode %s is not in top %d, current rank %d, peer=%d\n", - mnv.vin2.prevout.ToStringShort(), (int)MAX_POSE_RANK, nRank, pnode->GetId()); - return; - } - - { - LOCK(cs); - - std::string strMessage1 = strprintf("%s%d%s", mnv.addr.ToString(false), mnv.nonce, blockHash.ToString()); - std::string strMessage2 = strprintf("%s%d%s%s%s", mnv.addr.ToString(false), mnv.nonce, blockHash.ToString(), - mnv.vin1.prevout.ToStringShort(), mnv.vin2.prevout.ToStringShort()); - - CMasternode* pmn1 = Find(mnv.vin1.prevout); - if(!pmn1) { - LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- can't find masternode1 %s\n", mnv.vin1.prevout.ToStringShort()); - return; - } - - CMasternode* pmn2 = Find(mnv.vin2.prevout); - if(!pmn2) { - LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- can't find masternode2 %s\n", mnv.vin2.prevout.ToStringShort()); - return; - } - - if(pmn1->addr != mnv.addr) { - LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- addr %s does not match %s\n", mnv.addr.ToString(), pmn1->addr.ToString()); - return; - } - - if(!CMessageSigner::VerifyMessage(pmn1->pubKeyMasternode, mnv.vchSig1, strMessage1, strError)) { - LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- VerifyMessage() for masternode1 failed, error: %s\n", strError); - return; - } - - if(!CMessageSigner::VerifyMessage(pmn2->pubKeyMasternode, mnv.vchSig2, strMessage2, strError)) { - LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- VerifyMessage() for masternode2 failed, error: %s\n", strError); - return; - } - - if(!pmn1->IsPoSeVerified()) { - pmn1->DecreasePoSeBanScore(); - } - mnv.Relay(); - - LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- verified masternode %s for addr %s\n", - pmn1->vin.prevout.ToStringShort(), pmn1->addr.ToString()); - - // increase ban score for everyone else with the same addr - int nCount = 0; - for (auto& mnpair : mapMasternodes) { - if(mnpair.second.addr != mnv.addr || mnpair.first == mnv.vin1.prevout) continue; - mnpair.second.IncreasePoSeBanScore(); - nCount++; - LogPrint(BCLog::MASTERNODE, "CMasternodeMan::ProcessVerifyBroadcast -- increased PoSe ban score for %s addr %s, new score %d\n", - mnpair.first.ToStringShort(), mnpair.second.addr.ToString(), mnpair.second.nPoSeBanScore); - } - if(nCount) - LogPrintf("CMasternodeMan::ProcessVerifyBroadcast -- PoSe score increased for %d fake masternodes, addr %s\n", - nCount, pmn1->addr.ToString()); - } -} -*/ - void CInfinitynodeMan::UpdatedBlockTip(const CBlockIndex *pindex) { nCachedBlockHeight = pindex->nHeight;