Skip to content

Commit

Permalink
[PrivateSend] Fallback to less participants if possible, fix too long…
Browse files Browse the repository at this point in the history
… timeouts on server side (#2616)

* Fallback to less participants on timeouts if possible

* Only bump nTimeLastSuccessfulStep when state is changed

* Consistency: always set state first before relaying smth to clients
  • Loading branch information
UdjinM6 committed Jan 15, 2019
1 parent ee808d8 commit 8e4fe36
Showing 1 changed file with 29 additions and 10 deletions.
39 changes: 29 additions & 10 deletions src/privatesend-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,6 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm
RelayStatus(STATUS_ACCEPTED, connman);
} else {
PushStatus(pfrom, STATUS_REJECTED, nMessageID, connman);
SetNull();
}

} else if (strCommand == NetMsgType::DSSIGNFINALTX) {
Expand Down Expand Up @@ -332,8 +331,8 @@ void CPrivateSendServer::CreateFinalTransaction(CConnman& connman)
LogPrint("privatesend", "CPrivateSendServer::CreateFinalTransaction -- finalMutableTransaction=%s", txNew.ToString());

// request signatures from clients
RelayFinalTransaction(finalMutableTransaction, connman);
SetState(POOL_STATE_SIGNING);
RelayFinalTransaction(finalMutableTransaction, connman);
}

void CPrivateSendServer::CommitFinalTransaction(CConnman& connman)
Expand Down Expand Up @@ -484,7 +483,7 @@ void CPrivateSendServer::ChargeRandomFees(CConnman& connman)

CValidationState state;
if (!AcceptToMemoryPool(mempool, state, txCollateral, false, NULL, false, maxTxFee)) {
// should never really happen
// Can happen if this collateral belongs to some misbehaving participant we punished earlier
LogPrintf("CPrivateSendServer::ChargeRandomFees -- ERROR: AcceptToMemoryPool failed!\n");
} else {
connman.RelayTransaction(*txCollateral);
Expand All @@ -498,18 +497,40 @@ void CPrivateSendServer::ChargeRandomFees(CConnman& connman)
void CPrivateSendServer::CheckTimeout(CConnman& connman)
{
if (!fMasternodeMode) return;
if (nState == POOL_STATE_IDLE) return;

CheckQueue();

int nTimeout = (nState == POOL_STATE_SIGNING) ? PRIVATESEND_SIGNING_TIMEOUT : PRIVATESEND_QUEUE_TIMEOUT;
bool fTimeout = GetTime() - nTimeLastSuccessfulStep >= nTimeout;

if (nState != POOL_STATE_IDLE && fTimeout) {
LogPrint("privatesend", "CPrivateSendServer::CheckTimeout -- %s timed out (%ds) -- resetting\n",
(nState == POOL_STATE_SIGNING) ? "Signing" : "Session", nTimeout);
// Too early to do anything
if (!fTimeout) return;

// See if we have at least min number of participants, if so - we can still do smth
if (nState == POOL_STATE_QUEUE && vecSessionCollaterals.size() >= CPrivateSend::GetMinPoolParticipants()) {
LogPrint("privatesend", "CPrivateSendServer::CheckTimeout -- Queue for %d participants timed out (%ds) -- falling back to %d participants\n",
nSessionMaxParticipants, nTimeout, vecSessionCollaterals.size());
nSessionMaxParticipants = vecSessionCollaterals.size();
return;
}

if (nState == POOL_STATE_ACCEPTING_ENTRIES && GetEntriesCount() >= CPrivateSend::GetMinPoolParticipants()) {
LogPrint("privatesend", "CPrivateSendServer::CheckTimeout -- Accepting entries for %d participants timed out (%ds) -- falling back to %d participants\n",
nSessionMaxParticipants, nTimeout, GetEntriesCount());
// Punish misbehaving participants
ChargeFees(connman);
SetNull();
// Try to complete this session ignoring the misbehaving ones
nSessionMaxParticipants = GetEntriesCount();
CheckPool(connman);
return;
}

// All other cases
LogPrint("privatesend", "CPrivateSendServer::CheckTimeout -- %s timed out (%ds) -- resetting\n",
(nState == POOL_STATE_SIGNING) ? "Signing" : "Session", nTimeout);
ChargeFees(connman);
SetNull();
}

/*
Expand Down Expand Up @@ -617,7 +638,6 @@ bool CPrivateSendServer::AddEntry(const CPrivateSendEntry& entryNew, PoolMessage

LogPrint("privatesend", "CPrivateSendServer::AddEntry -- adding entry %d of %d required\n", GetEntriesCount(), nSessionMaxParticipants);
nMessageIDRet = MSG_ENTRIES_ADDED;
nTimeLastSuccessfulStep = GetTime();

return true;
}
Expand Down Expand Up @@ -726,7 +746,6 @@ bool CPrivateSendServer::CreateNewSession(const CPrivateSendAccept& dsa, PoolMes
nSessionMaxParticipants = CPrivateSend::GetMinPoolParticipants() + GetRandInt(CPrivateSend::GetMaxPoolParticipants() - CPrivateSend::GetMinPoolParticipants() + 1);

SetState(POOL_STATE_QUEUE);
nTimeLastSuccessfulStep = GetTime();

if (!fUnitTest) {
//broadcast that I'm accepting entries, only if it's the first entry through
Expand Down Expand Up @@ -769,7 +788,6 @@ bool CPrivateSendServer::AddUserToExistingSession(const CPrivateSendAccept& dsa,
// count new user as accepted to an existing session

nMessageIDRet = MSG_NOERR;
nTimeLastSuccessfulStep = GetTime();
vecSessionCollaterals.push_back(MakeTransactionRef(dsa.txCollateral));

LogPrintf("CPrivateSendServer::AddUserToExistingSession -- new user accepted, nSessionID: %d nSessionDenom: %d (%s) vecSessionCollaterals.size(): %d nSessionMaxParticipants: %d\n",
Expand Down Expand Up @@ -876,6 +894,7 @@ void CPrivateSendServer::SetState(PoolState nStateNew)
}

LogPrintf("CPrivateSendServer::SetState -- nState: %d, nStateNew: %d\n", nState, nStateNew);
nTimeLastSuccessfulStep = GetTime();
nState = nStateNew;
}

Expand Down

0 comments on commit 8e4fe36

Please sign in to comment.