void CClientMgr::Run() { idmgr_run(m_IDPool); AcceptNewClient(); ProcessAllClient(); CheckAndRemove(); }
bool CInstantSend::ResolveConflicts(const CTxLockCandidate& txLockCandidate) { LOCK2(cs_main, cs_instantsend); uint256 txHash = txLockCandidate.GetHash(); // make sure the lock is ready if(!txLockCandidate.IsAllOutPointsReady()) return false; AssertLockHeld(mempool.cs); // protect mempool.mapNextTx for (const auto& txin : txLockCandidate.txLockRequest.tx->vin) { uint256 hashConflicting; if(GetLockedOutPointTxHash(txin.prevout, hashConflicting) && txHash != hashConflicting) { // completed lock which conflicts with another completed one? // this means that majority of MNs in the quorum for this specific tx input are malicious! std::map<uint256, CTxLockCandidate>::iterator itLockCandidate = mapTxLockCandidates.find(txHash); std::map<uint256, CTxLockCandidate>::iterator itLockCandidateConflicting = mapTxLockCandidates.find(hashConflicting); if(itLockCandidate == mapTxLockCandidates.end() || itLockCandidateConflicting == mapTxLockCandidates.end()) { // safety check, should never really happen LogPrintf("CInstantSend::ResolveConflicts -- ERROR: Found conflicting completed Transaction Lock, but one of txLockCandidate-s is missing, txid=%s, conflicting txid=%s\n", txHash.ToString(), hashConflicting.ToString()); return false; } LogPrintf("CInstantSend::ResolveConflicts -- WARNING: Found conflicting completed Transaction Lock, dropping both, txid=%s, conflicting txid=%s\n", txHash.ToString(), hashConflicting.ToString()); CTxLockRequest txLockRequest = itLockCandidate->second.txLockRequest; CTxLockRequest txLockRequestConflicting = itLockCandidateConflicting->second.txLockRequest; itLockCandidate->second.SetConfirmedHeight(0); // expired itLockCandidateConflicting->second.SetConfirmedHeight(0); // expired CheckAndRemove(); // clean up // AlreadyHave should still return "true" for both of them mapLockRequestRejected.insert(std::make_pair(txHash, txLockRequest)); mapLockRequestRejected.insert(std::make_pair(hashConflicting, txLockRequestConflicting)); // TODO: clean up mapLockRequestRejected later somehow // (not a big issue since we already PoSe ban malicious masternodes // and they won't be able to spam) // TODO: ban all malicious masternodes permanently, do not accept anything from them, ever // TODO: notify zmq+script about this double-spend attempt // and let merchant cancel/hold the order if it's not too late... // can't do anything else, fallback to regular txes return false; } else if (mempool.mapNextTx.count(txin.prevout)) { // check if it's in mempool hashConflicting = mempool.mapNextTx.find(txin.prevout)->second->GetHash(); if(txHash == hashConflicting) continue; // matches current, not a conflict, skip to next txin // conflicts with tx in mempool LogPrintf("CInstantSend::ResolveConflicts -- ERROR: Failed to complete Transaction Lock, conflicts with mempool, txid=%s\n", txHash.ToString()); return false; } } // FOREACH // No conflicts were found so far, check to see if it was already included in block CTransactionRef txTmp; uint256 hashBlock; if(GetTransaction(txHash, txTmp, Params().GetConsensus(), hashBlock, true) && hashBlock != uint256()) { LogPrint("instantsend", "CInstantSend::ResolveConflicts -- Done, %s is included in block %s\n", txHash.ToString(), hashBlock.ToString()); return true; } // Not in block yet, make sure all its inputs are still unspent for (const auto& txin : txLockCandidate.txLockRequest.tx->vin) { Coin coin; if(!GetUTXOCoin(txin.prevout, coin)) { // Not in UTXO anymore? A conflicting tx was mined while we were waiting for votes. LogPrintf("CInstantSend::ResolveConflicts -- ERROR: Failed to find UTXO %s, can't complete Transaction Lock\n", txin.prevout.ToStringShort()); return false; } } LogPrint("instantsend", "CInstantSend::ResolveConflicts -- Done, txid=%s\n", txHash.ToString()); return true; }
void Gogame::AddStone(unsigned int color, unsigned int x, unsigned int y, bool ismove, int nodeid) { // Add a stone of a color at (x, y) // may either be play or setup // if x or y is out-of-bounds, this is regarded as 'pass' move // // ismove indicates whether this is a move or setup // if setup, the movenumber does not increase // ismove flag indicates if this play is a move or setup // Rcpp::Rcout << "add stone: " << // "(" << color << "," << x << "," << // y << "," << ismove << "," << nodeid << ") "; // check validity of color if (color != BL && color != WH && color != EM) { Rcpp::Rcout << "at nodeid " << nodeid << " "; Rcpp::stop("invalid color"); } if (ismove && color == EM) { Rcpp::Rcout << "at nodeid " << nodeid << " "; Rcpp::stop("empty stone is invalid for moves"); } // check if the stone can be put there if (!IsLegal(x, y, color, ismove)) { Summary(); Rcpp::Rcout << "at nodeid " << nodeid << ", tries to play: (x, y, color, ismove) = (" << x << ", " << y << ", " << color << ", " << (int)ismove << ")\n"; Rcpp::stop("illegal move"); } // update current node member field currentnode = nodeid; // case for setup move if (!ismove) { // if this is a setup move, then add stone at the point and // no need to check the liberty. // but do nothing if the x or y is out of bounds because // you cannot add stone there! if (x >= 1 && y >= 1 && (int)x <= boardsize && (int)y <= boardsize) { // if a stone is already there, then you need to first remove the stone if (board[y][x] == BL || board[y][x] == WH) { transitions.push_back(Transition(movenumber, x, y, -board[y][x], currentnode, false)); board[y][x] = EM; } // if this new stone is colored, add that stone if (color == BL || color == WH) { board[y][x] = color; transitions.push_back(Transition(movenumber, x, y, color, currentnode, false)); } } return; } // reaching here means it is a move movenumber++; // coordinates out of bounds are regarded as pass, // append transition, but do nothing afterwards // x = y = 0 means this move is a pass if (x < 1 || y < 1 || (int)x > boardsize || (int)y > boardsize) { transitions.push_back(Transition(movenumber, 0, 0, color, currentnode, true)); return; } // put the stone temporarily board[y][x] = color; // and record it in the transitions field transitions.push_back(Transition(movenumber, x, y, color, currentnode, true)); // enter four adjacent points to the checklist // if they are opponent color unsigned int opponent_color; if (color == BL) { opponent_color = WH; } else { opponent_color = BL; } // check if any opponent stone becomes captured due to this play // loop over the four adjacent point unsigned int xx; unsigned int yy; int increment; for (int k = 0; k < 4; k++) { increment = 2*(k % 2) - 1; if (k < 2) { xx = x + increment; yy = y; } else { xx = x; yy = y + increment; } // if this is a opponent stone, // check the liberty of this point, // and if it does not have a liberty, // remove all stones connected to it if (board[yy][xx] == opponent_color) CheckAndRemove(xx, yy); } }