mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 12:02:48 +01:00
Revert "fix - ds can leak info by number of inputs"
This reverts commit f98fe6a208
.
This commit is contained in:
parent
277ebbe83d
commit
aaeda811db
111
src/darksend.cpp
111
src/darksend.cpp
@ -67,22 +67,8 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
|
||||
}
|
||||
|
||||
int nDenom;
|
||||
int nNumberOfInputs;
|
||||
CTransaction txCollateral;
|
||||
vRecv >> nDenom >> nNumberOfInputs >> txCollateral;
|
||||
|
||||
//non-denom's are incompatible
|
||||
if((nDenom & (1 << 4))) {
|
||||
errorID = ERR_INVALID_DENOM;
|
||||
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, errorID);
|
||||
return;
|
||||
}
|
||||
|
||||
if(nNumberOfInputs < DARKSEND_MIN_INPUTS || nNumberOfInputs > DARKSEND_MAX_INPUTS) {
|
||||
errorID = ERR_INVALID_INPUTS_NUMBER;
|
||||
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, errorID);
|
||||
return;
|
||||
}
|
||||
vRecv >> nDenom >> txCollateral;
|
||||
|
||||
CMasternode* pmn = mnodeman.Find(activeMasternode.vin);
|
||||
if(pmn == NULL)
|
||||
@ -102,13 +88,13 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
|
||||
}
|
||||
}
|
||||
|
||||
if(!IsCompatibleWithSession(nDenom, nNumberOfInputs, txCollateral, errorID))
|
||||
if(!IsCompatibleWithSession(nDenom, txCollateral, errorID))
|
||||
{
|
||||
LogPrintf("dsa -- not compatible with existing transactions!\n");
|
||||
LogPrintf("dsa -- not compatible with existing transactions! \n");
|
||||
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, errorID);
|
||||
return;
|
||||
} else {
|
||||
LogPrintf("dsa -- is compatible, please submit!\n");
|
||||
LogPrintf("dsa -- is compatible, please submit! \n");
|
||||
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_ACCEPTED, errorID);
|
||||
return;
|
||||
}
|
||||
@ -124,15 +110,6 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
|
||||
CDarksendQueue dsq;
|
||||
vRecv >> dsq;
|
||||
|
||||
//non-denom's are incompatible
|
||||
if((dsq.nDenom & (1 << 4))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(dsq.nNumberOfInputs < DARKSEND_MIN_INPUTS || dsq.nNumberOfInputs > DARKSEND_MAX_INPUTS) {
|
||||
return;
|
||||
}
|
||||
|
||||
CService addr;
|
||||
if(!dsq.GetAddress(addr)) return;
|
||||
if(!dsq.CheckSignature()) return;
|
||||
@ -196,16 +173,10 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
|
||||
}
|
||||
|
||||
std::vector<CTxIn> in;
|
||||
int64_t nAmount;
|
||||
CTransaction txCollateral;
|
||||
std::vector<CTxOut> out;
|
||||
vRecv >> in >> txCollateral >> out;
|
||||
|
||||
if((int)in.size() != sessionNumberOfInputs || (int)out.size() != sessionNumberOfInputs) {
|
||||
errorID = ERR_INVALID_INPUTS_NUMBER;
|
||||
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_REJECTED, errorID);
|
||||
return;
|
||||
}
|
||||
|
||||
vRecv >> in >> nAmount >> txCollateral >> out;
|
||||
|
||||
//do we have enough users in the current session?
|
||||
if(!IsSessionReady()){
|
||||
@ -299,7 +270,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
|
||||
}
|
||||
}
|
||||
|
||||
if(AddEntry(in, txCollateral, out, errorID)){
|
||||
if(AddEntry(in, nAmount, txCollateral, out, errorID)){
|
||||
pfrom->PushMessage("dssu", sessionID, GetState(), GetEntriesCount(), MASTERNODE_ACCEPTED, errorID);
|
||||
Check();
|
||||
|
||||
@ -915,7 +886,6 @@ void CDarksendPool::CheckForCompleteQueue(){
|
||||
|
||||
CDarksendQueue dsq;
|
||||
dsq.nDenom = sessionDenom;
|
||||
dsq.nNumberOfInputs = sessionNumberOfInputs;
|
||||
dsq.vin = activeMasternode.vin;
|
||||
dsq.time = GetTime();
|
||||
dsq.ready = true;
|
||||
@ -1022,11 +992,11 @@ bool CDarksendPool::IsCollateralValid(const CTransaction& txCollateral){
|
||||
//
|
||||
// Add a clients transaction to the pool
|
||||
//
|
||||
bool CDarksendPool::AddEntry(const std::vector<CTxIn>& newInput, const CTransaction& txCollateral, const std::vector<CTxOut>& newOutput, int& errorID){
|
||||
bool CDarksendPool::AddEntry(const std::vector<CTxIn>& newInput, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxOut>& newOutput, int& errorID){
|
||||
if (!fMasterNode) return false;
|
||||
|
||||
BOOST_FOREACH(CTxIn in, newInput) {
|
||||
if (in.prevout.IsNull()) {
|
||||
if (in.prevout.IsNull() || nAmount < 0) {
|
||||
LogPrint("darksend", "CDarksendPool::AddEntry - input not valid!\n");
|
||||
errorID = ERR_INVALID_INPUT;
|
||||
sessionUsers--;
|
||||
@ -1063,7 +1033,7 @@ bool CDarksendPool::AddEntry(const std::vector<CTxIn>& newInput, const CTransact
|
||||
}
|
||||
|
||||
CDarkSendEntry v;
|
||||
v.Add(newInput, txCollateral, newOutput);
|
||||
v.Add(newInput, nAmount, txCollateral, newOutput);
|
||||
entries.push_back(v);
|
||||
|
||||
LogPrint("darksend", "CDarksendPool::AddEntry -- adding %s\n", newInput[0].ToString());
|
||||
@ -1124,7 +1094,7 @@ bool CDarksendPool::SignaturesComplete(){
|
||||
// Execute a Darksend denomination via a Masternode.
|
||||
// This is only ran from clients
|
||||
//
|
||||
void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout){
|
||||
void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout, int64_t amount){
|
||||
|
||||
if(fMasterNode) {
|
||||
LogPrintf("CDarksendPool::SendDarksendDenominate() - Darksend from a Masternode is not supported currently.\n");
|
||||
@ -1171,10 +1141,13 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
|
||||
|
||||
//check it against the memory pool to make sure it's valid
|
||||
{
|
||||
int64_t nValueOut = 0;
|
||||
|
||||
CValidationState state;
|
||||
CMutableTransaction tx;
|
||||
|
||||
BOOST_FOREACH(const CTxOut& o, vout){
|
||||
nValueOut += o.nValue;
|
||||
tx.vout.push_back(o);
|
||||
}
|
||||
|
||||
@ -1201,10 +1174,10 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
|
||||
|
||||
// store our entry for later use
|
||||
CDarkSendEntry e;
|
||||
e.Add(vin, txCollateral, vout);
|
||||
e.Add(vin, amount, txCollateral, vout);
|
||||
entries.push_back(e);
|
||||
|
||||
RelayIn(entries[0].sev, txCollateral, entries[0].vout);
|
||||
RelayIn(entries[0].sev, entries[0].amount, txCollateral, entries[0].vout);
|
||||
Check();
|
||||
}
|
||||
|
||||
@ -1552,8 +1525,6 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
||||
//non-denom's are incompatible
|
||||
if((dsq.nDenom & (1 << 4))) continue;
|
||||
|
||||
if(dsq.nNumberOfInputs < DARKSEND_MIN_INPUTS || dsq.nNumberOfInputs > DARKSEND_MAX_INPUTS) continue;
|
||||
|
||||
bool fUsed = false;
|
||||
//don't reuse Masternodes
|
||||
BOOST_FOREACH(CTxIn usedVin, vecMasternodesUsed){
|
||||
@ -1567,16 +1538,11 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
||||
std::vector<CTxIn> vTempCoins;
|
||||
std::vector<COutput> vTempCoins2;
|
||||
// Try to match their denominations if possible
|
||||
if (!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, dsq.nNumberOfInputs, vTempCoins, vTempCoins2, 0, nDarksendRounds)){
|
||||
if (!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, nValueMin, nBalanceNeedsAnonymized, vTempCoins, vTempCoins2, nValueIn, 0, nDarksendRounds)){
|
||||
LogPrintf("DoAutomaticDenominating - Couldn't match denominations %d\n", dsq.nDenom);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((int)vTempCoins.size() < dsq.nNumberOfInputs) {
|
||||
LogPrintf("DoAutomaticDenominating - Not enough denominations %d to match queue - %d %d\n", dsq.nDenom, (int)vTempCoins.size(), dsq.nNumberOfInputs);
|
||||
continue;
|
||||
}
|
||||
|
||||
// connect to Masternode and submit the queue request
|
||||
CNode* pnode = ConnectNode((CAddress)addr, NULL, true);
|
||||
if(pnode != NULL)
|
||||
@ -1590,10 +1556,9 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
||||
pSubmittedToMasternode = pmn;
|
||||
vecMasternodesUsed.push_back(dsq.vin);
|
||||
sessionDenom = dsq.nDenom;
|
||||
sessionNumberOfInputs = dsq.nNumberOfInputs;
|
||||
|
||||
pnode->PushMessage("dsa", sessionDenom, sessionNumberOfInputs, txCollateral);
|
||||
LogPrintf("DoAutomaticDenominating --- connected (from queue), sending dsa for essionNumberOfInputs %d sessionDenom %d - %s\n", sessionNumberOfInputs, sessionDenom, pnode->addr.ToString());
|
||||
pnode->PushMessage("dsa", sessionDenom, txCollateral);
|
||||
LogPrintf("DoAutomaticDenominating --- connected (from queue), sending dsa for %d - %s\n", sessionDenom, pnode->addr.ToString());
|
||||
strAutoDenomResult = _("Mixing in progress...");
|
||||
dsq.time = 0; //remove node
|
||||
return true;
|
||||
@ -1638,23 +1603,8 @@ bool CDarksendPool::DoAutomaticDenominating(bool fDryRun)
|
||||
while(sessionDenom == 0)
|
||||
sessionDenom = GetDenominationsByAmounts(vecAmounts);
|
||||
|
||||
std::vector<CTxIn> vTempCoins;
|
||||
std::vector<COutput> vTempCoins2;
|
||||
if (!pwalletMain->SelectCoinsByDenominations(sessionDenom, rand() % DARKSEND_MAX_INPUTS + 1, vTempCoins, vTempCoins2, 0, nDarksendRounds)){
|
||||
// should never really happen
|
||||
LogPrintf("DoAutomaticDenominating - Couldn't match denominations %d\n", sessionDenom);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((int)vTempCoins.size() < DARKSEND_MIN_INPUTS) {
|
||||
LogPrintf("DoAutomaticDenominating - Not enough denominations to send %d\n", sessionDenom);
|
||||
continue;
|
||||
}
|
||||
|
||||
sessionNumberOfInputs = std::min(DARKSEND_MAX_INPUTS, (int)vTempCoins.size());
|
||||
|
||||
pnode->PushMessage("dsa", sessionDenom, sessionNumberOfInputs, txCollateral);
|
||||
LogPrintf("DoAutomaticDenominating --- connected, sending dsa for sessionNumberOfInputs %d sessionDenom %d\n", sessionNumberOfInputs, sessionDenom);
|
||||
pnode->PushMessage("dsa", sessionDenom, txCollateral);
|
||||
LogPrintf("DoAutomaticDenominating --- connected, sending dsa for %d\n", sessionDenom);
|
||||
strAutoDenomResult = _("Mixing in progress...");
|
||||
return true;
|
||||
} else {
|
||||
@ -1868,18 +1818,16 @@ bool CDarksendPool::IsCompatibleWithEntries(std::vector<CTxOut>& vout)
|
||||
LogPrintf(" vout 2 - %s\n", o2.ToString());
|
||||
*/
|
||||
if(GetDenominations(vout) != GetDenominations(v.vout)) return false;
|
||||
if(vout.size() != v.vout.size()) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDarksendPool::IsCompatibleWithSession(int64_t nDenom, int nNumberOfInputs, CTransaction txCollateral, int& errorID)
|
||||
bool CDarksendPool::IsCompatibleWithSession(int64_t nDenom, CTransaction txCollateral, int& errorID)
|
||||
{
|
||||
if(nDenom == 0) return false;
|
||||
|
||||
LogPrintf("CDarksendPool::IsCompatibleWithSession - sessionDenom %d sessionUsers %d nDenom %d nNumberOfInputs %d sessionNumberOfInputs %d\n",
|
||||
sessionDenom, sessionUsers, nDenom, nNumberOfInputs, sessionNumberOfInputs);
|
||||
LogPrintf("CDarksendPool::IsCompatibleWithSession - sessionDenom %d sessionUsers %d\n", sessionDenom, sessionUsers);
|
||||
|
||||
if (!unitTest && !IsCollateralValid(txCollateral)){
|
||||
LogPrint("darksend", "CDarksendPool::IsCompatibleWithSession - collateral not valid!\n");
|
||||
@ -1893,14 +1841,12 @@ bool CDarksendPool::IsCompatibleWithSession(int64_t nDenom, int nNumberOfInputs,
|
||||
sessionID = 1 + (rand() % 999999);
|
||||
sessionDenom = nDenom;
|
||||
sessionUsers++;
|
||||
sessionNumberOfInputs = nNumberOfInputs;
|
||||
lastTimeChanged = GetTimeMillis();
|
||||
|
||||
if(!unitTest){
|
||||
//broadcast that I'm accepting entries, only if it's the first entry through
|
||||
CDarksendQueue dsq;
|
||||
dsq.nDenom = nDenom;
|
||||
dsq.nNumberOfInputs = nNumberOfInputs;
|
||||
dsq.vin = activeMasternode.vin;
|
||||
dsq.time = GetTime();
|
||||
dsq.Sign();
|
||||
@ -1924,11 +1870,6 @@ bool CDarksendPool::IsCompatibleWithSession(int64_t nDenom, int nNumberOfInputs,
|
||||
return false;
|
||||
}
|
||||
|
||||
if(sessionNumberOfInputs != nNumberOfInputs) {
|
||||
errorID = ERR_INVALID_INPUTS_NUMBER;
|
||||
return false;
|
||||
}
|
||||
|
||||
LogPrintf("CDarkSendPool::IsCompatibleWithSession - compatible\n");
|
||||
|
||||
sessionUsers++;
|
||||
@ -2075,9 +2016,7 @@ std::string CDarksendPool::GetMessageByID(int messageID) {
|
||||
case ERR_EXISTING_TX: return _("Not compatible with existing transactions.");
|
||||
case ERR_FEES: return _("Transaction fees are too high.");
|
||||
case ERR_INVALID_COLLATERAL: return _("Collateral not valid.");
|
||||
case ERR_INVALID_DENOM: return _("Invalid denominations.");
|
||||
case ERR_INVALID_INPUT: return _("Input is not valid.");
|
||||
case ERR_INVALID_INPUTS_NUMBER: return _("Number of inputs is not valid.");
|
||||
case ERR_INVALID_SCRIPT: return _("Invalid script detected.");
|
||||
case ERR_INVALID_TX: return _("Transaction not valid.");
|
||||
case ERR_MAXIMUM: return _("Value more than Darksend pool maximum allows.");
|
||||
@ -2232,7 +2171,7 @@ void CDarksendPool::RelayFinalTransaction(const int sessionID, const CTransactio
|
||||
}
|
||||
}
|
||||
|
||||
void CDarksendPool::RelayIn(const std::vector<CTxDSIn>& vin, const CTransaction& txCollateral, const std::vector<CTxDSOut>& vout)
|
||||
void CDarksendPool::RelayIn(const std::vector<CTxDSIn>& vin, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxDSOut>& vout)
|
||||
{
|
||||
if(!pSubmittedToMasternode) return;
|
||||
|
||||
@ -2248,7 +2187,7 @@ void CDarksendPool::RelayIn(const std::vector<CTxDSIn>& vin, const CTransaction&
|
||||
CNode* pnode = FindNode(pSubmittedToMasternode->addr);
|
||||
if(pnode != NULL) {
|
||||
LogPrintf("RelayIn - found master, relaying message - %s \n", pnode->addr.ToString());
|
||||
pnode->PushMessage("dsi", vin2, txCollateral, vout2);
|
||||
pnode->PushMessage("dsi", vin2, nAmount, txCollateral, vout2);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,6 @@ class CActiveMasternode;
|
||||
#define DARKSEND_RELAY_OUT 2
|
||||
#define DARKSEND_RELAY_SIG 3
|
||||
|
||||
#define DARKSEND_MIN_INPUTS 1
|
||||
#define DARKSEND_MAX_INPUTS 5
|
||||
|
||||
static const int64_t DARKSEND_COLLATERAL = (0.01*COIN);
|
||||
static const int64_t DARKSEND_POOL_MAX = (999.99*COIN);
|
||||
|
||||
@ -101,6 +98,7 @@ public:
|
||||
bool isSet;
|
||||
std::vector<CTxDSIn> sev;
|
||||
std::vector<CTxDSOut> vout;
|
||||
int64_t amount;
|
||||
CTransaction collateral;
|
||||
CTransaction txSupporting;
|
||||
int64_t addedTime; // time in UTC milliseconds
|
||||
@ -109,10 +107,11 @@ public:
|
||||
{
|
||||
isSet = false;
|
||||
collateral = CTransaction();
|
||||
amount = 0;
|
||||
}
|
||||
|
||||
/// Add entries to use for Darksend
|
||||
bool Add(const std::vector<CTxIn> vinIn, const CTransaction collateralIn, const std::vector<CTxOut> voutIn)
|
||||
bool Add(const std::vector<CTxIn> vinIn, int64_t amountIn, const CTransaction collateralIn, const std::vector<CTxOut> voutIn)
|
||||
{
|
||||
if(isSet){return false;}
|
||||
|
||||
@ -122,6 +121,7 @@ public:
|
||||
BOOST_FOREACH(const CTxOut& out, voutIn)
|
||||
vout.push_back(out);
|
||||
|
||||
amount = amountIn;
|
||||
collateral = collateralIn;
|
||||
isSet = true;
|
||||
addedTime = GetTime();
|
||||
@ -161,14 +161,12 @@ public:
|
||||
CTxIn vin;
|
||||
int64_t time;
|
||||
int nDenom;
|
||||
int nNumberOfInputs;
|
||||
bool ready; //ready for submit
|
||||
std::vector<unsigned char> vchSig;
|
||||
|
||||
CDarksendQueue()
|
||||
{
|
||||
nDenom = 0;
|
||||
nNumberOfInputs = 0;
|
||||
vin = CTxIn();
|
||||
time = 0;
|
||||
vchSig.clear();
|
||||
@ -180,7 +178,6 @@ public:
|
||||
template <typename Stream, typename Operation>
|
||||
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
|
||||
READWRITE(nDenom);
|
||||
READWRITE(nNumberOfInputs);
|
||||
READWRITE(vin);
|
||||
READWRITE(time);
|
||||
READWRITE(ready);
|
||||
@ -304,9 +301,7 @@ public:
|
||||
ERR_EXISTING_TX,
|
||||
ERR_FEES,
|
||||
ERR_INVALID_COLLATERAL,
|
||||
ERR_INVALID_DENOM,
|
||||
ERR_INVALID_INPUT,
|
||||
ERR_INVALID_INPUTS_NUMBER,
|
||||
ERR_INVALID_SCRIPT,
|
||||
ERR_INVALID_TX,
|
||||
ERR_MAXIMUM,
|
||||
@ -329,7 +324,6 @@ public:
|
||||
|
||||
CMasternode* pSubmittedToMasternode;
|
||||
int sessionDenom; //Users must submit an denom matching this
|
||||
int sessionNumberOfInputs;//Users must submit only matching number of inputs
|
||||
int cachedNumBlocks; //used for the overview screen
|
||||
|
||||
CDarksendPool()
|
||||
@ -440,7 +434,7 @@ public:
|
||||
bool IsCompatibleWithEntries(std::vector<CTxOut>& vout);
|
||||
|
||||
/// Is this amount compatible with other client in the pool?
|
||||
bool IsCompatibleWithSession(int64_t nAmount, int nNumberOfInputs, CTransaction txCollateral, int &errorID);
|
||||
bool IsCompatibleWithSession(int64_t nAmount, CTransaction txCollateral, int &errorID);
|
||||
|
||||
/// Passively run Darksend in the background according to the configuration in settings (only for QT)
|
||||
bool DoAutomaticDenominating(bool fDryRun=false);
|
||||
@ -460,13 +454,13 @@ public:
|
||||
/// If the collateral is valid given by a client
|
||||
bool IsCollateralValid(const CTransaction& txCollateral);
|
||||
/// Add a clients entry to the pool
|
||||
bool AddEntry(const std::vector<CTxIn>& newInput, const CTransaction& txCollateral, const std::vector<CTxOut>& newOutput, int& errorID);
|
||||
bool AddEntry(const std::vector<CTxIn>& newInput, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxOut>& newOutput, int& errorID);
|
||||
/// Add signature to a vin
|
||||
bool AddScriptSig(const CTxIn& newVin);
|
||||
/// Check that all inputs are signed. (Are all inputs signed?)
|
||||
bool SignaturesComplete();
|
||||
/// As a client, send a transaction to a Masternode to start the denomination process
|
||||
void SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout);
|
||||
void SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout, int64_t amount);
|
||||
/// Get Masternode updates about the progress of Darksend
|
||||
bool StatusUpdate(int newState, int newEntriesCount, int newAccepted, int &errorID, int newSessionID=0);
|
||||
|
||||
@ -505,7 +499,7 @@ public:
|
||||
void RelayFinalTransaction(const int sessionID, const CTransaction& txNew);
|
||||
void RelaySignaturesAnon(std::vector<CTxIn>& vin);
|
||||
void RelayInAnon(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout);
|
||||
void RelayIn(const std::vector<CTxDSIn>& vin, const CTransaction& txCollateral, const std::vector<CTxDSOut>& vout);
|
||||
void RelayIn(const std::vector<CTxDSIn>& vin, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxDSOut>& vout);
|
||||
void RelayStatus(const int sessionID, const int newState, const int newEntriesCount, const int newAccepted, const int errorID=MSG_NOERR);
|
||||
void RelayCompletedTransaction(const int sessionID, const bool error, const int errorID);
|
||||
};
|
||||
|
@ -10,7 +10,7 @@
|
||||
* network protocol versioning
|
||||
*/
|
||||
|
||||
static const int PROTOCOL_VERSION = 70104;
|
||||
static const int PROTOCOL_VERSION = 70103;
|
||||
|
||||
//! initial proto version, to be increased after version/verack negotiation
|
||||
static const int INIT_PROTO_VERSION = 209;
|
||||
@ -22,7 +22,7 @@ static const int GETHEADERS_VERSION = 70077;
|
||||
static const int MIN_PEER_PROTO_VERSION = 70066;
|
||||
|
||||
//! minimum peer version accepted by DarksendPool
|
||||
static const int MIN_POOL_PEER_PROTO_VERSION = 70104;
|
||||
static const int MIN_POOL_PEER_PROTO_VERSION = 70103;
|
||||
|
||||
//! minimum peer version for masternode budgets
|
||||
static const int MIN_BUDGET_PEER_PROTO_VERSION = 70103;
|
||||
|
108
src/wallet.cpp
108
src/wallet.cpp
@ -1787,9 +1787,11 @@ struct CompareByPriority
|
||||
}
|
||||
};
|
||||
|
||||
bool CWallet::SelectCoinsByDenominations(int nDenom, int nNumberOfInputs, std::vector<CTxIn>& vCoinsRet, std::vector<COutput>& vCoinsRet2, int nDarksendRoundsMin, int nDarksendRoundsMax)
|
||||
bool CWallet::SelectCoinsByDenominations(int nDenom, int64_t nValueMin, int64_t nValueMax, std::vector<CTxIn>& vCoinsRet, std::vector<COutput>& vCoinsRet2, int64_t& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax)
|
||||
{
|
||||
vCoinsRet.clear();
|
||||
nValueRet = 0;
|
||||
|
||||
vCoinsRet2.clear();
|
||||
vector<COutput> vCoins;
|
||||
AvailableCoins(vCoins, true, NULL, ONLY_DENOMINATED);
|
||||
@ -1812,44 +1814,53 @@ bool CWallet::SelectCoinsByDenominations(int nDenom, int nNumberOfInputs, std::v
|
||||
{
|
||||
// masternode-like input should not be selected by AvailableCoins now anyway
|
||||
//if(out.tx->vout[out.i].nValue == 1000*COIN) continue;
|
||||
bool fAccepted = false;
|
||||
if(nValueRet + out.tx->vout[out.i].nValue <= nValueMax){
|
||||
bool fAccepted = false;
|
||||
|
||||
// Function returns as follows:
|
||||
//
|
||||
// bit 0 - 100DRK+1 ( bit on if present )
|
||||
// bit 1 - 10DRK+1
|
||||
// bit 2 - 1DRK+1
|
||||
// bit 3 - .1DRK+1
|
||||
// Function returns as follows:
|
||||
//
|
||||
// bit 0 - 100DRK+1 ( bit on if present )
|
||||
// bit 1 - 10DRK+1
|
||||
// bit 2 - 1DRK+1
|
||||
// bit 3 - .1DRK+1
|
||||
|
||||
CTxIn vin = CTxIn(out.tx->GetHash(),out.i);
|
||||
CTxIn vin = CTxIn(out.tx->GetHash(),out.i);
|
||||
|
||||
int rounds = GetInputDarksendRounds(vin);
|
||||
if(rounds >= nDarksendRoundsMax) continue;
|
||||
if(rounds < nDarksendRoundsMin) continue;
|
||||
int rounds = GetInputDarksendRounds(vin);
|
||||
if(rounds >= nDarksendRoundsMax) continue;
|
||||
if(rounds < nDarksendRoundsMin) continue;
|
||||
|
||||
if(fFound100 && fFound10 && fFound1 && fFoundDot1){ //if fulfilled
|
||||
//we can return this for submission
|
||||
if((int)vCoinsRet.size() >= nNumberOfInputs) return true;
|
||||
//Denomination criterion has been met, we can take any matching denominations
|
||||
if((nDenom & (1 << 0)) && out.tx->vout[out.i].nValue == ((100*COIN) +100000)) {fAccepted = true;}
|
||||
else if((nDenom & (1 << 1)) && out.tx->vout[out.i].nValue == ((10*COIN)+10000)) {fAccepted = true;}
|
||||
else if((nDenom & (1 << 2)) && out.tx->vout[out.i].nValue == ((1*COIN) +1000)) {fAccepted = true;}
|
||||
else if((nDenom & (1 << 3)) && out.tx->vout[out.i].nValue == ((.1*COIN)+100)) {fAccepted = true;}
|
||||
} else {
|
||||
//Criterion has not been satisfied, we will only take 1 of each until it is.
|
||||
if((nDenom & (1 << 0)) && out.tx->vout[out.i].nValue == ((100*COIN) +100000)) {fAccepted = true; fFound100 = true;}
|
||||
else if((nDenom & (1 << 1)) && out.tx->vout[out.i].nValue == ((10*COIN)+10000)) {fAccepted = true; fFound10 = true;}
|
||||
else if((nDenom & (1 << 2)) && out.tx->vout[out.i].nValue == ((1*COIN) +1000)) {fAccepted = true; fFound1 = true;}
|
||||
else if((nDenom & (1 << 3)) && out.tx->vout[out.i].nValue == ((.1*COIN)+100)) {fAccepted = true; fFoundDot1 = true;}
|
||||
if(fFound100 && fFound10 && fFound1 && fFoundDot1){ //if fulfilled
|
||||
//we can return this for submission
|
||||
if(nValueRet >= nValueMin){
|
||||
//random reduce the max amount we'll submit for anonymity
|
||||
nValueMax -= (rand() % (nValueMax/5));
|
||||
//on average use 50% of the inputs or less
|
||||
int r = (rand() % (int)vCoins.size());
|
||||
if((int)vCoinsRet.size() > r) return true;
|
||||
}
|
||||
//Denomination criterion has been met, we can take any matching denominations
|
||||
if((nDenom & (1 << 0)) && out.tx->vout[out.i].nValue == ((100*COIN) +100000)) {fAccepted = true;}
|
||||
else if((nDenom & (1 << 1)) && out.tx->vout[out.i].nValue == ((10*COIN)+10000)) {fAccepted = true;}
|
||||
else if((nDenom & (1 << 2)) && out.tx->vout[out.i].nValue == ((1*COIN) +1000)) {fAccepted = true;}
|
||||
else if((nDenom & (1 << 3)) && out.tx->vout[out.i].nValue == ((.1*COIN)+100)) {fAccepted = true;}
|
||||
} else {
|
||||
//Criterion has not been satisfied, we will only take 1 of each until it is.
|
||||
if((nDenom & (1 << 0)) && out.tx->vout[out.i].nValue == ((100*COIN) +100000)) {fAccepted = true; fFound100 = true;}
|
||||
else if((nDenom & (1 << 1)) && out.tx->vout[out.i].nValue == ((10*COIN)+10000)) {fAccepted = true; fFound10 = true;}
|
||||
else if((nDenom & (1 << 2)) && out.tx->vout[out.i].nValue == ((1*COIN) +1000)) {fAccepted = true; fFound1 = true;}
|
||||
else if((nDenom & (1 << 3)) && out.tx->vout[out.i].nValue == ((.1*COIN)+100)) {fAccepted = true; fFoundDot1 = true;}
|
||||
}
|
||||
if(!fAccepted) continue;
|
||||
|
||||
vin.prevPubKey = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey
|
||||
nValueRet += out.tx->vout[out.i].nValue;
|
||||
vCoinsRet.push_back(vin);
|
||||
vCoinsRet2.push_back(out);
|
||||
}
|
||||
if(!fAccepted) continue;
|
||||
|
||||
vin.prevPubKey = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey
|
||||
vCoinsRet.push_back(vin);
|
||||
vCoinsRet2.push_back(out);
|
||||
}
|
||||
|
||||
return ((int)vCoinsRet.size() >= nNumberOfInputs && fFound100 && fFound10 && fFound1 && fFoundDot1);
|
||||
return (nValueRet >= nValueMin && fFound100 && fFound10 && fFound1 && fFoundDot1);
|
||||
}
|
||||
|
||||
bool CWallet::SelectCoinsDark(CAmount nValueMin, CAmount nValueMax, std::vector<CTxIn>& setCoinsRet, CAmount& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax) const
|
||||
@ -2380,7 +2391,7 @@ int64_t CWallet::GetTotalValue(std::vector<CTxIn> vCoins) {
|
||||
return nTotalValue;
|
||||
}
|
||||
|
||||
std::string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
|
||||
string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
|
||||
{
|
||||
if (IsLocked())
|
||||
return _("Error: Wallet locked, unable to create transaction!");
|
||||
@ -2393,6 +2404,7 @@ std::string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
|
||||
std::vector<CTxIn> vCoins;
|
||||
std::vector<CTxIn> vCoinsResult;
|
||||
std::vector<COutput> vCoins2;
|
||||
int64_t nValueIn = 0;
|
||||
CReserveKey reservekey(this);
|
||||
|
||||
/*
|
||||
@ -2401,17 +2413,11 @@ std::string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
|
||||
if minRounds >= 0 it means only denominated inputs are going in and coming out
|
||||
*/
|
||||
if(minRounds >= 0){
|
||||
if (!SelectCoinsByDenominations(darkSendPool.sessionDenom, darkSendPool.sessionNumberOfInputs, vCoins, vCoins2, minRounds, maxRounds))
|
||||
if (!SelectCoinsByDenominations(darkSendPool.sessionDenom, 0.1*COIN, DARKSEND_POOL_MAX, vCoins, vCoins2, nValueIn, minRounds, maxRounds))
|
||||
return _("Error: Can't select current denominated inputs");
|
||||
|
||||
if ((int)vCoins.size() < darkSendPool.sessionNumberOfInputs) {
|
||||
LogPrintf("PrepareDarksendDenominate - Not enough denominations %d to match queue - %d %d\n", darkSendPool.sessionDenom, (int)vCoins.size(), darkSendPool.sessionNumberOfInputs);
|
||||
return "Error: Not enough denominations to match queue";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
LogPrintf("PrepareDarksendDenominate - preparing darksend denominate\n");
|
||||
LogPrintf("PrepareDarksendDenominate - preparing darksend denominate . Got: %d \n", nValueIn);
|
||||
|
||||
{
|
||||
LOCK(cs_wallet);
|
||||
@ -2419,18 +2425,20 @@ std::string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
|
||||
LockCoin(v.prevout);
|
||||
}
|
||||
|
||||
int64_t nValueLeft = nValueIn;
|
||||
std::vector<CTxOut> vOut;
|
||||
|
||||
/*
|
||||
TODO: Front load with needed denominations (e.g. .1, 1 )
|
||||
*/
|
||||
|
||||
// Make outputs by looping through denominations: try to add needed denomination,
|
||||
// repeat darkSendPool.sessionNumberOfInputs times.
|
||||
// Make outputs by looping through denominations: try to add every needed denomination, repeat up to 5-10 times.
|
||||
// This way we can be pretty sure that it should have at least one of each needed denomination.
|
||||
// NOTE: No need to randomize order of inputs because they were
|
||||
// initially shuffled in CWallet::SelectCoinsByDenominations already.
|
||||
int nStep = 0;
|
||||
while(nStep < darkSendPool.sessionNumberOfInputs) {
|
||||
int nStepsMax = 5 + GetRandInt(5);
|
||||
while(nStep < nStepsMax) {
|
||||
|
||||
BOOST_FOREACH(int64_t v, darkSendDenominations){
|
||||
// only use the ones that are approved
|
||||
@ -2442,7 +2450,7 @@ std::string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
|
||||
if(!fAccepted) continue;
|
||||
|
||||
// try to add it
|
||||
if((int)vCoinsResult.size() < darkSendPool.sessionNumberOfInputs) {
|
||||
if(nValueLeft - v >= 0) {
|
||||
// Note: this relies on a fact that both vectors MUST have same size
|
||||
std::vector<CTxIn>::iterator it = vCoins.begin();
|
||||
std::vector<COutput>::iterator it2 = vCoins2.begin();
|
||||
@ -2467,6 +2475,7 @@ std::string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
|
||||
vOut.push_back(o);
|
||||
|
||||
// subtract denomination amount
|
||||
nValueLeft -= v;
|
||||
|
||||
break;
|
||||
}
|
||||
@ -2475,7 +2484,10 @@ std::string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nStep++;
|
||||
|
||||
if(nValueLeft == 0) break;
|
||||
}
|
||||
|
||||
{
|
||||
@ -2485,9 +2497,7 @@ std::string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
|
||||
UnlockCoin(v.prevout);
|
||||
}
|
||||
|
||||
if(darkSendPool.GetDenominations(vOut) != darkSendPool.sessionDenom ||
|
||||
(int)vCoinsResult.size() != darkSendPool.sessionNumberOfInputs ||
|
||||
(int)vOut.size() != darkSendPool.sessionNumberOfInputs) {
|
||||
if(darkSendPool.GetDenominations(vOut) != darkSendPool.sessionDenom) {
|
||||
// unlock used coins on failure
|
||||
LOCK(cs_wallet);
|
||||
BOOST_FOREACH(CTxIn v, vCoinsResult)
|
||||
@ -2499,7 +2509,7 @@ std::string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
|
||||
std::random_shuffle (vOut.begin(), vOut.end());
|
||||
|
||||
// We also do not care about full amount as long as we have right denominations, just pass what we found
|
||||
darkSendPool.SendDarksendDenominate(vCoinsResult, vOut);
|
||||
darkSendPool.SendDarksendDenominate(vCoinsResult, vOut, nValueIn - nValueLeft);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
@ -149,7 +149,7 @@ private:
|
||||
public:
|
||||
// bool SelectCoins(int64_t nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64_t& nValueRet, const CCoinControl *coinControl = NULL, AvailableCoinsType coin_type=ALL_COINS, bool useIX = true) const;
|
||||
bool SelectCoinsDark(int64_t nValueMin, int64_t nValueMax, std::vector<CTxIn>& setCoinsRet, int64_t& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax) const;
|
||||
bool SelectCoinsByDenominations(int nDenom, int nNumberOfInputs, std::vector<CTxIn>& vCoinsRet, std::vector<COutput>& vCoinsRet2, int nDarksendRoundsMin, int nDarksendRoundsMax);
|
||||
bool SelectCoinsByDenominations(int nDenom, int64_t nValueMin, int64_t nValueMax, std::vector<CTxIn>& vCoinsRet, std::vector<COutput>& vCoinsRet2, int64_t& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax);
|
||||
bool SelectCoinsDarkDenominated(int64_t nTargetValue, std::vector<CTxIn>& setCoinsRet, int64_t& nValueRet) const;
|
||||
bool HasCollateralInputs(bool fOnlyConfirmed = true) const;
|
||||
bool IsCollateralAmount(int64_t nInputAmount) const;
|
||||
|
Loading…
Reference in New Issue
Block a user