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_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])

View File

@ -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

View File

@ -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();

View File

@ -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);
};

View File

@ -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;

View File

@ -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;