mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 20:12:57 +01:00
Refac: misc coinjoin refactoring and spelling / grammar fixes (#4304)
* refactor: misc coinjoin refactoring * fix spelling / grammar recommendations in coinjoin
This commit is contained in:
parent
f14e8eeada
commit
f65b789f9a
@ -87,7 +87,7 @@ void CCoinJoinClientQueueManager::ProcessMessage(CNode* pfrom, const std::string
|
||||
|
||||
// if the queue is ready, submit if we can
|
||||
if (dsq.fReady) {
|
||||
for (auto& pair : coinJoinClientManagers) {
|
||||
for (const auto& pair : coinJoinClientManagers) {
|
||||
if (pair.second->TrySubmitDenominate(dmn->pdmnState->addr, connman)) {
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- CoinJoin queue (%s) is ready on masternode %s\n", dsq.ToString(), dmn->pdmnState->addr.ToString());
|
||||
return;
|
||||
@ -304,7 +304,7 @@ void CCoinJoinClientSession::UnlockCoins()
|
||||
vecOutPointLocked.clear();
|
||||
}
|
||||
|
||||
std::string CCoinJoinClientSession::GetStatus(bool fWaitForBlock)
|
||||
std::string CCoinJoinClientSession::GetStatus(bool fWaitForBlock) const
|
||||
{
|
||||
static int nStatusMessageProgress = 0;
|
||||
nStatusMessageProgress += 10;
|
||||
@ -350,7 +350,7 @@ std::string CCoinJoinClientManager::GetStatuses()
|
||||
std::string strStatus;
|
||||
bool fWaitForBlock = WaitForAnotherBlock();
|
||||
|
||||
for (auto& session : deqSessions) {
|
||||
for (const auto& session : deqSessions) {
|
||||
strStatus += session.GetStatus(fWaitForBlock) + "; ";
|
||||
}
|
||||
return strStatus;
|
||||
@ -361,7 +361,7 @@ std::string CCoinJoinClientManager::GetSessionDenoms()
|
||||
LOCK(cs_deqsessions);
|
||||
std::string strSessionDenoms;
|
||||
|
||||
for (auto& session : deqSessions) {
|
||||
for (const auto& session : deqSessions) {
|
||||
strSessionDenoms += CCoinJoin::DenominationToString(session.nSessionDenom) + "; ";
|
||||
}
|
||||
return strSessionDenoms.empty() ? "N/A" : strSessionDenoms;
|
||||
@ -636,7 +636,7 @@ bool CCoinJoinClientSession::SignFinalTransaction(const CTransaction& finalTrans
|
||||
// TODO we're using amount=0 here but we should use the correct amount. This works because Dash ignores the amount while signing/verifying (only used in Bitcoin/Segwit)
|
||||
if (!SignSignature(mixingWallet, prevPubKey, finalMutableTransaction, nMyInputIndex, 0, int(SIGHASH_ALL | SIGHASH_ANYONECANPAY))) { // changes scriptSig
|
||||
LogPrint(BCLog::COINJOIN, "CCoinJoinClientSession::%s -- Unable to sign my own transaction!\n", __func__);
|
||||
// not sure what to do here, it will timeout...?
|
||||
// not sure what to do here, it will time out...?
|
||||
}
|
||||
|
||||
sigs.push_back(finalMutableTransaction.vin[nMyInputIndex]);
|
||||
@ -710,14 +710,14 @@ bool CCoinJoinClientManager::CheckAutomaticBackup()
|
||||
return false;
|
||||
case -1:
|
||||
// Automatic backup failed, nothing else we can do until user fixes the issue manually.
|
||||
// There is no way to bring user attention in daemon mode so we just update status and
|
||||
// There is no way to bring user attention in daemon mode, so we just update status and
|
||||
// keep spamming if debug is on.
|
||||
LogPrint(BCLog::COINJOIN, "CCoinJoinClientManager::CheckAutomaticBackup -- ERROR! Failed to create automatic backup.\n");
|
||||
strAutoDenomResult = _("ERROR! Failed to create automatic backup") + ", " + _("see debug.log for details.");
|
||||
return false;
|
||||
case -2:
|
||||
// We were able to create automatic backup but keypool was not replenished because wallet is locked.
|
||||
// There is no way to bring user attention in daemon mode so we just update status and
|
||||
// There is no way to bring user attention in daemon mode, so we just update status and
|
||||
// keep spamming if debug is on.
|
||||
LogPrint(BCLog::COINJOIN, "CCoinJoinClientManager::CheckAutomaticBackup -- WARNING! Failed to create replenish keypool, please unlock your wallet to do so.\n");
|
||||
strAutoDenomResult = _("WARNING! Failed to replenish keypool, please unlock your wallet to do so.") + ", " + _("see debug.log for details.");
|
||||
@ -732,7 +732,7 @@ bool CCoinJoinClientManager::CheckAutomaticBackup()
|
||||
StopMixing();
|
||||
return false;
|
||||
} else if (mixingWallet.nKeysLeftSinceAutoBackup < COINJOIN_KEYS_THRESHOLD_WARNING) {
|
||||
// Low number of keys left but it's still more or less safe to continue
|
||||
// Low number of keys left, but it's still more or less safe to continue
|
||||
LogPrint(BCLog::COINJOIN, "CCoinJoinClientManager::CheckAutomaticBackup -- Very low number of keys left: %d\n", mixingWallet.nKeysLeftSinceAutoBackup);
|
||||
strAutoDenomResult = strprintf(_("Very low number of keys left: %d"), mixingWallet.nKeysLeftSinceAutoBackup);
|
||||
|
||||
@ -1002,18 +1002,18 @@ CDeterministicMNCPtr CCoinJoinClientManager::GetRandomNotUsedMasternode()
|
||||
{
|
||||
auto mnList = deterministicMNManager->GetListAtChainTip();
|
||||
|
||||
int nCountEnabled = mnList.GetValidMNsCount();
|
||||
int nCountNotExcluded = nCountEnabled - vecMasternodesUsed.size();
|
||||
size_t nCountEnabled = mnList.GetValidMNsCount();
|
||||
size_t nCountNotExcluded = nCountEnabled - vecMasternodesUsed.size();
|
||||
|
||||
LogPrint(BCLog::COINJOIN, "CCoinJoinClientManager::%s -- %d enabled masternodes, %d masternodes to choose from\n", __func__, nCountEnabled, nCountNotExcluded);
|
||||
if(nCountNotExcluded < 1) {
|
||||
if (nCountNotExcluded < 1) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// fill a vector
|
||||
std::vector<CDeterministicMNCPtr> vpMasternodesShuffled;
|
||||
vpMasternodesShuffled.reserve((size_t)nCountEnabled);
|
||||
mnList.ForEachMN(true, [&](const CDeterministicMNCPtr& dmn) {
|
||||
vpMasternodesShuffled.reserve(nCountEnabled);
|
||||
mnList.ForEachMN(true, [&vpMasternodesShuffled](const CDeterministicMNCPtr& dmn) {
|
||||
vpMasternodesShuffled.emplace_back(dmn);
|
||||
});
|
||||
|
||||
@ -1179,7 +1179,7 @@ bool CCoinJoinClientSession::ProcessPendingDsaRequest(CConnman& connman)
|
||||
{
|
||||
if (!pendingDsaRequest) return false;
|
||||
|
||||
bool fDone = connman.ForNode(pendingDsaRequest.GetAddr(), [&](CNode* pnode) {
|
||||
bool fDone = connman.ForNode(pendingDsaRequest.GetAddr(), [this, &connman](CNode* pnode) {
|
||||
LogPrint(BCLog::COINJOIN, "-- processing dsa queue for addr=%s\n", pnode->addr.ToString());
|
||||
nTimeLastSuccessfulStep = GetTime();
|
||||
// TODO: this vvvv should be here after new state POOL_STATE_CONNECTING is added and MIN_COINJOIN_PEER_PROTO_VERSION is bumped
|
||||
@ -1260,7 +1260,7 @@ bool CCoinJoinClientSession::SubmitDenominate(CConnman& connman)
|
||||
}
|
||||
}
|
||||
|
||||
// more inputs first, for equal input count prefer the one with less rounds
|
||||
// more inputs first, for equal input count prefer the one with fewer rounds
|
||||
std::sort(vecInputsByRounds.begin(), vecInputsByRounds.end(), [](const auto& a, const auto& b) {
|
||||
return a.second > b.second || (a.second == b.second && a.first < b.first);
|
||||
});
|
||||
@ -1384,9 +1384,9 @@ bool CCoinJoinClientSession::MakeCollateralAmounts()
|
||||
LOCK2(cs_main, mempool.cs);
|
||||
LOCK(mixingWallet.cs_wallet);
|
||||
|
||||
// NOTE: We do not allow txes larger than 100kB, so we have to limit number of inputs here.
|
||||
// NOTE: We do not allow txes larger than 100 kB, so we have to limit number of inputs here.
|
||||
// We still want to consume a lot of inputs to avoid creating only smaller denoms though.
|
||||
// Knowing that each CTxIn is at least 148b big, 400 inputs should take 400 x ~148b = ~60kB.
|
||||
// Knowing that each CTxIn is at least 148 B big, 400 inputs should take 400 x ~148 B = ~60 kB.
|
||||
// This still leaves more than enough room for another data of typical MakeCollateralAmounts tx.
|
||||
std::vector<CompactTallyItem> vecTally;
|
||||
if (!mixingWallet.SelectCoinsGroupedByAddresses(vecTally, false, false, true, 400)) {
|
||||
@ -1394,7 +1394,7 @@ bool CCoinJoinClientSession::MakeCollateralAmounts()
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start from smallest balances first to consume tiny amounts and cleanup UTXO a bit
|
||||
// Start from the smallest balances first to consume tiny amounts and cleanup UTXO a bit
|
||||
std::sort(vecTally.begin(), vecTally.end(), [](const CompactTallyItem& a, const CompactTallyItem& b) {
|
||||
return a.nAmount < b.nAmount;
|
||||
});
|
||||
@ -1546,10 +1546,10 @@ bool CCoinJoinClientSession::CreateCollateralTransaction(CMutableTransaction& tx
|
||||
scriptChange = GetScriptForDestination(vchPubKey.GetID());
|
||||
reservekey.KeepKey();
|
||||
// return change
|
||||
txCollateral.vout.push_back(CTxOut(txout.nValue - CCoinJoin::GetCollateralAmount(), scriptChange));
|
||||
txCollateral.vout.emplace_back(txout.nValue - CCoinJoin::GetCollateralAmount(), scriptChange);
|
||||
} else { // txout.nValue < CCoinJoin::GetCollateralAmount() * 2
|
||||
// create dummy data output only and pay everything as a fee
|
||||
txCollateral.vout.push_back(CTxOut(0, CScript() << OP_RETURN));
|
||||
txCollateral.vout.emplace_back(0, CScript() << OP_RETURN);
|
||||
}
|
||||
|
||||
if (!SignSignature(mixingWallet, txout.scriptPubKey, txCollateral, 0, txout.nValue, SIGHASH_ALL)) {
|
||||
@ -1568,9 +1568,9 @@ bool CCoinJoinClientSession::CreateDenominated(CAmount nBalanceToDenominate)
|
||||
LOCK2(cs_main, mempool.cs);
|
||||
LOCK(mixingWallet.cs_wallet);
|
||||
|
||||
// NOTE: We do not allow txes larger than 100kB, so we have to limit number of inputs here.
|
||||
// NOTE: We do not allow txes larger than 100 kB, so we have to limit number of inputs here.
|
||||
// We still want to consume a lot of inputs to avoid creating only smaller denoms though.
|
||||
// Knowing that each CTxIn is at least 148b big, 400 inputs should take 400 x ~148b = ~60kB.
|
||||
// Knowing that each CTxIn is at least 148 B big, 400 inputs should take 400 x ~148 B = ~60 kB.
|
||||
// This still leaves more than enough room for another data of typical CreateDenominated tx.
|
||||
std::vector<CompactTallyItem> vecTally;
|
||||
if (!mixingWallet.SelectCoinsGroupedByAddresses(vecTally, true, true, true, 400)) {
|
||||
@ -1578,7 +1578,7 @@ bool CCoinJoinClientSession::CreateDenominated(CAmount nBalanceToDenominate)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Start from largest balances first to speed things up by creating txes with larger/largest denoms included
|
||||
// Start from the largest balances first to speed things up by creating txes with larger/largest denoms included
|
||||
std::sort(vecTally.begin(), vecTally.end(), [](const CompactTallyItem& a, const CompactTallyItem& b) {
|
||||
return a.nAmount > b.nAmount;
|
||||
});
|
||||
@ -1713,10 +1713,10 @@ bool CCoinJoinClientSession::CreateDenominated(CAmount nBalanceToDenominate, con
|
||||
auto countPossibleOutputs = [&](CAmount nAmount) -> int {
|
||||
std::vector<CAmount> vecOutputs;
|
||||
while (true) {
|
||||
// Create an potential output
|
||||
// Create a potential output
|
||||
vecOutputs.push_back(nAmount);
|
||||
if (!txBuilder.CouldAddOutputs(vecOutputs) || txBuilder.CountOutputs() + vecOutputs.size() > COINJOIN_DENOM_OUTPUTS_THRESHOLD) {
|
||||
// If its not possible to add it due to insufficient amount left or total number of outputs exceeds
|
||||
// If it's not possible to add it due to insufficient amount left or total number of outputs exceeds
|
||||
// COINJOIN_DENOM_OUTPUTS_THRESHOLD drop the output again and stop trying.
|
||||
vecOutputs.pop_back();
|
||||
break;
|
||||
@ -1735,7 +1735,7 @@ bool CCoinJoinClientSession::CreateDenominated(CAmount nBalanceToDenominate, con
|
||||
// accurate approximation by many smaller denoms. This is ok because when we get here we
|
||||
// should have nCoinJoinDenomsGoal of each smaller denom already. Also, without `+1`
|
||||
// we can end up in a situation when there is already nCoinJoinDenomsHardCap of smaller
|
||||
// denoms yet we can't mix the remaining nBalanceToDenominate because it's smaller than
|
||||
// denoms, yet we can't mix the remaining nBalanceToDenominate because it's smaller than
|
||||
// nDenomValue (and thus denomsToCreateBal == 0), so the target would never get reached
|
||||
// even when there is enough funds for that.
|
||||
int denomsToCreateBal = (nBalanceToDenominate / nDenomValue) + 1;
|
||||
@ -1790,7 +1790,7 @@ bool CCoinJoinClientSession::CreateDenominated(CAmount nBalanceToDenominate, con
|
||||
return true;
|
||||
}
|
||||
|
||||
void CCoinJoinClientSession::RelayIn(const CCoinJoinEntry& entry, CConnman& connman)
|
||||
void CCoinJoinClientSession::RelayIn(const CCoinJoinEntry& entry, CConnman& connman) const
|
||||
{
|
||||
if (!mixingMasternode) return;
|
||||
|
||||
@ -1877,7 +1877,7 @@ void CCoinJoinClientManager::GetJsonInfo(UniValue& obj) const
|
||||
void DoCoinJoinMaintenance(CConnman& connman)
|
||||
{
|
||||
coinJoinClientQueueManager.DoMaintenance();
|
||||
for (auto& pair : coinJoinClientManagers) {
|
||||
for (const auto& pair : coinJoinClientManagers) {
|
||||
pair.second->DoMaintenance(connman);
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <coinjoin/coinjoin-util.h>
|
||||
#include <coinjoin/coinjoin.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
class CDeterministicMN;
|
||||
typedef std::shared_ptr<const CDeterministicMN> CDeterministicMNCPtr;
|
||||
|
||||
@ -43,15 +45,15 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
CPendingDsaRequest(const CService& addr_, const CCoinJoinAccept& dsa_) :
|
||||
addr(addr_),
|
||||
dsa(dsa_),
|
||||
CPendingDsaRequest(CService addr_, CCoinJoinAccept dsa_) :
|
||||
addr(std::move(addr_)),
|
||||
dsa(std::move(dsa_)),
|
||||
nTimeCreated(GetTime())
|
||||
{
|
||||
}
|
||||
|
||||
CService GetAddr() { return addr; }
|
||||
CCoinJoinAccept GetDSA() { return dsa; }
|
||||
CService GetAddr() const { return addr; }
|
||||
CCoinJoinAccept GetDSA() const { return dsa; }
|
||||
bool IsExpired() const { return GetTime() - nTimeCreated > TIMEOUT; }
|
||||
|
||||
friend bool operator==(const CPendingDsaRequest& a, const CPendingDsaRequest& b)
|
||||
@ -114,12 +116,12 @@ private:
|
||||
/// As a client, check and sign the final transaction
|
||||
bool SignFinalTransaction(const CTransaction& finalTransactionNew, CNode* pnode, CConnman& connman);
|
||||
|
||||
void RelayIn(const CCoinJoinEntry& entry, CConnman& connman);
|
||||
void RelayIn(const CCoinJoinEntry& entry, CConnman& connman) const;
|
||||
|
||||
void SetNull();
|
||||
|
||||
public:
|
||||
CCoinJoinClientSession(CWallet& pwallet) :
|
||||
explicit CCoinJoinClientSession(CWallet& pwallet) :
|
||||
vecOutPointLocked(),
|
||||
strLastMessage(),
|
||||
strAutoDenomResult(),
|
||||
@ -137,7 +139,7 @@ public:
|
||||
|
||||
void ResetPool();
|
||||
|
||||
std::string GetStatus(bool fWaitForBlock);
|
||||
std::string GetStatus(bool fWaitForBlock) const;
|
||||
|
||||
bool GetMixingMasternodeInfo(CDeterministicMNCPtr& ret) const;
|
||||
|
||||
@ -169,10 +171,6 @@ public:
|
||||
class CCoinJoinClientManager
|
||||
{
|
||||
private:
|
||||
CCoinJoinClientManager() = delete;
|
||||
CCoinJoinClientManager(CCoinJoinClientManager const&) = delete;
|
||||
CCoinJoinClientManager& operator=(CCoinJoinClientManager const&) = delete;
|
||||
|
||||
// Keep track of the used Masternodes
|
||||
std::vector<COutPoint> vecMasternodesUsed;
|
||||
|
||||
@ -183,7 +181,7 @@ private:
|
||||
bool fMixing{false};
|
||||
|
||||
int nCachedLastSuccessBlock;
|
||||
int nMinBlocksToWait; // how many blocks to wait after one successful mixing tx in non-multisession mode
|
||||
int nMinBlocksToWait; // how many blocks to wait for after one successful mixing tx in non-multisession mode
|
||||
std::string strAutoDenomResult;
|
||||
|
||||
CWallet& mixingWallet;
|
||||
@ -200,7 +198,11 @@ public:
|
||||
int nCachedNumBlocks; // used for the overview screen
|
||||
bool fCreateAutoBackups; // builtin support for automatic backups
|
||||
|
||||
CCoinJoinClientManager(CWallet& wallet) :
|
||||
CCoinJoinClientManager() = delete;
|
||||
CCoinJoinClientManager(CCoinJoinClientManager const&) = delete;
|
||||
CCoinJoinClientManager& operator=(CCoinJoinClientManager const&) = delete;
|
||||
|
||||
explicit CCoinJoinClientManager(CWallet& wallet) :
|
||||
vecMasternodesUsed(),
|
||||
deqSessions(),
|
||||
nCachedLastSuccessBlock(0),
|
||||
|
@ -20,8 +20,6 @@
|
||||
#include <validation.h>
|
||||
#include <version.h>
|
||||
|
||||
#include <llmq/quorums_instantsend.h>
|
||||
|
||||
#include <univalue.h>
|
||||
|
||||
CCoinJoinServer coinJoinServer;
|
||||
@ -32,208 +30,228 @@ void CCoinJoinServer::ProcessMessage(CNode* pfrom, const std::string& strCommand
|
||||
if (!masternodeSync.IsBlockchainSynced()) return;
|
||||
|
||||
if (strCommand == NetMsgType::DSACCEPT) {
|
||||
if (pfrom->nVersion < MIN_COINJOIN_PEER_PROTO_VERSION) {
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- peer=%d using obsolete version %i\n", pfrom->GetId(), pfrom->nVersion);
|
||||
if (enable_bip61) {
|
||||
connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand,
|
||||
REJECT_OBSOLETE, strprintf(
|
||||
"Version must be %d or greater", MIN_COINJOIN_PEER_PROTO_VERSION)));
|
||||
}
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_VERSION, connman);
|
||||
return;
|
||||
}
|
||||
|
||||
if (IsSessionReady()) {
|
||||
// too many users in this session already, reject new ones
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- queue is already full!\n");
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_QUEUE_FULL, connman);
|
||||
return;
|
||||
}
|
||||
|
||||
CCoinJoinAccept dsa;
|
||||
vRecv >> dsa;
|
||||
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- nDenom %d (%s) txCollateral %s", dsa.nDenom, CCoinJoin::DenominationToString(dsa.nDenom), dsa.txCollateral.ToString()); /* Continued */
|
||||
|
||||
auto mnList = deterministicMNManager->GetListAtChainTip();
|
||||
auto dmn = WITH_LOCK(activeMasternodeInfoCs, return mnList.GetValidMNByCollateral(activeMasternodeInfo.outpoint));
|
||||
if (!dmn) {
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_MN_LIST, connman);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vecSessionCollaterals.empty()) {
|
||||
{
|
||||
TRY_LOCK(cs_vecqueue, lockRecv);
|
||||
if (!lockRecv) return;
|
||||
|
||||
for (const auto& q : vecCoinJoinQueue) {
|
||||
if (WITH_LOCK(activeMasternodeInfoCs, return q.masternodeOutpoint == activeMasternodeInfo.outpoint)) {
|
||||
// refuse to create another queue this often
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- last dsq is still in queue, refuse to mix\n");
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_RECENT, connman);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int64_t nLastDsq = mmetaman.GetMetaInfo(dmn->proTxHash)->GetLastDsq();
|
||||
int64_t nDsqThreshold = mmetaman.GetDsqThreshold(dmn->proTxHash, mnList.GetValidMNsCount());
|
||||
if (nLastDsq != 0 && nDsqThreshold > mmetaman.GetDsqCount()) {
|
||||
if (fLogIPs) {
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- last dsq too recent, must wait: peer=%d, addr=%s\n", pfrom->GetId(), pfrom->addr.ToString());
|
||||
} else {
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- last dsq too recent, must wait: peer=%d\n", pfrom->GetId());
|
||||
}
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_RECENT, connman);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PoolMessage nMessageID = MSG_NOERR;
|
||||
|
||||
bool fResult = nSessionID == 0 ? CreateNewSession(dsa, nMessageID, connman)
|
||||
: AddUserToExistingSession(dsa, nMessageID);
|
||||
if (fResult) {
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- is compatible, please submit!\n");
|
||||
PushStatus(pfrom, STATUS_ACCEPTED, nMessageID, connman);
|
||||
return;
|
||||
} else {
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- not compatible with existing transactions!\n");
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID, connman);
|
||||
return;
|
||||
}
|
||||
|
||||
ProcessDSACCEPT(pfrom, strCommand, vRecv, connman, enable_bip61);
|
||||
return;
|
||||
} else if (strCommand == NetMsgType::DSQUEUE) {
|
||||
if (pfrom->nVersion < MIN_COINJOIN_PEER_PROTO_VERSION) {
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- peer=%d using obsolete version %i\n", pfrom->GetId(), pfrom->nVersion);
|
||||
if (enable_bip61) {
|
||||
connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand,
|
||||
REJECT_OBSOLETE, strprintf(
|
||||
ProcessDSQUEUE(pfrom, strCommand, vRecv, connman, enable_bip61);
|
||||
return;
|
||||
} else if (strCommand == NetMsgType::DSVIN) {
|
||||
ProcessDSVIN(pfrom, strCommand, vRecv, connman, enable_bip61);
|
||||
return;
|
||||
} else if (strCommand == NetMsgType::DSSIGNFINALTX) {
|
||||
ProcessDSSIGNFINALTX(pfrom, strCommand, vRecv, connman, enable_bip61);
|
||||
}
|
||||
}
|
||||
|
||||
void CCoinJoinServer::ProcessDSACCEPT(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman, bool enable_bip61)
|
||||
{
|
||||
if (pfrom->nVersion < MIN_COINJOIN_PEER_PROTO_VERSION) {
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- peer=%d using obsolete version %i\n", pfrom->GetId(), pfrom->nVersion);
|
||||
if (enable_bip61) {
|
||||
connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand,
|
||||
REJECT_OBSOLETE, strprintf(
|
||||
"Version must be %d or greater", MIN_COINJOIN_PEER_PROTO_VERSION)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_VERSION, connman);
|
||||
return;
|
||||
}
|
||||
|
||||
CCoinJoinQueue dsq;
|
||||
vRecv >> dsq;
|
||||
if (IsSessionReady()) {
|
||||
// too many users in this session already, reject new ones
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- queue is already full!\n");
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_QUEUE_FULL, connman);
|
||||
return;
|
||||
}
|
||||
|
||||
CCoinJoinAccept dsa;
|
||||
vRecv >> dsa;
|
||||
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- nDenom %d (%s) txCollateral %s", dsa.nDenom, CCoinJoin::DenominationToString(dsa.nDenom), dsa.txCollateral.ToString()); /* Continued */
|
||||
|
||||
auto mnList = deterministicMNManager->GetListAtChainTip();
|
||||
auto dmn = WITH_LOCK(activeMasternodeInfoCs, return mnList.GetValidMNByCollateral(activeMasternodeInfo.outpoint));
|
||||
if (!dmn) {
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_MN_LIST, connman);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vecSessionCollaterals.empty()) {
|
||||
{
|
||||
TRY_LOCK(cs_vecqueue, lockRecv);
|
||||
if (!lockRecv) return;
|
||||
|
||||
// process every dsq only once
|
||||
for (const auto& q : vecCoinJoinQueue) {
|
||||
if (q == dsq) {
|
||||
return;
|
||||
}
|
||||
if (q.fReady == dsq.fReady && q.masternodeOutpoint == dsq.masternodeOutpoint) {
|
||||
// no way the same mn can send another dsq with the same readiness this soon
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- Peer %s is sending WAY too many dsq messages for a masternode with collateral %s\n", pfrom->GetLogString(), dsq.masternodeOutpoint.ToStringShort());
|
||||
if (WITH_LOCK(activeMasternodeInfoCs, return q.masternodeOutpoint == activeMasternodeInfo.outpoint)) {
|
||||
// refuse to create another queue this often
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- last dsq is still in queue, refuse to mix\n");
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_RECENT, connman);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // cs_vecqueue
|
||||
}
|
||||
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- %s new\n", dsq.ToString());
|
||||
|
||||
if (dsq.IsTimeOutOfBounds()) return;
|
||||
|
||||
auto mnList = deterministicMNManager->GetListAtChainTip();
|
||||
auto dmn = mnList.GetValidMNByCollateral(dsq.masternodeOutpoint);
|
||||
if (!dmn) return;
|
||||
|
||||
if (!dsq.CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) {
|
||||
LOCK(cs_main);
|
||||
Misbehaving(pfrom->GetId(), 10);
|
||||
int64_t nLastDsq = mmetaman.GetMetaInfo(dmn->proTxHash)->GetLastDsq();
|
||||
int64_t nDsqThreshold = mmetaman.GetDsqThreshold(dmn->proTxHash, mnList.GetValidMNsCount());
|
||||
if (nLastDsq != 0 && nDsqThreshold > mmetaman.GetDsqCount()) {
|
||||
if (fLogIPs) {
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- last dsq too recent, must wait: peer=%d, addr=%s\n", pfrom->GetId(), pfrom->addr.ToString());
|
||||
} else {
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- last dsq too recent, must wait: peer=%d\n", pfrom->GetId());
|
||||
}
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_RECENT, connman);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dsq.fReady) {
|
||||
int64_t nLastDsq = mmetaman.GetMetaInfo(dmn->proTxHash)->GetLastDsq();
|
||||
int64_t nDsqThreshold = mmetaman.GetDsqThreshold(dmn->proTxHash, mnList.GetValidMNsCount());
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- nLastDsq: %d nDsqThreshold: %d nDsqCount: %d\n", nLastDsq, nDsqThreshold, mmetaman.GetDsqCount());
|
||||
//don't allow a few nodes to dominate the queuing process
|
||||
if (nLastDsq != 0 && nDsqThreshold > mmetaman.GetDsqCount()) {
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- Masternode %s is sending too many dsq messages\n", dmn->pdmnState->addr.ToString());
|
||||
return;
|
||||
}
|
||||
mmetaman.AllowMixing(dmn->proTxHash);
|
||||
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- new CoinJoin queue (%s) from masternode %s\n", dsq.ToString(), dmn->pdmnState->addr.ToString());
|
||||
|
||||
TRY_LOCK(cs_vecqueue, lockRecv);
|
||||
if (!lockRecv) return;
|
||||
vecCoinJoinQueue.push_back(dsq);
|
||||
dsq.Relay(connman);
|
||||
}
|
||||
|
||||
} else if (strCommand == NetMsgType::DSVIN) {
|
||||
if (pfrom->nVersion < MIN_COINJOIN_PEER_PROTO_VERSION) {
|
||||
LogPrint(BCLog::COINJOIN, "DSVIN -- peer=%d using obsolete version %i\n", pfrom->GetId(), pfrom->nVersion);
|
||||
if (enable_bip61) {
|
||||
connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand,
|
||||
REJECT_OBSOLETE, strprintf(
|
||||
"Version must be %d or greater", MIN_COINJOIN_PEER_PROTO_VERSION)));
|
||||
}
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_VERSION, connman);
|
||||
return;
|
||||
}
|
||||
|
||||
//do we have enough users in the current session?
|
||||
if (!IsSessionReady()) {
|
||||
LogPrint(BCLog::COINJOIN, "DSVIN -- session not complete!\n");
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_SESSION, connman);
|
||||
return;
|
||||
}
|
||||
|
||||
CCoinJoinEntry entry;
|
||||
vRecv >> entry;
|
||||
|
||||
LogPrint(BCLog::COINJOIN, "DSVIN -- txCollateral %s", entry.txCollateral->ToString()); /* Continued */
|
||||
|
||||
PoolMessage nMessageID = MSG_NOERR;
|
||||
|
||||
entry.addr = pfrom->addr;
|
||||
if (AddEntry(connman, entry, nMessageID)) {
|
||||
PushStatus(pfrom, STATUS_ACCEPTED, nMessageID, connman);
|
||||
CheckPool(connman);
|
||||
RelayStatus(STATUS_ACCEPTED, connman);
|
||||
} else {
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID, connman);
|
||||
}
|
||||
|
||||
} else if (strCommand == NetMsgType::DSSIGNFINALTX) {
|
||||
if (pfrom->nVersion < MIN_COINJOIN_PEER_PROTO_VERSION) {
|
||||
LogPrint(BCLog::COINJOIN, "DSSIGNFINALTX -- peer=%d using obsolete version %i\n", pfrom->GetId(), pfrom->nVersion);
|
||||
if (enable_bip61) {
|
||||
connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand,
|
||||
REJECT_OBSOLETE, strprintf(
|
||||
"Version must be %d or greater", MIN_COINJOIN_PEER_PROTO_VERSION)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<CTxIn> vecTxIn;
|
||||
vRecv >> vecTxIn;
|
||||
|
||||
LogPrint(BCLog::COINJOIN, "DSSIGNFINALTX -- vecTxIn.size() %s\n", vecTxIn.size());
|
||||
|
||||
int nTxInIndex = 0;
|
||||
int nTxInsCount = (int)vecTxIn.size();
|
||||
|
||||
for (const auto& txin : vecTxIn) {
|
||||
nTxInIndex++;
|
||||
if (!AddScriptSig(txin)) {
|
||||
LogPrint(BCLog::COINJOIN, "DSSIGNFINALTX -- AddScriptSig() failed at %d/%d, session: %d\n", nTxInIndex, nTxInsCount, nSessionID);
|
||||
RelayStatus(STATUS_REJECTED, connman);
|
||||
return;
|
||||
}
|
||||
LogPrint(BCLog::COINJOIN, "DSSIGNFINALTX -- AddScriptSig() %d/%d success\n", nTxInIndex, nTxInsCount);
|
||||
}
|
||||
// all is good
|
||||
CheckPool(connman);
|
||||
}
|
||||
|
||||
PoolMessage nMessageID = MSG_NOERR;
|
||||
|
||||
bool fResult = nSessionID == 0 ? CreateNewSession(dsa, nMessageID, connman)
|
||||
: AddUserToExistingSession(dsa, nMessageID);
|
||||
if (fResult) {
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- is compatible, please submit!\n");
|
||||
PushStatus(pfrom, STATUS_ACCEPTED, nMessageID, connman);
|
||||
return;
|
||||
} else {
|
||||
LogPrint(BCLog::COINJOIN, "DSACCEPT -- not compatible with existing transactions!\n");
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID, connman);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void CCoinJoinServer::ProcessDSQUEUE(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman, bool enable_bip61)
|
||||
{
|
||||
if (pfrom->nVersion < MIN_COINJOIN_PEER_PROTO_VERSION) {
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- peer=%d using obsolete version %i\n", pfrom->GetId(), pfrom->nVersion);
|
||||
if (enable_bip61) {
|
||||
connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand,
|
||||
REJECT_OBSOLETE, strprintf(
|
||||
"Version must be %d or greater", MIN_COINJOIN_PEER_PROTO_VERSION)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
CCoinJoinQueue dsq;
|
||||
vRecv >> dsq;
|
||||
|
||||
{
|
||||
TRY_LOCK(cs_vecqueue, lockRecv);
|
||||
if (!lockRecv) return;
|
||||
|
||||
// process every dsq only once
|
||||
for (const auto& q : vecCoinJoinQueue) {
|
||||
if (q == dsq) {
|
||||
return;
|
||||
}
|
||||
if (q.fReady == dsq.fReady && q.masternodeOutpoint == dsq.masternodeOutpoint) {
|
||||
// no way the same mn can send another dsq with the same readiness this soon
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- Peer %s is sending WAY too many dsq messages for a masternode with collateral %s\n", pfrom->GetLogString(), dsq.masternodeOutpoint.ToStringShort());
|
||||
return;
|
||||
}
|
||||
}
|
||||
} // cs_vecqueue
|
||||
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- %s new\n", dsq.ToString());
|
||||
|
||||
if (dsq.IsTimeOutOfBounds()) return;
|
||||
|
||||
auto mnList = deterministicMNManager->GetListAtChainTip();
|
||||
auto dmn = mnList.GetValidMNByCollateral(dsq.masternodeOutpoint);
|
||||
if (!dmn) return;
|
||||
|
||||
if (!dsq.CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) {
|
||||
LOCK(cs_main);
|
||||
Misbehaving(pfrom->GetId(), 10);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dsq.fReady) {
|
||||
int64_t nLastDsq = mmetaman.GetMetaInfo(dmn->proTxHash)->GetLastDsq();
|
||||
int64_t nDsqThreshold = mmetaman.GetDsqThreshold(dmn->proTxHash, mnList.GetValidMNsCount());
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- nLastDsq: %d nDsqThreshold: %d nDsqCount: %d\n", nLastDsq, nDsqThreshold, mmetaman.GetDsqCount());
|
||||
//don't allow a few nodes to dominate the queuing process
|
||||
if (nLastDsq != 0 && nDsqThreshold > mmetaman.GetDsqCount()) {
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- Masternode %s is sending too many dsq messages\n", dmn->pdmnState->addr.ToString());
|
||||
return;
|
||||
}
|
||||
mmetaman.AllowMixing(dmn->proTxHash);
|
||||
|
||||
LogPrint(BCLog::COINJOIN, "DSQUEUE -- new CoinJoin queue (%s) from masternode %s\n", dsq.ToString(), dmn->pdmnState->addr.ToString());
|
||||
|
||||
TRY_LOCK(cs_vecqueue, lockRecv);
|
||||
if (!lockRecv) return;
|
||||
vecCoinJoinQueue.push_back(dsq);
|
||||
dsq.Relay(connman);
|
||||
}
|
||||
}
|
||||
|
||||
void CCoinJoinServer::ProcessDSVIN(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman, bool enable_bip61)
|
||||
{
|
||||
if (pfrom->nVersion < MIN_COINJOIN_PEER_PROTO_VERSION) {
|
||||
LogPrint(BCLog::COINJOIN, "DSVIN -- peer=%d using obsolete version %i\n", pfrom->GetId(), pfrom->nVersion);
|
||||
if (enable_bip61) {
|
||||
connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand,
|
||||
REJECT_OBSOLETE, strprintf(
|
||||
"Version must be %d or greater", MIN_COINJOIN_PEER_PROTO_VERSION)));
|
||||
}
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_VERSION, connman);
|
||||
return;
|
||||
}
|
||||
|
||||
//do we have enough users in the current session?
|
||||
if (!IsSessionReady()) {
|
||||
LogPrint(BCLog::COINJOIN, "DSVIN -- session not complete!\n");
|
||||
PushStatus(pfrom, STATUS_REJECTED, ERR_SESSION, connman);
|
||||
return;
|
||||
}
|
||||
|
||||
CCoinJoinEntry entry;
|
||||
vRecv >> entry;
|
||||
|
||||
LogPrint(BCLog::COINJOIN, "DSVIN -- txCollateral %s", entry.txCollateral->ToString()); /* Continued */
|
||||
|
||||
PoolMessage nMessageID = MSG_NOERR;
|
||||
|
||||
entry.addr = pfrom->addr;
|
||||
if (AddEntry(connman, entry, nMessageID)) {
|
||||
PushStatus(pfrom, STATUS_ACCEPTED, nMessageID, connman);
|
||||
CheckPool(connman);
|
||||
RelayStatus(STATUS_ACCEPTED, connman);
|
||||
} else {
|
||||
PushStatus(pfrom, STATUS_REJECTED, nMessageID, connman);
|
||||
}
|
||||
}
|
||||
|
||||
void CCoinJoinServer::ProcessDSSIGNFINALTX(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman, bool enable_bip61)
|
||||
{
|
||||
if (pfrom->nVersion < MIN_COINJOIN_PEER_PROTO_VERSION) {
|
||||
LogPrint(BCLog::COINJOIN, "DSSIGNFINALTX -- peer=%d using obsolete version %i\n", pfrom->GetId(), pfrom->nVersion);
|
||||
if (enable_bip61) {
|
||||
connman.PushMessage(pfrom, CNetMsgMaker(pfrom->GetSendVersion()).Make(NetMsgType::REJECT, strCommand,
|
||||
REJECT_OBSOLETE, strprintf(
|
||||
"Version must be %d or greater", MIN_COINJOIN_PEER_PROTO_VERSION)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<CTxIn> vecTxIn;
|
||||
vRecv >> vecTxIn;
|
||||
|
||||
LogPrint(BCLog::COINJOIN, "DSSIGNFINALTX -- vecTxIn.size() %s\n", vecTxIn.size());
|
||||
|
||||
int nTxInIndex = 0;
|
||||
int nTxInsCount = (int)vecTxIn.size();
|
||||
|
||||
for (const auto& txin : vecTxIn) {
|
||||
nTxInIndex++;
|
||||
if (!AddScriptSig(txin)) {
|
||||
LogPrint(BCLog::COINJOIN, "DSSIGNFINALTX -- AddScriptSig() failed at %d/%d, session: %d\n", nTxInIndex, nTxInsCount, nSessionID);
|
||||
RelayStatus(STATUS_REJECTED, connman);
|
||||
return;
|
||||
}
|
||||
LogPrint(BCLog::COINJOIN, "DSSIGNFINALTX -- AddScriptSig() %d/%d success\n", nTxInIndex, nTxInsCount);
|
||||
}
|
||||
// all is good
|
||||
CheckPool(connman);
|
||||
}
|
||||
|
||||
void CCoinJoinServer::SetNull()
|
||||
@ -272,7 +290,7 @@ void CCoinJoinServer::CheckPool(CConnman& connman)
|
||||
return;
|
||||
}
|
||||
|
||||
// If we have all of the signatures, try to compile the transaction
|
||||
// If we have all the signatures, try to compile the transaction
|
||||
if (nState == POOL_STATE_SIGNING && IsSignaturesComplete()) {
|
||||
LogPrint(BCLog::COINJOIN, "CCoinJoinServer::CheckPool -- SIGNING\n");
|
||||
CommitFinalTransaction(connman);
|
||||
@ -360,14 +378,14 @@ void CCoinJoinServer::CommitFinalTransaction(CConnman& connman)
|
||||
//
|
||||
// Why bother? CoinJoin uses collateral to ensure abuse to the process is kept to a minimum.
|
||||
// The submission and signing stages are completely separate. In the cases where
|
||||
// a client submits a transaction then refused to sign, there must be a cost. Otherwise they
|
||||
// a client submits a transaction then refused to sign, there must be a cost. Otherwise, they
|
||||
// would be able to do this over and over again and bring the mixing to a halt.
|
||||
//
|
||||
// How does this work? Messages to Masternodes come in via NetMsgType::DSVIN, these require a valid collateral
|
||||
// transaction for the client to be able to enter the pool. This transaction is kept by the Masternode
|
||||
// until the transaction is either complete or fails.
|
||||
//
|
||||
void CCoinJoinServer::ChargeFees(CConnman& connman)
|
||||
void CCoinJoinServer::ChargeFees(CConnman& connman) const
|
||||
{
|
||||
if (!fMasternodeMode) return;
|
||||
|
||||
@ -432,12 +450,12 @@ void CCoinJoinServer::ChargeFees(CConnman& connman)
|
||||
Collateral Fee Charges:
|
||||
|
||||
Being that mixing has "no fees" we need to have some kind of cost associated
|
||||
with using it to stop abuse. Otherwise it could serve as an attack vector and
|
||||
with using it to stop abuse. Otherwise, it could serve as an attack vector and
|
||||
allow endless transaction that would bloat Dash and make it unusable. To
|
||||
stop these kinds of attacks 1 in 10 successful transactions are charged. This
|
||||
adds up to a cost of 0.001DRK per transaction on average.
|
||||
*/
|
||||
void CCoinJoinServer::ChargeRandomFees(CConnman& connman)
|
||||
void CCoinJoinServer::ChargeRandomFees(CConnman& connman) const
|
||||
{
|
||||
if (!fMasternodeMode) return;
|
||||
|
||||
@ -448,7 +466,7 @@ void CCoinJoinServer::ChargeRandomFees(CConnman& connman)
|
||||
}
|
||||
}
|
||||
|
||||
void CCoinJoinServer::ConsumeCollateral(CConnman& connman, const CTransactionRef& txref)
|
||||
void CCoinJoinServer::ConsumeCollateral(CConnman& connman, const CTransactionRef& txref) const
|
||||
{
|
||||
LOCK(cs_main);
|
||||
CValidationState validationState;
|
||||
@ -460,7 +478,7 @@ void CCoinJoinServer::ConsumeCollateral(CConnman& connman, const CTransactionRef
|
||||
}
|
||||
}
|
||||
|
||||
bool CCoinJoinServer::HasTimedOut()
|
||||
bool CCoinJoinServer::HasTimedOut() const
|
||||
{
|
||||
if (!fMasternodeMode) return false;
|
||||
|
||||
@ -510,7 +528,7 @@ void CCoinJoinServer::CheckForCompleteQueue(CConnman& connman)
|
||||
}
|
||||
|
||||
// Check to make sure a given input matches an input in the pool and its scriptSig is valid
|
||||
bool CCoinJoinServer::IsInputScriptSigValid(const CTxIn& txin)
|
||||
bool CCoinJoinServer::IsInputScriptSigValid(const CTxIn& txin) const
|
||||
{
|
||||
CMutableTransaction txNew;
|
||||
txNew.vin.clear();
|
||||
@ -652,7 +670,7 @@ bool CCoinJoinServer::AddScriptSig(const CTxIn& txinNew)
|
||||
}
|
||||
|
||||
// Check to make sure everything is signed
|
||||
bool CCoinJoinServer::IsSignaturesComplete()
|
||||
bool CCoinJoinServer::IsSignaturesComplete() const
|
||||
{
|
||||
for (const auto& entry : vecEntries) {
|
||||
for (const auto& txdsin : entry.vecTxDSIn) {
|
||||
@ -663,7 +681,7 @@ bool CCoinJoinServer::IsSignaturesComplete()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CCoinJoinServer::IsAcceptableDSA(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet)
|
||||
bool CCoinJoinServer::IsAcceptableDSA(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet) const
|
||||
{
|
||||
if (!fMasternodeMode) return false;
|
||||
|
||||
@ -756,7 +774,7 @@ bool CCoinJoinServer::AddUserToExistingSession(const CCoinJoinAccept& dsa, PoolM
|
||||
}
|
||||
|
||||
// Returns true if either max size has been reached or if the mix timed out and min size was reached
|
||||
bool CCoinJoinServer::IsSessionReady()
|
||||
bool CCoinJoinServer::IsSessionReady() const
|
||||
{
|
||||
if (nState == POOL_STATE_QUEUE) {
|
||||
if ((int)vecSessionCollaterals.size() >= CCoinJoin::GetMaxPoolParticipants()) {
|
||||
@ -792,7 +810,7 @@ void CCoinJoinServer::RelayFinalTransaction(const CTransaction& txFinal, CConnma
|
||||
}
|
||||
}
|
||||
|
||||
void CCoinJoinServer::PushStatus(CNode* pnode, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID, CConnman& connman)
|
||||
void CCoinJoinServer::PushStatus(CNode* pnode, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID, CConnman& connman) const
|
||||
{
|
||||
if (!pnode) return;
|
||||
CCoinJoinStatusUpdate psssup(nSessionID, nState, 0, nStatusUpdate, nMessageID);
|
||||
@ -869,7 +887,7 @@ void CCoinJoinServer::SetState(PoolState nStateNew)
|
||||
nState = nStateNew;
|
||||
}
|
||||
|
||||
void CCoinJoinServer::DoMaintenance(CConnman& connman)
|
||||
void CCoinJoinServer::DoMaintenance(CConnman& connman) const
|
||||
{
|
||||
if (!fMasternodeMode) return; // only run on masternodes
|
||||
|
||||
|
@ -31,11 +31,11 @@ private:
|
||||
bool AddScriptSig(const CTxIn& txin);
|
||||
|
||||
/// Charge fees to bad actors (Charge clients a fee if they're abusive)
|
||||
void ChargeFees(CConnman& connman);
|
||||
void ChargeFees(CConnman& connman) const;
|
||||
/// Rarely charge fees to pay miners
|
||||
void ChargeRandomFees(CConnman& connman);
|
||||
void ChargeRandomFees(CConnman& connman) const;
|
||||
/// Consume collateral in cases when peer misbehaved
|
||||
void ConsumeCollateral(CConnman& connman, const CTransactionRef& txref);
|
||||
void ConsumeCollateral(CConnman& connman, const CTransactionRef& txref) const;
|
||||
|
||||
/// Check for process
|
||||
void CheckPool(CConnman& connman);
|
||||
@ -44,26 +44,31 @@ private:
|
||||
void CommitFinalTransaction(CConnman& connman);
|
||||
|
||||
/// Is this nDenom and txCollateral acceptable?
|
||||
bool IsAcceptableDSA(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet);
|
||||
bool IsAcceptableDSA(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet) const;
|
||||
bool CreateNewSession(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet, CConnman& connman);
|
||||
bool AddUserToExistingSession(const CCoinJoinAccept& dsa, PoolMessage& nMessageIDRet);
|
||||
/// Do we have enough users to take entries?
|
||||
bool IsSessionReady();
|
||||
bool IsSessionReady() const;
|
||||
|
||||
/// Check that all inputs are signed. (Are all inputs signed?)
|
||||
bool IsSignaturesComplete();
|
||||
bool IsSignaturesComplete() const;
|
||||
/// Check to make sure a given input matches an input in the pool and its scriptSig is valid
|
||||
bool IsInputScriptSigValid(const CTxIn& txin);
|
||||
bool IsInputScriptSigValid(const CTxIn& txin) const;
|
||||
|
||||
// Set the 'state' value, with some logging and capturing when the state changed
|
||||
void SetState(PoolState nStateNew);
|
||||
|
||||
/// Relay mixing Messages
|
||||
void RelayFinalTransaction(const CTransaction& txFinal, CConnman& connman);
|
||||
void PushStatus(CNode* pnode, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID, CConnman& connman);
|
||||
void PushStatus(CNode* pnode, PoolStatusUpdate nStatusUpdate, PoolMessage nMessageID, CConnman& connman) const;
|
||||
void RelayStatus(PoolStatusUpdate nStatusUpdate, CConnman& connman, PoolMessage nMessageID = MSG_NOERR);
|
||||
void RelayCompletedTransaction(PoolMessage nMessageID, CConnman& connman);
|
||||
|
||||
void ProcessDSACCEPT(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman, bool enable_bip61);
|
||||
void ProcessDSQUEUE(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman, bool enable_bip61);
|
||||
void ProcessDSVIN(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman, bool enable_bip61);
|
||||
void ProcessDSSIGNFINALTX(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman, bool enable_bip61);
|
||||
|
||||
void SetNull();
|
||||
|
||||
public:
|
||||
@ -73,11 +78,11 @@ public:
|
||||
|
||||
void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman, bool enable_bip61);
|
||||
|
||||
bool HasTimedOut();
|
||||
bool HasTimedOut() const;
|
||||
void CheckTimeout(CConnman& connman);
|
||||
void CheckForCompleteQueue(CConnman& connman);
|
||||
|
||||
void DoMaintenance(CConnman& connman);
|
||||
void DoMaintenance(CConnman& connman) const;
|
||||
|
||||
void GetJsonInfo(UniValue& obj) const;
|
||||
};
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include <chain.h>
|
||||
#include <messagesigner.h>
|
||||
#include <netmessagemaker.h>
|
||||
#include <script/sign.h>
|
||||
#include <txmempool.h>
|
||||
#include <util/system.h>
|
||||
#include <util/moneystr.h>
|
||||
@ -119,7 +118,7 @@ bool CCoinJoinBroadcastTx::IsExpired(const CBlockIndex* pindex) const
|
||||
{
|
||||
// expire confirmed DSTXes after ~1h since confirmation or chainlocked confirmation
|
||||
if (nConfirmedHeight == -1 || pindex->nHeight < nConfirmedHeight) return false; // not mined yet
|
||||
if (pindex->nHeight - nConfirmedHeight > 24) return true; // mined more then an hour ago
|
||||
if (pindex->nHeight - nConfirmedHeight > 24) return true; // mined more than an hour ago
|
||||
return llmq::chainLocksHandler->HasChainLock(pindex->nHeight, *pindex->phashBlock);
|
||||
}
|
||||
|
||||
@ -251,7 +250,7 @@ bool CCoinJoinBaseSession::IsValidInOuts(const std::vector<CTxIn>& vin, const st
|
||||
return false;
|
||||
}
|
||||
// IsPayToPublicKeyHash() above already checks for scriptPubKey size,
|
||||
// no need to double check, hence no usage of ERR_NON_STANDARD_PUBKEY
|
||||
// no need to double-check, hence no usage of ERR_NON_STANDARD_PUBKEY
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -292,7 +291,7 @@ bool CCoinJoinBaseSession::IsValidInOuts(const std::vector<CTxIn>& vin, const st
|
||||
}
|
||||
|
||||
// The same size and denom for inputs and outputs ensures their total value is also the same,
|
||||
// no need to double check. If not, we are doing something wrong, bail out.
|
||||
// no need to double-check. If not, we are doing something wrong, bail out.
|
||||
if (nFees != 0) {
|
||||
LogPrint(BCLog::COINJOIN, "CCoinJoinBaseSession::%s -- ERROR: non-zero fees! fees: %lld\n", __func__, nFees);
|
||||
nMessageIDRet = ERR_FEES;
|
||||
|
@ -11,6 +11,8 @@
|
||||
#include <timedata.h>
|
||||
#include <tinyformat.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
class CCoinJoin;
|
||||
class CConnman;
|
||||
class CBLSPublicKey;
|
||||
@ -116,9 +118,9 @@ public:
|
||||
bool fHasSig; // flag to indicate if signed
|
||||
int nRounds;
|
||||
|
||||
CTxDSIn(const CTxIn& txin, const CScript& script, int nRounds) :
|
||||
CTxDSIn(const CTxIn& txin, CScript script, int nRounds) :
|
||||
CTxIn(txin),
|
||||
prevPubKey(script),
|
||||
prevPubKey(std::move(script)),
|
||||
fHasSig(false),
|
||||
nRounds(nRounds)
|
||||
{
|
||||
@ -143,9 +145,9 @@ public:
|
||||
nDenom(0),
|
||||
txCollateral(CMutableTransaction()){};
|
||||
|
||||
CCoinJoinAccept(int nDenom, const CMutableTransaction& txCollateral) :
|
||||
CCoinJoinAccept(int nDenom, CMutableTransaction txCollateral) :
|
||||
nDenom(nDenom),
|
||||
txCollateral(txCollateral){};
|
||||
txCollateral(std::move(txCollateral)){};
|
||||
|
||||
SERIALIZE_METHODS(CCoinJoinAccept, obj)
|
||||
{
|
||||
@ -176,9 +178,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
CCoinJoinEntry(const std::vector<CTxDSIn>& vecTxDSIn, const std::vector<CTxOut>& vecTxOut, const CTransaction& txCollateral) :
|
||||
vecTxDSIn(vecTxDSIn),
|
||||
vecTxOut(vecTxOut),
|
||||
CCoinJoinEntry(std::vector<CTxDSIn> vecTxDSIn, std::vector<CTxOut> vecTxOut, const CTransaction& txCollateral) :
|
||||
vecTxDSIn(std::move(vecTxDSIn)),
|
||||
vecTxOut(std::move(vecTxOut)),
|
||||
txCollateral(MakeTransactionRef(txCollateral)),
|
||||
addr(CService())
|
||||
{
|
||||
@ -217,7 +219,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
CCoinJoinQueue(int nDenom, COutPoint outpoint, int64_t nTime, bool fReady) :
|
||||
CCoinJoinQueue(int nDenom, const COutPoint& outpoint, int64_t nTime, bool fReady) :
|
||||
nDenom(nDenom),
|
||||
masternodeOutpoint(outpoint),
|
||||
nTime(nTime),
|
||||
@ -288,9 +290,9 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
CCoinJoinBroadcastTx(const CTransactionRef& _tx, COutPoint _outpoint, int64_t _sigTime) :
|
||||
CCoinJoinBroadcastTx(CTransactionRef _tx, const COutPoint& _outpoint, int64_t _sigTime) :
|
||||
nConfirmedHeight(-1),
|
||||
tx(_tx),
|
||||
tx(std::move(_tx)),
|
||||
masternodeOutpoint(_outpoint),
|
||||
vchSig(),
|
||||
sigTime(_sigTime)
|
||||
|
Loading…
Reference in New Issue
Block a user