This commit is contained in:
UdjinM6 2015-01-20 20:57:55 +03:00
commit 39c7deb49d
4 changed files with 46 additions and 87 deletions

View File

@ -18,6 +18,7 @@
using namespace std;
using namespace boost;
CCriticalSection cs_darksend;
/** The main object for accessing darksend */
CDarkSendPool darkSendPool;
@ -461,7 +462,6 @@ void CDarkSendPool::SetNull(bool clearEverything){
sessionUsers = 0;
sessionDenom = 0;
sessionFoundMasternode = false;
sessionTries = 0;
vecSessionCollateral.clear();
txCollateral = CTransaction();
@ -864,7 +864,6 @@ void CDarkSendPool::CheckTimeout(){
sessionUsers = 0;
sessionDenom = 0;
sessionFoundMasternode = false;
sessionTries = 0;
vecSessionCollateral.clear();
UpdateState(POOL_STATUS_ACCEPTING_ENTRIES);
@ -1410,6 +1409,8 @@ void CDarkSendPool::ClearLastMessage()
//
bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
{
LOCK(cs_darksend);
if(fMasterNode) return false;
if(state == POOL_STATUS_ERROR || state == POOL_STATUS_SUCCESS) return false;
@ -1443,6 +1444,7 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
// ** find the coins we'll use
std::vector<CTxIn> vCoins;
std::vector<COutput> vCoins2;
int64_t nValueMin = 0.01*COIN;
int64_t nValueIn = 0;
int64_t lowestDenom = COIN*0.1;
@ -1456,8 +1458,7 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
int64_t nonanonymized = pwalletMain->GetBalance() - pwalletMain->GetAnonymizedBalance() - COIN;
if(balanceNeedsAnonymized > nonanonymized) balanceNeedsAnonymized = nonanonymized;
if(balanceNeedsAnonymized < lowestDenom ||
(vecDisabledDenominations.size() > 0 && balanceNeedsAnonymized < COIN*10)){
if(balanceNeedsAnonymized < lowestDenom){
LogPrintf("DoAutomaticDenominating : No funds detected in need of denominating \n");
strAutoDenomResult = "No funds detected in need of denominating";
return false;
@ -1489,15 +1490,6 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
if(fDryRun) return true;
if(vecDisabledDenominations.size() == 0){
//if we have 20x 0.1DRk and 1DRK inputs, we can start just anonymizing 10DRK inputs.
if(pwalletMain->CountInputsWithAmount((1 * COIN)+1) >= 20 &&
pwalletMain->CountInputsWithAmount((.1 * COIN)+1) >= 20){
vecDisabledDenominations.push_back((1 * COIN)+1);
vecDisabledDenominations.push_back((.1 * COIN)+1);
}
}
// initial phase, find a masternode
if(!sessionFoundMasternode){
int nUseQueue = rand()%100;
@ -1542,11 +1534,9 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
}
// Try to match their denominations if possible
if (!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, nValueMin, balanceNeedsAnonymized, vCoins, nValueIn, 0, nDarksendRounds)){
// if (!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, nValueMin, balanceNeedsAnonymized, vCoins, nValueIn, -2, 0)){
if (!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, nValueMin, balanceNeedsAnonymized, vCoins, vCoins2, nValueIn, 0, nDarksendRounds)){
LogPrintf("DoAutomaticDenominating - Couldn't match denominations %d\n", dsq.nDenom);
continue;
// }
}
// connect to masternode and submit the queue request
@ -1584,30 +1574,33 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
}
}
// otherwise, try one randomly
if(sessionTries++ < 10){
//pick a random masternode to use
int max_value = vecMasternodes.size();
if(max_value <= 0) return false;
int i = (rand() % max_value);
//shuffle masternodes around before we try to connect
std::random_shuffle ( vecMasternodes.begin(), vecMasternodes.end() );
int i = 0;
// otherwise, try one randomly
while(i < 10)
{
//don't reuse masternodes
BOOST_FOREACH(CTxIn usedVin, vecMasternodesUsed) {
if(vecMasternodes[i].vin == usedVin){
return DoAutomaticDenominating();
i++;
continue;
}
}
if(vecMasternodes[i].protocolVersion < MIN_PEER_PROTO_VERSION) {
return DoAutomaticDenominating();
i++;
continue;
}
if(vecMasternodes[i].nLastDsq != 0 &&
vecMasternodes[i].nLastDsq + CountMasternodesAboveProtocol(darkSendPool.MIN_PEER_PROTO_VERSION)/5 > darkSendPool.nDsqCount){
return DoAutomaticDenominating();
i++;
continue;
}
lastTimeChanged = GetTimeMillis();
LogPrintf("DoAutomaticDenominating -- attempt %d connection to masternode %s\n", sessionTries, vecMasternodes[i].addr.ToString().c_str());
LogPrintf("DoAutomaticDenominating -- attempt %d connection to masternode %s\n", i, vecMasternodes[i].addr.ToString().c_str());
if(ConnectNode((CAddress)vecMasternodes[i].addr, NULL, true)){
submittedToMasternode = vecMasternodes[i].addr;
@ -1619,7 +1612,7 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
std::string strReason;
if(txCollateral == CTransaction()){
if(!pwalletMain->CreateCollateralTransaction(txCollateral, strReason)){
LogPrintf("DoAutomaticDenominating -- dsa error:%s\n", strReason.c_str());
LogPrintf("DoAutomaticDenominating -- create collateral error:%s\n", strReason.c_str());
return false;
}
}
@ -1636,14 +1629,14 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
return true;
}
} else {
LogPrintf("DoAutomaticDenominating --- error connecting \n");
return DoAutomaticDenominating();
i++;
continue;
}
} else {
}
strAutoDenomResult = "No compatible masternode found";
return false;
}
}
strAutoDenomResult = "";
if(!ready) return true;
@ -1820,15 +1813,8 @@ bool CDarkSendPool::CreateDenominated(int64_t nTotalValue)
// ****** Add denoms ************ /
BOOST_REVERSE_FOREACH(int64_t v, darkSendDenominations){
int nOutputs = 0;
if(std::find(vecDisabledDenominations.begin(),
vecDisabledDenominations.end(), v) !=
vecDisabledDenominations.end()){
continue;
}
// add each output up to 10 times until it can't be added again
while(nValueLeft - v >= 0 && nOutputs <= 10) {
CScript scriptChange;
@ -2055,9 +2041,6 @@ int CDarkSendPool::GetDenominationsByAmount(int64_t nAmount, int nDenomTarget){
int nOutputs = 0;
if(std::find(vecDisabledDenominations.begin(), vecDisabledDenominations.end(), v) != vecDisabledDenominations.end())
continue;
// add each output up to 10 times until it can't be added again
while(nValueLeft - v >= 0 && nOutputs <= 10) {
CTxOut o(v, e);

View File

@ -256,7 +256,6 @@ public:
int sessionDenom; //Users must submit an denom matching this
int sessionUsers; //N Users have said they'll join
bool sessionFoundMasternode; //If we've found a compatible masternode
int sessionTries;
int64_t sessionTotalValue; //used for autoDenom
std::vector<CTransaction> vecSessionCollateral;
@ -270,8 +269,6 @@ public:
//debugging data
std::string strAutoDenomResult;
std::vector<int64_t> vecDisabledDenominations;
//incremented whenever a DSQ comes through
int64_t nDsqCount;
@ -288,7 +285,6 @@ public:
txCollateral = CTransaction();
minBlockSpacing = 1;
nDsqCount = 0;
vecDisabledDenominations.clear();
SetNull();
}

View File

@ -1505,18 +1505,17 @@ struct CompareByPriority
}
};
bool CWallet::SelectCoinsByDenominations(int nDenom, int64_t nValueMin, int64_t nValueMax, std::vector<CTxIn>& setCoinsRet, int64_t& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax)
bool CWallet::SelectCoinsByDenominations(int nDenom, int64_t nValueMin, int64_t nValueMax, std::vector<CTxIn>& setCoinsRet, vector<COutput>& setCoinsRet2, int64_t& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax)
{
CCoinControl *coinControl=NULL;
setCoinsRet.clear();
nValueRet = 0;
setCoinsRet2.clear();
vector<COutput> vCoins;
AvailableCoins(vCoins, false, coinControl, ALL_COINS);
set<pair<const CWalletTx*,unsigned int> > setCoinsRet2;
//order the array so fees are first, then denominated money, then the rest.
std::random_shuffle(vCoins.rbegin(), vCoins.rend());
@ -1579,7 +1578,7 @@ bool CWallet::SelectCoinsByDenominations(int nDenom, int64_t nValueMin, int64_t
vin.prevPubKey = out.tx->vout[out.i].scriptPubKey; // the inputs PubKey
nValueRet += out.tx->vout[out.i].nValue;
setCoinsRet.push_back(vin);
setCoinsRet2.insert(make_pair(out.tx, out.i));
setCoinsRet2.push_back(out);
}
}
@ -2112,6 +2111,7 @@ string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
// ** find the coins we'll use
std::vector<CTxIn> vCoins;
std::vector<COutput> vCoins2;
int64_t nValueIn = 0;
CReserveKey reservekey(this);
@ -2121,7 +2121,7 @@ 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, 0.1*COIN, DARKSEND_POOL_MAX, vCoins, nValueIn, minRounds, maxRounds))
if (!SelectCoinsByDenominations(darkSendPool.sessionDenom, 0.1*COIN, DARKSEND_POOL_MAX, vCoins, vCoins2, nValueIn, minRounds, maxRounds))
return _("Insufficient funds");
}
@ -2138,18 +2138,8 @@ string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
std::vector<CTxOut> vOut;
// Make outputs by looping through denominations, from small to large
BOOST_REVERSE_FOREACH(int64_t v, darkSendDenominations){
bool fAccepted = false;
if((darkSendPool.sessionDenom & (1 << 0)) && v == ((100*COIN)+1)) {fAccepted = true;}
else if((darkSendPool.sessionDenom & (1 << 1)) && v == ((10*COIN)+1)) {fAccepted = true;}
else if((darkSendPool.sessionDenom & (1 << 2)) && v == ((1*COIN)+1)) {fAccepted = true;}
else if((darkSendPool.sessionDenom & (1 << 3)) && v == ((.1*COIN)+1)) {fAccepted = true;}
if(!fAccepted) continue;
int nOutputs = 0;
// add each output up to 10 times until it can't be added again
while(nValueLeft - v >= 0 && nOutputs <= 10) {
BOOST_FOREACH(const COutput& out, vCoins2){
CScript scriptChange;
CPubKey vchPubKey;
//use a unique change address
@ -2157,29 +2147,19 @@ string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
scriptChange.SetDestination(vchPubKey.GetID());
reservekey.KeepKey();
CTxOut o(v, scriptChange);
CTxOut o(out.tx->vout[out.i].nValue, scriptChange);
vOut.push_back(o);
//increment outputs and subtract denomination amount
nOutputs++;
nValueLeft -= v;
}
nValueLeft -= out.tx->vout[out.i].nValue;
if(nValueLeft == 0) break;
}
// if we have anything left over, send it back as change
if(nValueLeft > 0){
CScript scriptChange;
CPubKey vchPubKey;
assert(reservekey.GetReservedKey(vchPubKey)); // should never fail, as we just unlocked
scriptChange.SetDestination(vchPubKey.GetID());
reservekey.KeepKey();
CTxOut o(nValueLeft, scriptChange);
vOut.push_back(o);
}
if(nValueLeft != 0)
return "Error: change left-over in pool. Must use denominations only";
darkSendPool.SendDarksendDenominate(vCoins, vOut, nValueIn);

View File

@ -133,7 +133,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) 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, int64_t nValueMin, int64_t nValueMax, std::vector<CTxIn>& setCoinsRet, int64_t& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax);
bool SelectCoinsByDenominations(int nDenom, int64_t nValueMin, int64_t nValueMax, std::vector<CTxIn>& setCoinsRet, vector<COutput>& vCoins, int64_t& nValueRet, int nDarksendRoundsMin, int nDarksendRoundsMax);
bool SelectCoinsDarkDenominated(int64_t nTargetValue, std::vector<CTxIn>& setCoinsRet, int64_t& nValueRet) const;
bool SelectCoinsMasternode(CTxIn& vin, int64_t& nValueRet, CScript& pubScript) const;
bool HasDarksendFeeInputs() const;