Merge 'upstream/v0.11.2.x' into v0.11.2.x
This commit is contained in:
commit
59bb5bec12
@ -3,7 +3,7 @@ AC_PREREQ([2.60])
|
||||
define(_CLIENT_VERSION_MAJOR, 0)
|
||||
define(_CLIENT_VERSION_MINOR, 11)
|
||||
define(_CLIENT_VERSION_REVISION, 2)
|
||||
define(_CLIENT_VERSION_BUILD, 1)
|
||||
define(_CLIENT_VERSION_BUILD, 2)
|
||||
define(_CLIENT_VERSION_IS_RELEASE, true)
|
||||
define(_COPYRIGHT_YEAR, 2015)
|
||||
AC_INIT([Darkcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@darkcoin.io],[darkcoin])
|
||||
|
@ -12,7 +12,7 @@
|
||||
#define CLIENT_VERSION_MAJOR 0
|
||||
#define CLIENT_VERSION_MINOR 11
|
||||
#define CLIENT_VERSION_REVISION 2
|
||||
#define CLIENT_VERSION_BUILD 0
|
||||
#define CLIENT_VERSION_BUILD 2
|
||||
|
||||
|
||||
|
||||
|
142
src/darksend.cpp
142
src/darksend.cpp
@ -173,6 +173,11 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
|
||||
return;
|
||||
}
|
||||
|
||||
if(state != POOL_STATUS_IDLE){
|
||||
LogPrintf("dsr -- wrong state to relay! \n");
|
||||
return;
|
||||
}
|
||||
|
||||
CDarkSendRelay dsr;
|
||||
vRecv >> dsr;
|
||||
|
||||
@ -450,8 +455,6 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
|
||||
bool success = false;
|
||||
int count = 0;
|
||||
|
||||
LogPrintf(" -- sigs count %d %d\n", (int)sigs.size(), count);
|
||||
|
||||
BOOST_FOREACH(const CTxIn item, sigs)
|
||||
{
|
||||
if(AddScriptSig(item)) success = true;
|
||||
@ -621,7 +624,7 @@ void CDarksendPool::SetNull(bool clearEverything){
|
||||
entries.clear();
|
||||
anonTx.vin.clear();
|
||||
anonTx.vout.clear();
|
||||
fResentInputsOutputs = false;
|
||||
nTrickleInputsOutputs = 0;
|
||||
|
||||
state = POOL_STATUS_IDLE;
|
||||
|
||||
@ -719,6 +722,7 @@ void CDarksendPool::Check()
|
||||
}
|
||||
|
||||
// shuffle the outputs for improved anonymity
|
||||
std::random_shuffle ( txNew.vin.begin(), txNew.vin.end(), randomizeList);
|
||||
std::random_shuffle ( txNew.vout.begin(), txNew.vout.end(), randomizeList);
|
||||
} else {
|
||||
BOOST_FOREACH(CTxDSIn& v, anonTx.vin)
|
||||
@ -729,7 +733,7 @@ void CDarksendPool::Check()
|
||||
}
|
||||
|
||||
if(fDebug) LogPrintf("Transaction 1: %s\n", txNew.ToString().c_str());
|
||||
SignFinalTransaction(txNew, NULL);
|
||||
finalTransaction = txNew;
|
||||
|
||||
// request signatures from clients
|
||||
RelayFinalTransaction(sessionID, finalTransaction);
|
||||
@ -765,7 +769,7 @@ void CDarksendPool::CheckFinalTransaction()
|
||||
if(fDebug) LogPrintf("Transaction 2: %s\n", txNew.ToString().c_str());
|
||||
|
||||
// See if the transaction is valid
|
||||
if (!txNew.AcceptToMemoryPool(true))
|
||||
if (!txNew.AcceptToMemoryPool(false))
|
||||
{
|
||||
if(nCountAttempts > 10) {
|
||||
LogPrintf("CDarksendPool::Check() - CommitTransaction : Error: Transaction not valid\n");
|
||||
@ -939,7 +943,7 @@ void CDarksendPool::ChargeFees(){
|
||||
CWalletTx wtxCollateral = CWalletTx(pwalletMain, v.collateral);
|
||||
|
||||
// Broadcast
|
||||
if (!wtxCollateral.AcceptToMemoryPool(true))
|
||||
if (!wtxCollateral.AcceptToMemoryPool(false))
|
||||
{
|
||||
// This must not fail. The transaction has already been signed and recorded.
|
||||
LogPrintf("CDarksendPool::ChargeFees() : Error: Transaction not valid");
|
||||
@ -1393,7 +1397,7 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
|
||||
myEntries.push_back(e);
|
||||
|
||||
// submit inputs/outputs through relays
|
||||
RelayInAnon(vin, vout);
|
||||
TrickleInputsOutputs();
|
||||
|
||||
Check();
|
||||
}
|
||||
@ -1433,7 +1437,6 @@ bool CDarksendPool::StatusUpdate(int newState, int newEntriesCount, int newAccep
|
||||
sessionFoundMasternode = true;
|
||||
//wait for other users. Masternode will report when ready
|
||||
UpdateState(POOL_STATUS_QUEUE);
|
||||
LogPrintf("Updated 1\n");
|
||||
} else if (newAccepted == 0 && sessionID == 0 && !sessionFoundMasternode) {
|
||||
LogPrintf("CDarksendPool::StatusUpdate - entry not accepted by Masternode \n");
|
||||
UnlockCoins();
|
||||
@ -1452,6 +1455,7 @@ bool CDarksendPool::StatusUpdate(int newState, int newEntriesCount, int newAccep
|
||||
// If we refuse to sign, it's possible we'll be charged collateral
|
||||
//
|
||||
bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNode* node){
|
||||
if(fMasterNode) return false;
|
||||
if(fDebug) LogPrintf("CDarksendPool::SignFinalTransaction - Got Finalized Transaction - fSubmitAnonymousFailed %d\n", fSubmitAnonymousFailed);
|
||||
|
||||
finalTransaction = finalTransactionNew;
|
||||
@ -1475,7 +1479,12 @@ bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNod
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(mine >= 0){ //might have to do this one input at a time?
|
||||
//already signed
|
||||
if(finalTransaction.vin[mine].scriptSig != CScript()) continue;
|
||||
if(sigs.size() > 7) break; //send 7 each signing
|
||||
|
||||
int foundOutputs = 0;
|
||||
int64_t nValue1 = 0;
|
||||
int64_t nValue2 = 0;
|
||||
@ -1497,7 +1506,7 @@ bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNod
|
||||
// in this case, something went wrong and we'll refuse to sign. It's possible we'll be charged collateral. But that's
|
||||
// better then signing if the transaction doesn't look like what we wanted.
|
||||
LogPrintf("CDarksendPool::Sign - My entries are not correct! Refusing to sign. %d entries %d target. \n", foundOutputs, targetOuputs);
|
||||
ResendMissingInputsOutputs();
|
||||
TrickleInputsOutputs();
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1517,6 +1526,15 @@ bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNod
|
||||
}
|
||||
|
||||
if(!fSubmitAnonymousFailed){
|
||||
//resubmit some other sigs from the transaction, so nodes can't tell who's inputs/outputs are whos
|
||||
BOOST_FOREACH(CTxIn& in, finalTransaction.vin)
|
||||
if((rand() % 100) > 75 && in.scriptSig != CScript())
|
||||
sigs.push_back(in);
|
||||
|
||||
std::random_shuffle ( sigs.begin(), sigs.end(), randomizeList);
|
||||
|
||||
printf("sigs count %d\n", (int)sigs.size());
|
||||
|
||||
RelaySignaturesAnon(sigs);
|
||||
} else {
|
||||
// push all of our signatures to the Masternode
|
||||
@ -1851,6 +1869,7 @@ bool CDarksendPool::PrepareDarksendDenominate()
|
||||
|
||||
bool CDarksendPool::Downgrade()
|
||||
{
|
||||
|
||||
if(fSubmitAnonymousFailed) return true;
|
||||
if(myEntries.size() == 0) return false;
|
||||
|
||||
@ -1863,17 +1882,72 @@ bool CDarksendPool::Downgrade()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDarksendPool::ResendMissingInputsOutputs()
|
||||
struct SortByTimesSent
|
||||
{
|
||||
if(fResentInputsOutputs) {
|
||||
bool operator()(const CTxDSIn & t1,
|
||||
const CTxDSIn & t2) const
|
||||
{
|
||||
return t1.nSentTimes > t2.nSentTimes;
|
||||
}
|
||||
|
||||
bool operator()(const CTxDSOut & t1,
|
||||
const CTxDSOut & t2) const
|
||||
{
|
||||
return t1.nSentTimes > t2.nSentTimes;
|
||||
}
|
||||
};
|
||||
|
||||
bool CDarksendPool::TrickleInputsOutputs()
|
||||
{
|
||||
if(nTrickleInputsOutputs >= 20) {
|
||||
Downgrade();
|
||||
return true;
|
||||
}
|
||||
if(myEntries.size() == 0) return false;
|
||||
|
||||
LogPrintf("CDarksendPool::Downgrade() : Downgrading and submitting directly\n");
|
||||
RelayInAnon(myEntries[0].sev, myEntries[0].vout);
|
||||
fResentInputsOutputs = true;
|
||||
std::vector<CTxIn> vin;
|
||||
std::vector<CTxOut> vout;
|
||||
|
||||
sort(myEntries[0].sev.rbegin(), myEntries[0].sev.rend(), SortByTimesSent());
|
||||
sort(myEntries[0].vout.rbegin(), myEntries[0].vout.rend(), SortByTimesSent());
|
||||
|
||||
int nCount1 = 0;
|
||||
int nCount2 = 0;
|
||||
int nMax = max(nTrickleInputsOutputs*3, 15)+3;
|
||||
|
||||
//trickle some of our inputs/outputs
|
||||
BOOST_FOREACH(CTxDSIn& in, myEntries[0].sev) {
|
||||
if(nCount1 < (rand() % nMax)+5){
|
||||
in.nSentTimes++;
|
||||
vin.push_back((CTxIn)in);
|
||||
nCount1++;
|
||||
} else {break;}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(CTxDSOut& out, myEntries[0].vout) {
|
||||
if(nCount2 < (rand() % nMax)+5){
|
||||
out.nSentTimes++;
|
||||
vout.push_back((CTxOut)out);
|
||||
nCount2++;
|
||||
} else {break;}
|
||||
}
|
||||
|
||||
//resubmit some other inputs/outputs from the transaction, so nodes can't tell who's inputs/outputs are whos
|
||||
BOOST_FOREACH(CTxIn& in, finalTransaction.vin)
|
||||
if((rand() % 100) > 75)
|
||||
vin.push_back(in);
|
||||
|
||||
BOOST_FOREACH(CTxOut& out, finalTransaction.vout)
|
||||
if((rand() % 100) > 75)
|
||||
vout.push_back(out);
|
||||
|
||||
//shuffle everything around
|
||||
std::random_shuffle ( vin.begin(), vin.end(), randomizeList);
|
||||
std::random_shuffle ( vout.begin(), vout.end(), randomizeList);
|
||||
|
||||
LogPrintf("CDarksendPool::TrickleInputsOutputs() : Sending %d inputs and %d outputs\n", (int)vin.size(), (int)vout.size());
|
||||
RelayInAnon(vin, vout);
|
||||
nTrickleInputsOutputs++;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2070,7 +2144,6 @@ bool CDarksendPool::IsCompatibleWithSession(int64_t nDenom, CTransaction txColla
|
||||
}
|
||||
|
||||
UpdateState(POOL_STATUS_QUEUE);
|
||||
LogPrintf("Updated 2\n");
|
||||
vecSessionCollateral.push_back(txCollateral);
|
||||
return true;
|
||||
}
|
||||
@ -2135,6 +2208,15 @@ void CDarksendPool::GetDenominationsToString(int nDenom, std::string& strDenom){
|
||||
}
|
||||
}
|
||||
|
||||
int CDarksendPool::GetDenominations(const std::vector<CTxDSOut>& vout){
|
||||
std::vector<CTxOut> vout2;
|
||||
|
||||
BOOST_FOREACH(CTxDSOut out, vout)
|
||||
vout2.push_back(out);
|
||||
|
||||
return GetDenominations(vout2);
|
||||
}
|
||||
|
||||
// return a bitshifted integer representing the denominations in this list
|
||||
int CDarksendPool::GetDenominations(const std::vector<CTxOut>& vout){
|
||||
std::vector<pair<int64_t, int> > denomUsed;
|
||||
@ -2427,16 +2509,25 @@ void CDarksendPool::RelayInAnon(std::vector<CTxIn>& vin, std::vector<CTxOut>& vo
|
||||
}
|
||||
}
|
||||
|
||||
void CDarksendPool::RelayIn(const std::vector<CTxIn>& vin, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxOut>& vout)
|
||||
void CDarksendPool::RelayIn(const std::vector<CTxDSIn>& vin, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxDSOut>& vout)
|
||||
{
|
||||
LOCK(cs_vNodes);
|
||||
|
||||
std::vector<CTxIn> vin2;
|
||||
std::vector<CTxOut> vout2;
|
||||
|
||||
BOOST_FOREACH(CTxDSIn in, vin)
|
||||
vin2.push_back(in);
|
||||
|
||||
BOOST_FOREACH(CTxDSOut out, vout)
|
||||
vout2.push_back(out);
|
||||
|
||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||
{
|
||||
if(!pSubmittedToMasternode) return;
|
||||
if((CNetAddr)darkSendPool.pSubmittedToMasternode->addr != (CNetAddr)pnode->addr) continue;
|
||||
LogPrintf("RelayIn - found master, relaying message - %s \n", pnode->addr.ToString().c_str());
|
||||
pnode->PushMessage("dsi", vin, nAmount, txCollateral, vout);
|
||||
pnode->PushMessage("dsi", vin2, nAmount, txCollateral, vout2);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2455,10 +2546,13 @@ void CDarksendPool::RelayCompletedTransaction(const int sessionID, const bool er
|
||||
}
|
||||
|
||||
bool CDSAnonTx::AddOutput(const CTxOut out){
|
||||
LOCK(cs_darksend);
|
||||
|
||||
if(fDebug) LogPrintf("CDSAnonTx::AddOutput -- new %s\n", out.ToString().substr(0,24).c_str());
|
||||
|
||||
//already have this output
|
||||
if(std::find(vout.begin(), vout.end(), out) != vout.end()) return false;
|
||||
BOOST_FOREACH(CTxOut& out2, vout)
|
||||
if(out2.nValue == out.nValue && out.scriptPubKey == out2.scriptPubKey)
|
||||
return false;
|
||||
|
||||
vout.push_back(out);
|
||||
std::random_shuffle ( vout.begin(), vout.end(), randomizeList);
|
||||
@ -2467,17 +2561,24 @@ bool CDSAnonTx::AddOutput(const CTxOut out){
|
||||
}
|
||||
|
||||
bool CDSAnonTx::AddInput(const CTxIn in){
|
||||
LOCK(cs_darksend);
|
||||
|
||||
if(fDebug) LogPrintf("CDSAnonTx::AddInput -- new %s\n", in.ToString().substr(0,24).c_str());
|
||||
|
||||
//already have this input
|
||||
if(std::find(vin.begin(), vin.end(), in) != vin.end()) return false;
|
||||
BOOST_FOREACH(CTxDSIn& in2, vin)
|
||||
if(in2.prevout == in.prevout && in.nSequence == in2.nSequence)
|
||||
return false;
|
||||
|
||||
vin.push_back(in);
|
||||
std::random_shuffle ( vin.begin(), vin.end(), randomizeList);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CDSAnonTx::AddSig(const CTxIn newIn){
|
||||
LOCK(cs_darksend);
|
||||
|
||||
if(fDebug) LogPrintf("CDSAnonTx::AddSig -- new %s\n", newIn.ToString().substr(0,24).c_str());
|
||||
|
||||
BOOST_FOREACH(CTxDSIn& in, vin){
|
||||
@ -2511,6 +2612,7 @@ void ThreadCheckDarkSendPool()
|
||||
//LogPrintf("ThreadCheckDarkSendPool::check timeout\n");
|
||||
|
||||
if(c % 10 == 0) darkSendPool.Check();
|
||||
if(c % 3 == 0) darkSendPool.TrickleInputsOutputs();
|
||||
darkSendPool.CheckTimeout();
|
||||
darkSendPool.CheckForCompleteQueue();
|
||||
|
||||
|
@ -63,6 +63,7 @@ class CTxDSIn : public CTxIn
|
||||
{
|
||||
public:
|
||||
bool fHasSig; // flag to indicate if signed
|
||||
int nSentTimes; //times we've sent this anonymously
|
||||
|
||||
CTxDSIn(const CTxIn& in)
|
||||
{
|
||||
@ -70,9 +71,25 @@ public:
|
||||
scriptSig = in.scriptSig;
|
||||
prevPubKey = in.prevPubKey;
|
||||
nSequence = in.nSequence;
|
||||
nSentTimes = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/** Holds an Darksend output
|
||||
*/
|
||||
class CTxDSOut : public CTxOut
|
||||
{
|
||||
public:
|
||||
int nSentTimes; //times we've sent this anonymously
|
||||
|
||||
CTxDSOut(const CTxOut& out)
|
||||
{
|
||||
nValue = out.nValue;
|
||||
nRounds = out.nRounds;
|
||||
scriptPubKey = out.scriptPubKey;
|
||||
nSentTimes = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/** A clients transaction in the Darksend pool
|
||||
* -- holds the input/output mapping for each user in the pool
|
||||
@ -81,10 +98,10 @@ class CDarkSendEntry
|
||||
{
|
||||
public:
|
||||
bool isSet;
|
||||
std::vector<CTxIn> sev;
|
||||
std::vector<CTxDSIn> sev;
|
||||
std::vector<CTxDSOut> vout;
|
||||
int64_t amount;
|
||||
CTransaction collateral;
|
||||
std::vector<CTxOut> vout;
|
||||
CTransaction txSupporting;
|
||||
int64_t addedTime; // time in UTC milliseconds
|
||||
|
||||
@ -100,8 +117,12 @@ public:
|
||||
{
|
||||
if(isSet){return false;}
|
||||
|
||||
sev = vinIn;
|
||||
vout = voutIn;
|
||||
BOOST_FOREACH(const CTxIn& in, vinIn)
|
||||
sev.push_back(in);
|
||||
|
||||
BOOST_FOREACH(const CTxOut& out, voutIn)
|
||||
vout.push_back(out);
|
||||
|
||||
amount = amountIn;
|
||||
collateral = collateralIn;
|
||||
isSet = true;
|
||||
@ -314,7 +335,7 @@ public:
|
||||
vector<unsigned char> vchMasternodeRelaySig;
|
||||
int nMasternodeBlockHeight;
|
||||
std::string strMasternodeSharedKey;
|
||||
bool fResentInputsOutputs;
|
||||
int nTrickleInputsOutputs;
|
||||
|
||||
CDarksendPool()
|
||||
{
|
||||
@ -328,7 +349,7 @@ public:
|
||||
minBlockSpacing = 1;
|
||||
lastNewBlock = 0;
|
||||
strMasternodeSharedKey = "";
|
||||
fResentInputsOutputs = false;
|
||||
nTrickleInputsOutputs = 0;
|
||||
|
||||
SetNull();
|
||||
}
|
||||
@ -367,7 +388,7 @@ public:
|
||||
bool SetCollateralAddress(std::string strAddress);
|
||||
void Reset();
|
||||
bool Downgrade();
|
||||
bool ResendMissingInputsOutputs();
|
||||
bool TrickleInputsOutputs();
|
||||
|
||||
void SetNull(bool clearEverything=false);
|
||||
|
||||
@ -507,6 +528,8 @@ public:
|
||||
|
||||
/// Get the denominations for a list of outputs (returns a bitshifted integer)
|
||||
int GetDenominations(const std::vector<CTxOut>& vout);
|
||||
int GetDenominations(const std::vector<CTxDSOut>& vout);
|
||||
|
||||
void GetDenominationsToString(int nDenom, std::string& strDenom);
|
||||
|
||||
/// Get the denominations for a specific amount of darkcoin.
|
||||
@ -521,7 +544,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<CTxIn>& vin, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxOut>& 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 std::string error="");
|
||||
void RelayCompletedTransaction(const int sessionID, const bool error, const std::string errorMessage);
|
||||
};
|
||||
|
@ -208,6 +208,8 @@ uint256 CMasternode::CalculateScore(int mod, int64_t nBlockHeight)
|
||||
|
||||
void CMasternode::Check()
|
||||
{
|
||||
LOCK(cs_main);
|
||||
|
||||
//once spent, stop doing the checks
|
||||
if(activeState == MASTERNODE_VIN_SPENT) return;
|
||||
|
||||
|
@ -436,6 +436,9 @@ CMasternode* CMasternodeMan::GetMasternodeByRank(int nRank, int64_t nBlockHeight
|
||||
|
||||
void CMasternodeMan::ProcessMasternodeConnections()
|
||||
{
|
||||
//we don't care about this for testing
|
||||
if(TestNet() || RegTest()) return;
|
||||
|
||||
LOCK(cs_vNodes);
|
||||
|
||||
if(!darkSendPool.pSubmittedToMasternode) return;
|
||||
|
Loading…
Reference in New Issue
Block a user