@@ -171,15 +171,17 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm
171171
172172 LogPrint (BCLog::PRIVATESEND, " DSVIN -- txCollateral %s" , entry.txCollateral ->ToString ());
173173
174- if (entry.vecTxDSIn .size () > PRIVATESEND_ENTRY_MAX_SIZE) {
175- LogPrintf (" DSVIN -- ERROR: too many inputs! %d/%d\n " , entry.vecTxDSIn .size (), PRIVATESEND_ENTRY_MAX_SIZE);
176- PushStatus (pfrom, STATUS_REJECTED, ERR_MAXIMUM, connman);
174+ if (entry.vecTxDSIn .size () != entry.vecTxOut .size ()) {
175+ LogPrintf (" DSVIN -- ERROR: inputs vs outputs size mismatch! %d vs %d\n " , entry.vecTxDSIn .size (), entry.vecTxOut .size ());
176+ PushStatus (pfrom, STATUS_REJECTED, ERR_SIZE_MISMATCH, connman);
177+ ConsumeCollateral (connman, entry.txCollateral );
177178 return ;
178179 }
179180
180- if (entry.vecTxOut .size () > PRIVATESEND_ENTRY_MAX_SIZE) {
181- LogPrintf (" DSVIN -- ERROR: too many outputs ! %d/%d\n " , entry.vecTxOut .size (), PRIVATESEND_ENTRY_MAX_SIZE);
181+ if (entry.vecTxDSIn .size () > PRIVATESEND_ENTRY_MAX_SIZE) {
182+ LogPrintf (" DSVIN -- ERROR: too many inputs ! %d/%d\n " , entry.vecTxDSIn .size (), PRIVATESEND_ENTRY_MAX_SIZE);
182183 PushStatus (pfrom, STATUS_REJECTED, ERR_MAXIMUM, connman);
184+ ConsumeCollateral (connman, entry.txCollateral );
183185 return ;
184186 }
185187
@@ -204,11 +206,13 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm
204206 if (txout.scriptPubKey .size () != 25 ) {
205207 LogPrintf (" DSVIN -- non-standard pubkey detected! scriptPubKey=%s\n " , ScriptToAsmStr (txout.scriptPubKey ));
206208 PushStatus (pfrom, STATUS_REJECTED, ERR_NON_STANDARD_PUBKEY, connman);
209+ ConsumeCollateral (connman, entry.txCollateral );
207210 return ;
208211 }
209212 if (!txout.scriptPubKey .IsPayToPublicKeyHash ()) {
210213 LogPrintf (" DSVIN -- invalid script! scriptPubKey=%s\n " , ScriptToAsmStr (txout.scriptPubKey ));
211214 PushStatus (pfrom, STATUS_REJECTED, ERR_INVALID_SCRIPT, connman);
215+ ConsumeCollateral (connman, entry.txCollateral );
212216 return ;
213217 }
214218 }
@@ -226,8 +230,20 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm
226230 PushStatus (pfrom, STATUS_REJECTED, ERR_MISSING_TX, connman);
227231 return ;
228232 }
233+ if (!CPrivateSend::IsDenominatedAmount (mempoolTx->vout [txin.prevout .n ].nValue )) {
234+ LogPrintf (" DSVIN -- non-denominated mempool input! txin=%s\n " , txin.ToString ());
235+ PushStatus (pfrom, STATUS_REJECTED, ERR_DENOM, connman);
236+ ConsumeCollateral (connman, entry.txCollateral );
237+ return ;
238+ }
229239 nValueIn += mempoolTx->vout [txin.prevout .n ].nValue ;
230240 } else if (GetUTXOCoin (txin.prevout , coin)) {
241+ if (!CPrivateSend::IsDenominatedAmount (coin.out .nValue )) {
242+ LogPrintf (" DSVIN -- non-denominated input! txin=%s\n " , txin.ToString ());
243+ PushStatus (pfrom, STATUS_REJECTED, ERR_DENOM, connman);
244+ ConsumeCollateral (connman, entry.txCollateral );
245+ return ;
246+ }
231247 nValueIn += coin.out .nValue ;
232248 } else {
233249 LogPrintf (" DSVIN -- missing input! txin=%s\n " , txin.ToString ());
@@ -456,16 +472,7 @@ void CPrivateSendServer::ChargeFees(CConnman& connman)
456472 if (nState == POOL_STATE_ACCEPTING_ENTRIES || nState == POOL_STATE_SIGNING) {
457473 LogPrintf (" CPrivateSendServer::ChargeFees -- found uncooperative node (didn't %s transaction), charging fees: %s" ,
458474 (nState == POOL_STATE_SIGNING) ? " sign" : " send" , vecOffendersCollaterals[0 ]->ToString ());
459-
460- LOCK (cs_main);
461-
462- CValidationState state;
463- if (!AcceptToMemoryPool (mempool, state, vecOffendersCollaterals[0 ], false , NULL , false , maxTxFee)) {
464- // should never really happen
465- LogPrintf (" CPrivateSendServer::ChargeFees -- ERROR: AcceptToMemoryPool failed!\n " );
466- } else {
467- connman.RelayTransaction (*vecOffendersCollaterals[0 ]);
468- }
475+ ConsumeCollateral (connman, vecOffendersCollaterals[0 ]);
469476 }
470477}
471478
@@ -485,19 +492,22 @@ void CPrivateSendServer::ChargeRandomFees(CConnman& connman)
485492{
486493 if (!fMasternodeMode ) return ;
487494
488- LOCK (cs_main);
489-
490495 for (const auto & txCollateral : vecSessionCollaterals) {
491496 if (GetRandInt (100 ) > 10 ) return ;
492497 LogPrintf (" CPrivateSendServer::ChargeRandomFees -- charging random fees, txCollateral=%s" , txCollateral->ToString ());
498+ ConsumeCollateral (connman, txCollateral);
499+ }
500+ }
493501
494- CValidationState state;
495- if (!AcceptToMemoryPool (mempool, state, txCollateral, false , NULL , false , maxTxFee)) {
496- // Can happen if this collateral belongs to some misbehaving participant we punished earlier
497- LogPrintf (" CPrivateSendServer::ChargeRandomFees -- ERROR: AcceptToMemoryPool failed!\n " );
498- } else {
499- connman.RelayTransaction (*txCollateral);
500- }
502+ void CPrivateSendServer::ConsumeCollateral (CConnman& connman, const CTransactionRef& txref)
503+ {
504+ LOCK (cs_main);
505+ CValidationState validationState;
506+ if (!AcceptToMemoryPool (mempool, validationState, txref, false , nullptr )) {
507+ LogPrint (BCLog::PRIVATESEND, " %s -- AcceptToMemoryPool failed\n " , __func__);
508+ } else {
509+ connman.RelayTransaction (*txref);
510+ LogPrint (BCLog::PRIVATESEND, " %s -- Collateral was consumed\n " , __func__);
501511 }
502512}
503513
0 commit comments