From af377ea072a9b14eb7c4a3f649486fb33e1d44b5 Mon Sep 17 00:00:00 2001 From: Karthik Date: Mon, 28 Feb 2022 20:37:50 -0500 Subject: [PATCH 1/4] Add function to validate DSTX message --- src/net_processing.cpp | 104 ++++++++++++++++++++++++----------------- 1 file changed, 62 insertions(+), 42 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 07012f26ed8c..ae0ad9d6f1ca 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2362,6 +2362,56 @@ std::string RejectCodeToString(const unsigned char code) return ""; } +bool static ValidateDSTX(CCoinJoinBroadcastTx dstx, uint256 hashTx, bool &bReturn) +{ + bReturn = true; + if (!dstx.IsValidStructure()) { + LogPrint(BCLog::COINJOIN, "DSTX -- Invalid DSTX structure: %s\n", hashTx.ToString()); + return false; + } + if(CCoinJoin::GetDSTX(hashTx)) { + LogPrint(BCLog::COINJOIN, "DSTX -- Already have %s, skipping...\n", hashTx.ToString()); + return true; // not an error + } + + const CBlockIndex* pindex{nullptr}; + CDeterministicMNCPtr dmn{nullptr}; + { + LOCK(cs_main); + pindex = chainActive.Tip(); + } + // It could be that a MN is no longer in the list but its DSTX is not yet mined. + // Try to find a MN up to 24 blocks deep to make sure such dstx-es are relayed and processed correctly. + for (int i = 0; i < 24 && pindex; ++i) { + dmn = deterministicMNManager->GetListForBlock(pindex).GetMNByCollateral(dstx.masternodeOutpoint); + if (dmn) break; + pindex = pindex->pprev; + } + if(!dmn) { + LogPrint(BCLog::COINJOIN, "DSTX -- Can't find masternode %s to verify %s\n", dstx.masternodeOutpoint.ToStringShort(), hashTx.ToString()); + return false; + } + + if (!mmetaman.GetMetaInfo(dmn->proTxHash)->IsValidForMixingTxes()) { + LogPrint(BCLog::COINJOIN, "DSTX -- Masternode %s is sending too many transactions %s\n", dstx.masternodeOutpoint.ToStringShort(), hashTx.ToString()); + return true; + // TODO: Not an error? Could it be that someone is relaying old DSTXes + // we have no idea about (e.g we were offline)? How to handle them? + } + + if (!dstx.CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) { + LogPrint(BCLog::COINJOIN, "DSTX -- CheckSignature() failed for %s\n", hashTx.ToString()); + return false; + } + + LogPrint(BCLog::COINJOIN, "DSTX -- Got Masternode transaction %s\n", hashTx.ToString()); + mempool.PrioritiseTransaction(hashTx, 0.1*COIN); + mmetaman.DisallowMixing(dmn->proTxHash); + + bReturn = false; + return true; +} + bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, int64_t nTimeReceived, const CChainParams& chainparams, CConnman* connman, const std::atomic& interruptMsgProc, bool enable_bip61) { LogPrint(BCLog::NET, "received: %s (%u bytes) peer=%d\n", SanitizeString(strCommand), vRecv.size(), pfrom->GetId()); @@ -3149,49 +3199,15 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr // Process custom logic, no matter if tx will be accepted to mempool later or not if (nInvType == MSG_DSTX) { - uint256 hashTx = tx.GetHash(); - if (!dstx.IsValidStructure()) { - LogPrint(BCLog::COINJOIN, "DSTX -- Invalid DSTX structure: %s\n", hashTx.ToString()); - return false; - } - if(CCoinJoin::GetDSTX(hashTx)) { - LogPrint(BCLog::COINJOIN, "DSTX -- Already have %s, skipping...\n", hashTx.ToString()); - return true; // not an error - } - - const CBlockIndex* pindex{nullptr}; - CDeterministicMNCPtr dmn{nullptr}; - { - LOCK(cs_main); - pindex = ::ChainActive().Tip(); - } - // It could be that a MN is no longer in the list but its DSTX is not yet mined. - // Try to find a MN up to 24 blocks deep to make sure such dstx-es are relayed and processed correctly. - for (int i = 0; i < 24 && pindex; ++i) { - dmn = deterministicMNManager->GetListForBlock(pindex).GetMNByCollateral(dstx.masternodeOutpoint); - if (dmn) break; - pindex = pindex->pprev; - } - if(!dmn) { - LogPrint(BCLog::COINJOIN, "DSTX -- Can't find masternode %s to verify %s\n", dstx.masternodeOutpoint.ToStringShort(), hashTx.ToString()); - return false; - } - - if (!mmetaman.GetMetaInfo(dmn->proTxHash)->IsValidForMixingTxes()) { - LogPrint(BCLog::COINJOIN, "DSTX -- Masternode %s is sending too many transactions %s\n", dstx.masternodeOutpoint.ToStringShort(), hashTx.ToString()); - return true; - // TODO: Not an error? Could it be that someone is relaying old DSTXes - // we have no idea about (e.g we were offline)? How to handle them? - } - - if (!dstx.CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) { - LogPrint(BCLog::COINJOIN, "DSTX -- CheckSignature() failed for %s\n", hashTx.ToString()); - return false; - } - LogPrint(BCLog::COINJOIN, "DSTX -- Got Masternode transaction %s\n", hashTx.ToString()); - mempool.PrioritiseTransaction(hashTx, 0.1*COIN); - mmetaman.DisallowMixing(dmn->proTxHash); + // Validate DSTX and return bRet if we need to return from here + bool bDoReturn = false; + uint256 hashTx = tx.GetHash(); + bool bRet = ValidateDSTX(dstx, hashTx, bDoReturn); + if (bDoReturn) + { + return bRet; + } } LOCK2(cs_main, g_cs_orphans); @@ -4908,5 +4924,9 @@ class CNetProcessingCleanup mapOrphanTransactionsByPrev.clear(); nMapOrphanTransactionsSize = 0; } +<<<<<<< HEAD }; static CNetProcessingCleanup instance_of_cnetprocessingcleanup; +======= +} instance_of_cnetprocessingcleanup; +>>>>>>> Add function to validate DSTX message From 4c827beaf23403be30bb95d72afdf342e9725b7e Mon Sep 17 00:00:00 2001 From: Karthik Date: Tue, 29 Mar 2022 07:59:33 -0400 Subject: [PATCH 2/4] Addressed review comment: Remove text left due to merge --- src/net_processing.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index ae0ad9d6f1ca..51348ff3289c 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -4924,9 +4924,5 @@ class CNetProcessingCleanup mapOrphanTransactionsByPrev.clear(); nMapOrphanTransactionsSize = 0; } -<<<<<<< HEAD }; -static CNetProcessingCleanup instance_of_cnetprocessingcleanup; -======= -} instance_of_cnetprocessingcleanup; ->>>>>>> Add function to validate DSTX message +static CNetProcessingCleanup instance_of_cnetprocessingcleanup; \ No newline at end of file From b7d3ece218500d993136ba871350e206f8a34a7a Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 30 Mar 2022 02:55:57 +0300 Subject: [PATCH 3/4] Apply suggestions from code review --- src/net_processing.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 51348ff3289c..1d799d93eea9 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -2378,7 +2378,7 @@ bool static ValidateDSTX(CCoinJoinBroadcastTx dstx, uint256 hashTx, bool &bRetur CDeterministicMNCPtr dmn{nullptr}; { LOCK(cs_main); - pindex = chainActive.Tip(); + pindex = ::ChainActive().Tip(); } // It could be that a MN is no longer in the list but its DSTX is not yet mined. // Try to find a MN up to 24 blocks deep to make sure such dstx-es are relayed and processed correctly. @@ -3204,8 +3204,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr bool bDoReturn = false; uint256 hashTx = tx.GetHash(); bool bRet = ValidateDSTX(dstx, hashTx, bDoReturn); - if (bDoReturn) - { + if (bDoReturn) { return bRet; } } @@ -4925,4 +4924,4 @@ class CNetProcessingCleanup nMapOrphanTransactionsSize = 0; } }; -static CNetProcessingCleanup instance_of_cnetprocessingcleanup; \ No newline at end of file +static CNetProcessingCleanup instance_of_cnetprocessingcleanup; From 3c628f07c440ce6064b6769720af62cce7b73124 Mon Sep 17 00:00:00 2001 From: UdjinM6 Date: Wed, 30 Mar 2022 03:44:01 +0300 Subject: [PATCH 4/4] Update src/net_processing.cpp --- src/net_processing.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 1d799d93eea9..f88afc79d86a 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -3200,7 +3200,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr // Process custom logic, no matter if tx will be accepted to mempool later or not if (nInvType == MSG_DSTX) { - // Validate DSTX and return bRet if we need to return from here + // Validate DSTX and return bRet if we need to return from here bool bDoReturn = false; uint256 hashTx = tx.GetHash(); bool bRet = ValidateDSTX(dstx, hashTx, bDoReturn);