Merge 'upstream/v0.11.2.x' into v0.11.2.x

This commit is contained in:
crowning2 2015-03-07 16:48:44 +01:00
commit 59bb5bec12
6 changed files with 160 additions and 30 deletions

View File

@ -3,7 +3,7 @@ AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 0) define(_CLIENT_VERSION_MAJOR, 0)
define(_CLIENT_VERSION_MINOR, 11) define(_CLIENT_VERSION_MINOR, 11)
define(_CLIENT_VERSION_REVISION, 2) define(_CLIENT_VERSION_REVISION, 2)
define(_CLIENT_VERSION_BUILD, 1) define(_CLIENT_VERSION_BUILD, 2)
define(_CLIENT_VERSION_IS_RELEASE, true) define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2015) define(_COPYRIGHT_YEAR, 2015)
AC_INIT([Darkcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@darkcoin.io],[darkcoin]) AC_INIT([Darkcoin Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[info@darkcoin.io],[darkcoin])

View File

@ -12,7 +12,7 @@
#define CLIENT_VERSION_MAJOR 0 #define CLIENT_VERSION_MAJOR 0
#define CLIENT_VERSION_MINOR 11 #define CLIENT_VERSION_MINOR 11
#define CLIENT_VERSION_REVISION 2 #define CLIENT_VERSION_REVISION 2
#define CLIENT_VERSION_BUILD 0 #define CLIENT_VERSION_BUILD 2

View File

@ -173,6 +173,11 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
return; return;
} }
if(state != POOL_STATUS_IDLE){
LogPrintf("dsr -- wrong state to relay! \n");
return;
}
CDarkSendRelay dsr; CDarkSendRelay dsr;
vRecv >> dsr; vRecv >> dsr;
@ -450,8 +455,6 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
bool success = false; bool success = false;
int count = 0; int count = 0;
LogPrintf(" -- sigs count %d %d\n", (int)sigs.size(), count);
BOOST_FOREACH(const CTxIn item, sigs) BOOST_FOREACH(const CTxIn item, sigs)
{ {
if(AddScriptSig(item)) success = true; if(AddScriptSig(item)) success = true;
@ -621,7 +624,7 @@ void CDarksendPool::SetNull(bool clearEverything){
entries.clear(); entries.clear();
anonTx.vin.clear(); anonTx.vin.clear();
anonTx.vout.clear(); anonTx.vout.clear();
fResentInputsOutputs = false; nTrickleInputsOutputs = 0;
state = POOL_STATUS_IDLE; state = POOL_STATUS_IDLE;
@ -719,6 +722,7 @@ void CDarksendPool::Check()
} }
// shuffle the outputs for improved anonymity // 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); std::random_shuffle ( txNew.vout.begin(), txNew.vout.end(), randomizeList);
} else { } else {
BOOST_FOREACH(CTxDSIn& v, anonTx.vin) BOOST_FOREACH(CTxDSIn& v, anonTx.vin)
@ -729,7 +733,7 @@ void CDarksendPool::Check()
} }
if(fDebug) LogPrintf("Transaction 1: %s\n", txNew.ToString().c_str()); if(fDebug) LogPrintf("Transaction 1: %s\n", txNew.ToString().c_str());
SignFinalTransaction(txNew, NULL); finalTransaction = txNew;
// request signatures from clients // request signatures from clients
RelayFinalTransaction(sessionID, finalTransaction); RelayFinalTransaction(sessionID, finalTransaction);
@ -765,7 +769,7 @@ void CDarksendPool::CheckFinalTransaction()
if(fDebug) LogPrintf("Transaction 2: %s\n", txNew.ToString().c_str()); if(fDebug) LogPrintf("Transaction 2: %s\n", txNew.ToString().c_str());
// See if the transaction is valid // See if the transaction is valid
if (!txNew.AcceptToMemoryPool(true)) if (!txNew.AcceptToMemoryPool(false))
{ {
if(nCountAttempts > 10) { if(nCountAttempts > 10) {
LogPrintf("CDarksendPool::Check() - CommitTransaction : Error: Transaction not valid\n"); LogPrintf("CDarksendPool::Check() - CommitTransaction : Error: Transaction not valid\n");
@ -939,7 +943,7 @@ void CDarksendPool::ChargeFees(){
CWalletTx wtxCollateral = CWalletTx(pwalletMain, v.collateral); CWalletTx wtxCollateral = CWalletTx(pwalletMain, v.collateral);
// Broadcast // Broadcast
if (!wtxCollateral.AcceptToMemoryPool(true)) if (!wtxCollateral.AcceptToMemoryPool(false))
{ {
// This must not fail. The transaction has already been signed and recorded. // This must not fail. The transaction has already been signed and recorded.
LogPrintf("CDarksendPool::ChargeFees() : Error: Transaction not valid"); LogPrintf("CDarksendPool::ChargeFees() : Error: Transaction not valid");
@ -1393,7 +1397,7 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
myEntries.push_back(e); myEntries.push_back(e);
// submit inputs/outputs through relays // submit inputs/outputs through relays
RelayInAnon(vin, vout); TrickleInputsOutputs();
Check(); Check();
} }
@ -1433,7 +1437,6 @@ bool CDarksendPool::StatusUpdate(int newState, int newEntriesCount, int newAccep
sessionFoundMasternode = true; sessionFoundMasternode = true;
//wait for other users. Masternode will report when ready //wait for other users. Masternode will report when ready
UpdateState(POOL_STATUS_QUEUE); UpdateState(POOL_STATUS_QUEUE);
LogPrintf("Updated 1\n");
} else if (newAccepted == 0 && sessionID == 0 && !sessionFoundMasternode) { } else if (newAccepted == 0 && sessionID == 0 && !sessionFoundMasternode) {
LogPrintf("CDarksendPool::StatusUpdate - entry not accepted by Masternode \n"); LogPrintf("CDarksendPool::StatusUpdate - entry not accepted by Masternode \n");
UnlockCoins(); 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 // If we refuse to sign, it's possible we'll be charged collateral
// //
bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNode* node){ bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNode* node){
if(fMasterNode) return false;
if(fDebug) LogPrintf("CDarksendPool::SignFinalTransaction - Got Finalized Transaction - fSubmitAnonymousFailed %d\n", fSubmitAnonymousFailed); if(fDebug) LogPrintf("CDarksendPool::SignFinalTransaction - Got Finalized Transaction - fSubmitAnonymousFailed %d\n", fSubmitAnonymousFailed);
finalTransaction = finalTransactionNew; 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? 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; int foundOutputs = 0;
int64_t nValue1 = 0; int64_t nValue1 = 0;
int64_t nValue2 = 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 // 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. // 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); LogPrintf("CDarksendPool::Sign - My entries are not correct! Refusing to sign. %d entries %d target. \n", foundOutputs, targetOuputs);
ResendMissingInputsOutputs(); TrickleInputsOutputs();
return false; return false;
} }
@ -1517,6 +1526,15 @@ bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNod
} }
if(!fSubmitAnonymousFailed){ 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); RelaySignaturesAnon(sigs);
} else { } else {
// push all of our signatures to the Masternode // push all of our signatures to the Masternode
@ -1851,6 +1869,7 @@ bool CDarksendPool::PrepareDarksendDenominate()
bool CDarksendPool::Downgrade() bool CDarksendPool::Downgrade()
{ {
if(fSubmitAnonymousFailed) return true; if(fSubmitAnonymousFailed) return true;
if(myEntries.size() == 0) return false; if(myEntries.size() == 0) return false;
@ -1863,17 +1882,72 @@ bool CDarksendPool::Downgrade()
return true; 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(); Downgrade();
return true; return true;
} }
if(myEntries.size() == 0) return false; if(myEntries.size() == 0) return false;
LogPrintf("CDarksendPool::Downgrade() : Downgrading and submitting directly\n"); std::vector<CTxIn> vin;
RelayInAnon(myEntries[0].sev, myEntries[0].vout); std::vector<CTxOut> vout;
fResentInputsOutputs = true;
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; return true;
} }
@ -2070,7 +2144,6 @@ bool CDarksendPool::IsCompatibleWithSession(int64_t nDenom, CTransaction txColla
} }
UpdateState(POOL_STATUS_QUEUE); UpdateState(POOL_STATUS_QUEUE);
LogPrintf("Updated 2\n");
vecSessionCollateral.push_back(txCollateral); vecSessionCollateral.push_back(txCollateral);
return true; 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 // return a bitshifted integer representing the denominations in this list
int CDarksendPool::GetDenominations(const std::vector<CTxOut>& vout){ int CDarksendPool::GetDenominations(const std::vector<CTxOut>& vout){
std::vector<pair<int64_t, int> > denomUsed; 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); 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) BOOST_FOREACH(CNode* pnode, vNodes)
{ {
if(!pSubmittedToMasternode) return; if(!pSubmittedToMasternode) return;
if((CNetAddr)darkSendPool.pSubmittedToMasternode->addr != (CNetAddr)pnode->addr) continue; if((CNetAddr)darkSendPool.pSubmittedToMasternode->addr != (CNetAddr)pnode->addr) continue;
LogPrintf("RelayIn - found master, relaying message - %s \n", pnode->addr.ToString().c_str()); 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){ bool CDSAnonTx::AddOutput(const CTxOut out){
LOCK(cs_darksend);
if(fDebug) LogPrintf("CDSAnonTx::AddOutput -- new %s\n", out.ToString().substr(0,24).c_str()); if(fDebug) LogPrintf("CDSAnonTx::AddOutput -- new %s\n", out.ToString().substr(0,24).c_str());
//already have this output BOOST_FOREACH(CTxOut& out2, vout)
if(std::find(vout.begin(), vout.end(), out) != vout.end()) return false; if(out2.nValue == out.nValue && out.scriptPubKey == out2.scriptPubKey)
return false;
vout.push_back(out); vout.push_back(out);
std::random_shuffle ( vout.begin(), vout.end(), randomizeList); std::random_shuffle ( vout.begin(), vout.end(), randomizeList);
@ -2467,17 +2561,24 @@ bool CDSAnonTx::AddOutput(const CTxOut out){
} }
bool CDSAnonTx::AddInput(const CTxIn in){ bool CDSAnonTx::AddInput(const CTxIn in){
LOCK(cs_darksend);
if(fDebug) LogPrintf("CDSAnonTx::AddInput -- new %s\n", in.ToString().substr(0,24).c_str()); if(fDebug) LogPrintf("CDSAnonTx::AddInput -- new %s\n", in.ToString().substr(0,24).c_str());
//already have this input //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); vin.push_back(in);
std::random_shuffle ( vin.begin(), vin.end(), randomizeList);
return true; return true;
} }
bool CDSAnonTx::AddSig(const CTxIn newIn){ bool CDSAnonTx::AddSig(const CTxIn newIn){
LOCK(cs_darksend);
if(fDebug) LogPrintf("CDSAnonTx::AddSig -- new %s\n", newIn.ToString().substr(0,24).c_str()); if(fDebug) LogPrintf("CDSAnonTx::AddSig -- new %s\n", newIn.ToString().substr(0,24).c_str());
BOOST_FOREACH(CTxDSIn& in, vin){ BOOST_FOREACH(CTxDSIn& in, vin){
@ -2511,6 +2612,7 @@ void ThreadCheckDarkSendPool()
//LogPrintf("ThreadCheckDarkSendPool::check timeout\n"); //LogPrintf("ThreadCheckDarkSendPool::check timeout\n");
if(c % 10 == 0) darkSendPool.Check(); if(c % 10 == 0) darkSendPool.Check();
if(c % 3 == 0) darkSendPool.TrickleInputsOutputs();
darkSendPool.CheckTimeout(); darkSendPool.CheckTimeout();
darkSendPool.CheckForCompleteQueue(); darkSendPool.CheckForCompleteQueue();

View File

@ -63,6 +63,7 @@ class CTxDSIn : public CTxIn
{ {
public: public:
bool fHasSig; // flag to indicate if signed bool fHasSig; // flag to indicate if signed
int nSentTimes; //times we've sent this anonymously
CTxDSIn(const CTxIn& in) CTxDSIn(const CTxIn& in)
{ {
@ -70,9 +71,25 @@ public:
scriptSig = in.scriptSig; scriptSig = in.scriptSig;
prevPubKey = in.prevPubKey; prevPubKey = in.prevPubKey;
nSequence = in.nSequence; 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 /** A clients transaction in the Darksend pool
* -- holds the input/output mapping for each user in the pool * -- holds the input/output mapping for each user in the pool
@ -81,10 +98,10 @@ class CDarkSendEntry
{ {
public: public:
bool isSet; bool isSet;
std::vector<CTxIn> sev; std::vector<CTxDSIn> sev;
std::vector<CTxDSOut> vout;
int64_t amount; int64_t amount;
CTransaction collateral; CTransaction collateral;
std::vector<CTxOut> vout;
CTransaction txSupporting; CTransaction txSupporting;
int64_t addedTime; // time in UTC milliseconds int64_t addedTime; // time in UTC milliseconds
@ -100,8 +117,12 @@ public:
{ {
if(isSet){return false;} if(isSet){return false;}
sev = vinIn; BOOST_FOREACH(const CTxIn& in, vinIn)
vout = voutIn; sev.push_back(in);
BOOST_FOREACH(const CTxOut& out, voutIn)
vout.push_back(out);
amount = amountIn; amount = amountIn;
collateral = collateralIn; collateral = collateralIn;
isSet = true; isSet = true;
@ -314,7 +335,7 @@ public:
vector<unsigned char> vchMasternodeRelaySig; vector<unsigned char> vchMasternodeRelaySig;
int nMasternodeBlockHeight; int nMasternodeBlockHeight;
std::string strMasternodeSharedKey; std::string strMasternodeSharedKey;
bool fResentInputsOutputs; int nTrickleInputsOutputs;
CDarksendPool() CDarksendPool()
{ {
@ -328,7 +349,7 @@ public:
minBlockSpacing = 1; minBlockSpacing = 1;
lastNewBlock = 0; lastNewBlock = 0;
strMasternodeSharedKey = ""; strMasternodeSharedKey = "";
fResentInputsOutputs = false; nTrickleInputsOutputs = 0;
SetNull(); SetNull();
} }
@ -367,7 +388,7 @@ public:
bool SetCollateralAddress(std::string strAddress); bool SetCollateralAddress(std::string strAddress);
void Reset(); void Reset();
bool Downgrade(); bool Downgrade();
bool ResendMissingInputsOutputs(); bool TrickleInputsOutputs();
void SetNull(bool clearEverything=false); void SetNull(bool clearEverything=false);
@ -507,6 +528,8 @@ public:
/// Get the denominations for a list of outputs (returns a bitshifted integer) /// Get the denominations for a list of outputs (returns a bitshifted integer)
int GetDenominations(const std::vector<CTxOut>& vout); int GetDenominations(const std::vector<CTxOut>& vout);
int GetDenominations(const std::vector<CTxDSOut>& vout);
void GetDenominationsToString(int nDenom, std::string& strDenom); void GetDenominationsToString(int nDenom, std::string& strDenom);
/// Get the denominations for a specific amount of darkcoin. /// Get the denominations for a specific amount of darkcoin.
@ -521,7 +544,7 @@ public:
void RelayFinalTransaction(const int sessionID, const CTransaction& txNew); void RelayFinalTransaction(const int sessionID, const CTransaction& txNew);
void RelaySignaturesAnon(std::vector<CTxIn>& vin); void RelaySignaturesAnon(std::vector<CTxIn>& vin);
void RelayInAnon(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout); 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 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); void RelayCompletedTransaction(const int sessionID, const bool error, const std::string errorMessage);
}; };

View File

@ -208,6 +208,8 @@ uint256 CMasternode::CalculateScore(int mod, int64_t nBlockHeight)
void CMasternode::Check() void CMasternode::Check()
{ {
LOCK(cs_main);
//once spent, stop doing the checks //once spent, stop doing the checks
if(activeState == MASTERNODE_VIN_SPENT) return; if(activeState == MASTERNODE_VIN_SPENT) return;

View File

@ -436,6 +436,9 @@ CMasternode* CMasternodeMan::GetMasternodeByRank(int nRank, int64_t nBlockHeight
void CMasternodeMan::ProcessMasternodeConnections() void CMasternodeMan::ProcessMasternodeConnections()
{ {
//we don't care about this for testing
if(TestNet() || RegTest()) return;
LOCK(cs_vNodes); LOCK(cs_vNodes);
if(!darkSendPool.pSubmittedToMasternode) return; if(!darkSendPool.pSubmittedToMasternode) return;