Reverting some DS changes

- Some changes caused instability of DS, this should fix that.
This commit is contained in:
Evan Duffield 2015-04-05 23:52:37 -07:00
parent e29b66d1dc
commit f0192b1bb3
3 changed files with 35 additions and 525 deletions

View File

@ -130,9 +130,6 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
} }
if(state == POOL_STATUS_QUEUE){ if(state == POOL_STATUS_QUEUE){
//save the relay signature info
AddRelaySignature(dsq.vchRelaySig, dsq.nBlockHeight, dsq.strSharedKey);
if (fDebug) LogPrintf("Darksend queue is ready - %s\n", addr.ToString().c_str()); if (fDebug) LogPrintf("Darksend queue is ready - %s\n", addr.ToString().c_str());
PrepareDarksendDenominate(); PrepareDarksendDenominate();
} }
@ -158,138 +155,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
dsq.time = GetTime(); dsq.time = GetTime();
} }
} else if (strCommand == "dsr") { //Darksend Relay } else if (strCommand == "dsi") { //DarkSend vIn
//* Ask a Masternode to relay an anonymous output to another Masternode *//
std::string error = "";
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
LogPrintf("dsr -- incompatible version! \n");
return;
}
if(!fMasterNode){
LogPrintf("dsr -- not a Masternode! \n");
return;
}
CDarkSendRelay dsr;
vRecv >> dsr;
if(chainActive.Tip()->nHeight - dsr.nBlockHeight > 10) return;
if(dsr.nRelayType != DARKSEND_RELAY_IN &&
dsr.nRelayType != DARKSEND_RELAY_OUT &&
dsr.nRelayType != DARKSEND_RELAY_SIG) return;
if(dsr.in == CTxIn() && dsr.nRelayType == DARKSEND_RELAY_IN) return;
if(dsr.out == CTxOut() && dsr.nRelayType == DARKSEND_RELAY_OUT) return;
if(dsr.in == CTxIn() && dsr.nRelayType == DARKSEND_RELAY_SIG) return;
CMasternode* pmn = mnodeman.Find(dsr.vinMasternode);
if(pmn == NULL){
LogPrintf("dsr -- unknown Masternode! %s \n", dsr.vinMasternode.ToString().c_str());
return;
}
/*
For added DDOS protection, clients can only relay through 20 nodes per block.
*/
int rank = mnodeman.GetMasternodeRank(activeMasternode.vin, dsr.nBlockHeight, MIN_POOL_PEER_PROTO_VERSION);
if(rank == -1 || rank > 20){
LogPrintf("dsr -- invalid relay Masternode! %s \n", activeMasternode.vin.ToString().c_str());
return;
}
//check the signature from the target Masternode
std::string strMessage = boost::lexical_cast<std::string>(dsr.nBlockHeight);
std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pmn->pubkey2, dsr.vchSig, strMessage, errorMessage)){
LogPrintf("dsr - Got bad Masternode address signature\n");
Misbehaving(pfrom->GetId(), 100);
return;
}
//connect and deliver the message
if(ConnectNode((CAddress)pmn->addr, NULL, true)){
CNode* pNode = FindNode(pmn->addr);
if(pNode)
{
pNode->PushMessage("dsai", dsr);
return;
}
}
} else if (strCommand == "dsai") { //Darksend Anonymous Item (Input/Output/Sig)
std::string error = "";
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
LogPrintf("dsai -- incompatible version! \n");
return;
}
if(!fMasterNode){
LogPrintf("dsai -- not a Masternode! \n");
return;
}
CDarkSendRelay dsr;
vRecv >> dsr;
if(chainActive.Tip()->nHeight - dsr.nBlockHeight > 10) return;
if(darkSendPool.strMasternodeSharedKey == "") return;
if(dsr.nRelayType != DARKSEND_RELAY_IN &&
dsr.nRelayType != DARKSEND_RELAY_OUT &&
dsr.nRelayType != DARKSEND_RELAY_SIG) return;
if(dsr.in == CTxIn() && dsr.nRelayType == DARKSEND_RELAY_IN) return;
if(dsr.out == CTxOut() && dsr.nRelayType == DARKSEND_RELAY_OUT) return;
if(dsr.in == CTxIn() && dsr.nRelayType == DARKSEND_RELAY_SIG) return;
CMasternode* pmn = mnodeman.Find(dsr.vinMasternode);
if(pmn == NULL){
LogPrintf("dsai -- unknown Masternode! %s \n", dsr.vinMasternode.ToString().c_str());
return;
}
//check the signature from the target Masternode
std::string strMessage = boost::lexical_cast<std::string>(dsr.nBlockHeight);
std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(pmn->pubkey2, dsr.vchSig, strMessage, errorMessage)){
LogPrintf("dsai - Got bad Masternode address signature\n");
Misbehaving(pfrom->GetId(), 100);
return;
}
if(!dsr.VerifyMessage(darkSendPool.strMasternodeSharedKey)){
LogPrintf("dsai - Got bad shared key signature\n");
Misbehaving(pfrom->GetId(), 30);
return;
}
//do we have enough users in the current session?
if(!IsSessionReady()){
LogPrintf("dsai -- session not complete! \n");
return;
}
switch(dsr.nRelayType){
case DARKSEND_RELAY_IN:
anonTx.AddInput(dsr.in);
break;
case DARKSEND_RELAY_OUT:
anonTx.AddOutput(dsr.out);
break;
case DARKSEND_RELAY_SIG:
anonTx.AddSig(dsr.in);
break;
}
// relay to all peers that an entry was added to the pool successfully.
Check();
} else if (strCommand == "dsi") { //Darksend vIn
std::string error = ""; std::string error = "";
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) { if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
LogPrintf("dsi -- incompatible version! \n"); LogPrintf("dsi -- incompatible version! \n");
@ -617,9 +483,6 @@ void CDarksendPool::SetNull(bool clearEverything){
finalTransaction.vout.clear(); finalTransaction.vout.clear();
entries.clear(); entries.clear();
anonTx.vin.clear();
anonTx.vout.clear();
nTrickleInputsOutputs = 0;
state = POOL_STATUS_IDLE; state = POOL_STATUS_IDLE;
@ -629,7 +492,6 @@ void CDarksendPool::SetNull(bool clearEverything){
lastEntryAccepted = 0; lastEntryAccepted = 0;
countEntriesAccepted = 0; countEntriesAccepted = 0;
lastNewBlock = 0; lastNewBlock = 0;
fSubmitAnonymousFailed = false;
sessionUsers = 0; sessionUsers = 0;
sessionDenom = 0; sessionDenom = 0;
@ -637,18 +499,11 @@ void CDarksendPool::SetNull(bool clearEverything){
vecSessionCollateral.clear(); vecSessionCollateral.clear();
txCollateral = CTransaction(); txCollateral = CTransaction();
vchMasternodeRelaySig.clear();
nMasternodeBlockHeight = 0;
if(clearEverything){ if(clearEverything){
myEntries.clear(); myEntries.clear();
sessionID = 0; sessionID = 0;
} }
//automatically downgrade for 11.2, blinding will be supported in 11.3/12.0
nTrickleInputsOutputs = INT_MAX;
Downgrade();
// -- seed random number generator (used for ordering output lists) // -- seed random number generator (used for ordering output lists)
unsigned int seed = 0; unsigned int seed = 0;
RAND_bytes((unsigned char*)&seed, sizeof(seed)); RAND_bytes((unsigned char*)&seed, sizeof(seed));
@ -686,14 +541,10 @@ void CDarksendPool::Check()
//printf("CDarksendPool::Check() %d - %d - %d\n", state, anonTx.CountEntries(), GetTimeMillis()-lastTimeChanged); //printf("CDarksendPool::Check() %d - %d - %d\n", state, anonTx.CountEntries(), GetTimeMillis()-lastTimeChanged);
// If entries is full, then move on to the next phase // If entries is full, then move on to the next phase
if(state == POOL_STATUS_ACCEPTING_ENTRIES && ( if(state == POOL_STATUS_ACCEPTING_ENTRIES && (int)entries.size() >= GetMaxPoolTransactions())
(int)entries.size() >= GetMaxPoolTransactions() ||
(GetTimeMillis()-lastTimeChanged > 5000 && anonTx.CountEntries() > GetMaxPoolTransactions()*5)
))
{ {
if(fDebug) LogPrintf("CDarksendPool::Check() -- TRYING TRANSACTION \n"); if(fDebug) LogPrintf("CDarksendPool::Check() -- TRYING TRANSACTION \n");
UpdateState(POOL_STATUS_FINALIZE_TRANSACTION); UpdateState(POOL_STATUS_FINALIZE_TRANSACTION);
nCountAttempts++;
} }
// create the finalized transaction for distribution to the clients // create the finalized transaction for distribution to the clients
@ -705,26 +556,19 @@ void CDarksendPool::Check()
CTransaction txNew; CTransaction txNew;
// make our new transaction // make our new transaction
if((int)entries.size() >= GetMaxPoolTransactions()) { for(unsigned int i = 0; i < entries.size(); i++){
for(unsigned int i = 0; i < entries.size(); i++){ BOOST_FOREACH(const CTxOut& v, entries[i].vout)
BOOST_FOREACH(const CTxOut& v, entries[i].vout)
txNew.vout.push_back(v);
BOOST_FOREACH(const CTxDSIn& s, entries[i].sev)
txNew.vin.push_back(s);
}
// 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)
txNew.vin.push_back((CTxIn)v);
BOOST_FOREACH(CTxOut& v, anonTx.vout)
txNew.vout.push_back(v); txNew.vout.push_back(v);
BOOST_FOREACH(const CTxDSIn& s, entries[i].sev)
txNew.vin.push_back(s);
} }
// 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);
if(fDebug) LogPrintf("Transaction 1: %s\n", txNew.ToString().c_str()); if(fDebug) LogPrintf("Transaction 1: %s\n", txNew.ToString().c_str());
finalTransaction = txNew; finalTransaction = txNew;
@ -733,8 +577,6 @@ void CDarksendPool::Check()
} }
} }
//printf("Signing Status %d %d\n", state == POOL_STATUS_SIGNING, SignaturesComplete());
// If we have all of the signatures, try to compile the transaction // If we have all of the signatures, try to compile the transaction
if(state == POOL_STATUS_SIGNING && SignaturesComplete()) { if(state == POOL_STATUS_SIGNING && SignaturesComplete()) {
if(fDebug) LogPrintf("CDarksendPool::Check() -- SIGNING\n"); if(fDebug) LogPrintf("CDarksendPool::Check() -- SIGNING\n");
@ -764,17 +606,13 @@ void CDarksendPool::CheckFinalTransaction()
// See if the transaction is valid // See if the transaction is valid
if (!txNew.AcceptToMemoryPool(false)) if (!txNew.AcceptToMemoryPool(false))
{ {
if(nCountAttempts > 60) { LogPrintf("CDarksendPool::Check() - CommitTransaction : Error: Transaction not valid\n");
LogPrintf("CDarksendPool::Check() - CommitTransaction : Error: Transaction not valid\n"); SetNull();
SetNull(); pwalletMain->Lock();
pwalletMain->Lock();
}
// not much we can do in this case] // not much we can do in this case]
UpdateState(POOL_STATUS_ACCEPTING_ENTRIES); UpdateState(POOL_STATUS_ACCEPTING_ENTRIES);
RelayCompletedTransaction(sessionID, true, "Transaction not valid, please try again");
if(!fSubmitAnonymousFailed && nCountAttempts > 30)
fSubmitAnonymousFailed = true;
return; return;
} }
@ -1039,13 +877,6 @@ void CDarksendPool::CheckTimeout(){
c++; c++;
} }
if(!fSubmitAnonymousFailed && !fMasterNode && state == POOL_STATUS_ACCEPTING_ENTRIES){
if(GetTimeMillis()-lastTimeChanged >= (DARKSEND_DOWNGRADE_TIMEOUT*1000)+addLagTime){
lastTimeChanged = GetTimeMillis();
Downgrade();
}
}
if(GetTimeMillis()-lastTimeChanged >= (DARKSEND_QUEUE_TIMEOUT*1000)+addLagTime){ if(GetTimeMillis()-lastTimeChanged >= (DARKSEND_QUEUE_TIMEOUT*1000)+addLagTime){
lastTimeChanged = GetTimeMillis(); lastTimeChanged = GetTimeMillis();
@ -1068,7 +899,6 @@ void CDarksendPool::CheckTimeout(){
} }
if(state == POOL_STATUS_SIGNING && GetTimeMillis()-lastTimeChanged >= (DARKSEND_SIGNING_TIMEOUT*1000)+addLagTime ) { if(state == POOL_STATUS_SIGNING && GetTimeMillis()-lastTimeChanged >= (DARKSEND_SIGNING_TIMEOUT*1000)+addLagTime ) {
if(fSubmitAnonymousFailed){
if(fDebug) LogPrintf("CDarksendPool::CheckTimeout() -- Session timed out -- restting\n"); if(fDebug) LogPrintf("CDarksendPool::CheckTimeout() -- Session timed out -- restting\n");
ChargeFees(); ChargeFees();
SetNull(); SetNull();
@ -1077,13 +907,6 @@ void CDarksendPool::CheckTimeout(){
UpdateState(POOL_STATUS_ERROR); UpdateState(POOL_STATUS_ERROR);
lastMessage = _("Signing timed out, please resubmit."); lastMessage = _("Signing timed out, please resubmit.");
} else { //Downgrade and try again
Downgrade();
finalTransaction.vin.clear();
finalTransaction.vout.clear();
UpdateState(POOL_STATUS_ACCEPTING_ENTRIES);
lastMessage = _("Downgrading and trying again.");
}
} }
} }
@ -1099,21 +922,13 @@ void CDarksendPool::CheckForCompleteQueue(){
// which is the active state right before merging the transaction // which is the active state right before merging the transaction
// //
if(state == POOL_STATUS_QUEUE && sessionUsers == GetMaxPoolTransactions()) { if(state == POOL_STATUS_QUEUE && sessionUsers == GetMaxPoolTransactions()) {
LogPrintf("Q ready");
UpdateState(POOL_STATUS_ACCEPTING_ENTRIES); UpdateState(POOL_STATUS_ACCEPTING_ENTRIES);
if(strMasternodeSharedKey == ""){
CKey secret;
secret.MakeNewKey(false);
strMasternodeSharedKey = CBitcoinSecret(secret).ToString();
}
CDarksendQueue dsq; CDarksendQueue dsq;
dsq.nDenom = sessionDenom; dsq.nDenom = sessionDenom;
dsq.vin = activeMasternode.vin; dsq.vin = activeMasternode.vin;
dsq.time = GetTime(); dsq.time = GetTime();
dsq.ready = true; dsq.ready = true;
dsq.SetSharedKey(strMasternodeSharedKey);
dsq.Sign(); dsq.Sign();
dsq.Relay(); dsq.Relay();
} }
@ -1299,13 +1114,6 @@ bool CDarksendPool::AddScriptSig(const CTxIn& newVin){
// Check to make sure everything is signed // Check to make sure everything is signed
bool CDarksendPool::SignaturesComplete(){ bool CDarksendPool::SignaturesComplete(){
bool fFoundIncomplete = false;
BOOST_FOREACH(CTxDSIn in, anonTx.vin){
if(!in.fHasSig)
fFoundIncomplete = true;
}
if(fFoundIncomplete == false) return true;
BOOST_FOREACH(const CDarkSendEntry& v, entries) { BOOST_FOREACH(const CDarkSendEntry& v, entries) {
BOOST_FOREACH(const CTxDSIn& s, v.sev){ BOOST_FOREACH(const CTxDSIn& s, v.sev){
if(!s.fHasSig) return false; if(!s.fHasSig) return false;
@ -1388,9 +1196,7 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
e.Add(vin, amount, txCollateral, vout); e.Add(vin, amount, txCollateral, vout);
myEntries.push_back(e); myEntries.push_back(e);
// submit inputs/outputs through relays RelayIn(myEntries[0].sev, myEntries[0].amount, txCollateral, myEntries[0].vout);
TrickleInputsOutputs();
Check(); Check();
} }
@ -1448,7 +1254,6 @@ bool CDarksendPool::StatusUpdate(int newState, int newEntriesCount, int newAccep
// //
bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNode* node){ bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNode* node){
if(fMasterNode) return false; if(fMasterNode) return false;
if(fDebug) LogPrintf("CDarksendPool::SignFinalTransaction - Got Finalized Transaction - fSubmitAnonymousFailed %d\n", fSubmitAnonymousFailed);
finalTransaction = finalTransactionNew; finalTransaction = finalTransactionNew;
LogPrintf("CDarksendPool::SignFinalTransaction %s\n", finalTransaction.ToString().c_str()); LogPrintf("CDarksendPool::SignFinalTransaction %s\n", finalTransaction.ToString().c_str());
@ -1473,10 +1278,6 @@ 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
CScript scriptOld = finalTransaction.vin[mine].scriptSig;
if(!fSubmitAnonymousFailed && 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;
@ -1498,7 +1299,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);
TrickleInputsOutputs();
return false; return false;
} }
@ -1508,8 +1309,6 @@ bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNod
// not sure what to do here, it will timeout...? // not sure what to do here, it will timeout...?
} }
if(scriptOld != CScript() && finalTransaction.vin[mine].scriptSig == scriptOld) continue;
sigs.push_back(finalTransaction.vin[mine]); sigs.push_back(finalTransaction.vin[mine]);
if(fDebug) LogPrintf(" -- dss %d %d %s\n", mine, (int)sigs.size(), finalTransaction.vin[mine].scriptSig.ToString().c_str()); if(fDebug) LogPrintf(" -- dss %d %d %s\n", mine, (int)sigs.size(), finalTransaction.vin[mine].scriptSig.ToString().c_str());
} }
@ -1519,22 +1318,10 @@ bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNod
if(fDebug) LogPrintf("CDarksendPool::Sign - txNew:\n%s", finalTransaction.ToString().c_str()); if(fDebug) LogPrintf("CDarksendPool::Sign - txNew:\n%s", finalTransaction.ToString().c_str());
} }
if(!fSubmitAnonymousFailed){ // push all of our signatures to the Masternode
//resubmit some other sigs from the transaction, so nodes can't tell who's inputs/outputs are whos if(sigs.size() > 0 && node != NULL)
BOOST_FOREACH(CTxIn& in, finalTransaction.vin) node->PushMessage("dss", sigs);
if((rand() % 100) > 75 && in.scriptSig != CScript())
sigs.push_back(in);
std::random_shuffle ( sigs.begin(), sigs.end(), randomizeList);
LogPrintf("sigs count %d\n", (int)sigs.size());
RelaySignaturesAnon(sigs);
} else {
// push all of our signatures to the Masternode
if(sigs.size() > 0 && node != NULL)
node->PushMessage("dss", sigs);
}
return true; return true;
} }
@ -1867,90 +1654,6 @@ bool CDarksendPool::PrepareDarksendDenominate()
return false; return false;
} }
bool CDarksendPool::Downgrade()
{
if(fSubmitAnonymousFailed) return true;
if(myEntries.size() == 0) return false;
fSubmitAnonymousFailed = true;
//LogPrintf("CDarksendPool::Downgrade() : Downgrading and submitting directly\n");
// relay our entry to the master node
RelayIn(myEntries[0].sev, myEntries[0].amount, txCollateral, myEntries[0].vout);
return true;
}
struct SortByTimesSent
{
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;
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;
}
bool CDarksendPool::SendRandomPaymentToSelf() bool CDarksendPool::SendRandomPaymentToSelf()
{ {
int64_t nBalance = pwalletMain->GetBalance(); int64_t nBalance = pwalletMain->GetBalance();
@ -2140,7 +1843,6 @@ bool CDarksendPool::IsCompatibleWithSession(int64_t nDenom, CTransaction txColla
dsq.vin = activeMasternode.vin; dsq.vin = activeMasternode.vin;
dsq.time = GetTime(); dsq.time = GetTime();
dsq.Sign(); dsq.Sign();
strMasternodeSharedKey = dsq.strSharedKey;
dsq.Relay(); dsq.Relay();
} }
@ -2400,29 +2102,9 @@ bool CDarksendQueue::Sign()
return false; return false;
} }
// -- second signature, for proving access to the anonymous relay system
nBlockHeight = chainActive.Tip()->nHeight; //sign with our current blockheight
strMessage = boost::lexical_cast<std::string>(nBlockHeight);
if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchRelaySig, key2)) {
LogPrintf("CDarksendQueue():Relay - Sign message failed");
return false;
}
if(!darkSendSigner.VerifyMessage(pubkey2, vchRelaySig, strMessage, errorMessage)) {
LogPrintf("CDarksendQueue():Relay - Verify message failed");
return false;
}
return true; return true;
} }
void CDarksendQueue::SetSharedKey(std::string strSharedKeyIn)
{
strSharedKey = strSharedKeyIn;
}
bool CDarksendQueue::Relay() bool CDarksendQueue::Relay()
{ {
@ -2448,18 +2130,6 @@ bool CDarksendQueue::CheckSignature()
return error("CDarksendQueue::CheckSignature() - Got bad Masternode address signature %s \n", vin.ToString().c_str()); return error("CDarksendQueue::CheckSignature() - Got bad Masternode address signature %s \n", vin.ToString().c_str());
} }
// -- second signature, for proving access to the anonymous relay system
if(ready)
{
strMessage = boost::lexical_cast<std::string>(nBlockHeight);
if(!darkSendSigner.VerifyMessage(pmn->pubkey2, vchRelaySig, strMessage, errorMessage)) {
LogPrintf("CDarksendQueue():CheckSignature - Verify message failed");
return false;
}
}
return true; return true;
} }
@ -2476,38 +2146,6 @@ void CDarksendPool::RelayFinalTransaction(const int sessionID, const CTransactio
} }
} }
void CDarksendPool::RelaySignaturesAnon(std::vector<CTxIn>& vin)
{
CTxOut emptyOut;
BOOST_FOREACH(CTxIn& in, vin){
LogPrintf("RelaySignaturesAnon - sig %s\n", in.ToString().c_str());
CDarkSendRelay dsr(pSubmittedToMasternode->vin, vchMasternodeRelaySig, nMasternodeBlockHeight, DARKSEND_RELAY_SIG, in, emptyOut);
dsr.Sign(strMasternodeSharedKey);
dsr.Relay();
}
}
void CDarksendPool::RelayInAnon(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout)
{
CTxOut emptyOut;
CTxIn emptyIn;
BOOST_FOREACH(CTxIn& in, vin){
LogPrintf("RelayInAnon - in %s\n", in.ToString().c_str());
CDarkSendRelay dsr(pSubmittedToMasternode->vin, vchMasternodeRelaySig, nMasternodeBlockHeight, DARKSEND_RELAY_IN, in, emptyOut);
dsr.Sign(strMasternodeSharedKey);
dsr.Relay();
}
BOOST_FOREACH(CTxOut& out, vout){
LogPrintf("RelayInAnon - out %s\n", out.ToString().c_str());
CDarkSendRelay dsr(pSubmittedToMasternode->vin, vchMasternodeRelaySig, nMasternodeBlockHeight, DARKSEND_RELAY_OUT, emptyIn, out);
dsr.Sign(strMasternodeSharedKey);
dsr.Relay();
}
}
void CDarksendPool::RelayIn(const std::vector<CTxDSIn>& vin, const int64_t& nAmount, 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)
{ {
@ -2544,57 +2182,6 @@ void CDarksendPool::RelayCompletedTransaction(const int sessionID, const bool er
pnode->PushMessage("dsc", sessionID, error, errorMessage); pnode->PushMessage("dsc", sessionID, error, errorMessage);
} }
bool CDSAnonTx::AddOutput(const CTxOut out){
if(fDebug) LogPrintf("CDSAnonTx::AddOutput -- new %s\n", out.ToString().substr(0,24).c_str());
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);
ClearSigs();
return true;
}
bool CDSAnonTx::AddInput(const CTxIn in){
if(fDebug) LogPrintf("CDSAnonTx::AddInput -- new %s\n", in.ToString().substr(0,24).c_str());
//already have this input
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);
ClearSigs();
return true;
}
bool CDSAnonTx::ClearSigs(){
BOOST_FOREACH(CTxDSIn& in, vin)
in.scriptSig = CScript();
return true;
}
bool CDSAnonTx::AddSig(const CTxIn newIn){
if(fDebug) LogPrintf("CDSAnonTx::AddSig -- new %s\n", newIn.ToString().substr(0,24).c_str());
BOOST_FOREACH(CTxDSIn& in, vin){
if(newIn.prevout == in.prevout && in.nSequence == newIn.nSequence){
in.scriptSig = newIn.scriptSig;
in.prevPubKey = newIn.prevPubKey;
in.fHasSig = true;
return true;
}
}
return false;
}
//TODO: Rename/move to core //TODO: Rename/move to core
void ThreadCheckDarkSendPool() void ThreadCheckDarkSendPool()
{ {
@ -2613,10 +2200,7 @@ void ThreadCheckDarkSendPool()
MilliSleep(1000); MilliSleep(1000);
//LogPrintf("ThreadCheckDarkSendPool::check timeout\n"); //LogPrintf("ThreadCheckDarkSendPool::check timeout\n");
if(c % 10 == 0) darkSendPool.Check();
if(c % 3 == 0) darkSendPool.TrickleInputsOutputs();
darkSendPool.CheckTimeout(); darkSendPool.CheckTimeout();
darkSendPool.CheckForCompleteQueue();
if(c % 60 == 0) if(c % 60 == 0)
{ {

View File

@ -39,9 +39,8 @@ class CActiveMasternode;
#define MASTERNODE_REJECTED 0 #define MASTERNODE_REJECTED 0
#define MASTERNODE_RESET -1 #define MASTERNODE_RESET -1
#define DARKSEND_QUEUE_TIMEOUT 180 // in seconds #define DARKSEND_QUEUE_TIMEOUT 120
#define DARKSEND_SIGNING_TIMEOUT 30 // in seconds #define DARKSEND_SIGNING_TIMEOUT 30
#define DARKSEND_DOWNGRADE_TIMEOUT 60 // in seconds
// used for anonymous relaying of inputs/outputs/sigs // used for anonymous relaying of inputs/outputs/sigs
#define DARKSEND_RELAY_IN 1 #define DARKSEND_RELAY_IN 1
@ -92,9 +91,7 @@ public:
} }
}; };
/** 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
*/
class CDarkSendEntry class CDarkSendEntry
{ {
public: public:
@ -152,20 +149,12 @@ public:
bool ready; //ready for submit bool ready; //ready for submit
std::vector<unsigned char> vchSig; std::vector<unsigned char> vchSig;
//information used for the anonymous relay system
int nBlockHeight;
std::vector<unsigned char> vchRelaySig;
std::string strSharedKey; // shared key
CDarksendQueue() CDarksendQueue()
{ {
nDenom = 0; nDenom = 0;
vin = CTxIn(); vin = CTxIn();
time = 0; time = 0;
vchSig.clear(); vchSig.clear();
vchRelaySig.clear();
nBlockHeight = 0;
strSharedKey = "";
ready = false; ready = false;
} }
@ -176,12 +165,6 @@ public:
READWRITE(time); READWRITE(time);
READWRITE(ready); READWRITE(ready);
READWRITE(vchSig); READWRITE(vchSig);
if(ready){
READWRITE(vchRelaySig);
READWRITE(nBlockHeight);
READWRITE(strSharedKey);
}
) )
bool GetAddress(CService &addr) bool GetAddress(CService &addr)
@ -207,9 +190,6 @@ public:
return false; return false;
} }
/// Set the 'strSharedKey'
void SetSharedKey(std::string strSharedKey);
/** Sign this Darksend transaction /** Sign this Darksend transaction
* \return true if all conditions are met: * \return true if all conditions are met:
* 1) we have an active Masternode, * 1) we have an active Masternode,
@ -258,32 +238,6 @@ public:
bool VerifyMessage(CPubKey pubkey, std::vector<unsigned char>& vchSig, std::string strMessage, std::string& errorMessage); bool VerifyMessage(CPubKey pubkey, std::vector<unsigned char>& vchSig, std::string strMessage, std::string& errorMessage);
}; };
/** Build a transaction anonymously
*/
class CDSAnonTx
{
public:
std::vector<CTxDSIn> vin; // collection of inputs
std::vector<CTxOut> vout; // collection of outputs
/// Is the transaction valid? (TODO: not defined - remove? or code?)
bool IsTransactionValid();
/// Add an output
bool AddOutput(const CTxOut out);
/// Add an input
bool AddInput(const CTxIn in);
/// Clear Signatures
bool ClearSigs();
/// Add Signature
bool AddSig(const CTxIn in);
/// Count the number of entries in the transaction
int CountEntries() {return (int)vin.size() + (int)vout.size();}
};
/// TODO: not defined - remove?
void ConnectToDarkSendMasterNodeWinner();
/** Used to keep track of current status of Darksend pool /** Used to keep track of current status of Darksend pool
*/ */
class CDarksendPool class CDarksendPool
@ -293,9 +247,6 @@ public:
std::vector<CDarkSendEntry> myEntries; // clients entries std::vector<CDarkSendEntry> myEntries; // clients entries
std::vector<CDarkSendEntry> entries; // Masternode entries std::vector<CDarkSendEntry> entries; // Masternode entries
CTransaction finalTransaction; // the finalized transaction ready for signing CTransaction finalTransaction; // the finalized transaction ready for signing
CDSAnonTx anonTx; // anonymous inputs/outputs
bool fSubmitAnonymousFailed; // initally false, will change to true if when attempts > 5
int nCountAttempts; // number of submitted attempts
int64_t lastTimeChanged; // last time the 'state' changed, in UTC milliseconds int64_t lastTimeChanged; // last time the 'state' changed, in UTC milliseconds
int64_t lastAutoDenomination; // TODO; not used - Delete? int64_t lastAutoDenomination; // TODO; not used - Delete?
@ -334,12 +285,6 @@ public:
//debugging data //debugging data
std::string strAutoDenomResult; std::string strAutoDenomResult;
// used for securing the anonymous relay system
vector<unsigned char> vchMasternodeRelaySig;
int nMasternodeBlockHeight;
std::string strMasternodeSharedKey;
int nTrickleInputsOutputs;
CDarksendPool() CDarksendPool()
{ {
/* Darksend uses collateral addresses to trust parties entering the pool /* Darksend uses collateral addresses to trust parties entering the pool
@ -351,8 +296,6 @@ public:
txCollateral = CTransaction(); txCollateral = CTransaction();
minBlockSpacing = 1; minBlockSpacing = 1;
lastNewBlock = 0; lastNewBlock = 0;
strMasternodeSharedKey = "";
nTrickleInputsOutputs = 0;
SetNull(); SetNull();
} }
@ -390,9 +333,6 @@ public:
bool SetCollateralAddress(std::string strAddress); bool SetCollateralAddress(std::string strAddress);
void Reset(); void Reset();
bool Downgrade();
bool TrickleInputsOutputs();
void SetNull(bool clearEverything=false); void SetNull(bool clearEverything=false);
void UnlockCoins(); void UnlockCoins();
@ -492,18 +432,6 @@ public:
bool IsCollateralValid(const CTransaction& txCollateral); bool IsCollateralValid(const CTransaction& txCollateral);
/// Add a clients entry to the pool /// Add a clients entry to the pool
bool AddEntry(const std::vector<CTxIn>& newInput, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxOut>& newOutput, std::string& error); bool AddEntry(const std::vector<CTxIn>& newInput, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxOut>& newOutput, std::string& error);
/// Add an anonymous output/inputs/sig
bool AddAnonymousOutput(const CTxOut& out) {return anonTx.AddOutput(out);}
bool AddAnonymousInput(const CTxIn& in) {return anonTx.AddInput(in);}
bool AddAnonymousSig(const CTxIn& in) {return anonTx.AddSig(in);}
bool AddRelaySignature(vector<unsigned char> vchMasternodeRelaySigIn, int nMasternodeBlockHeightIn, std::string strSharedKey) {
vchMasternodeRelaySig = vchMasternodeRelaySigIn;
nMasternodeBlockHeight = nMasternodeBlockHeightIn;
strMasternodeSharedKey = strSharedKey;
return true;
}
/// Add signature to a vin /// Add signature to a vin
bool AddScriptSig(const CTxIn& newVin); bool AddScriptSig(const CTxIn& newVin);
/// Check that all inputs are signed. (Are all inputs signed?) /// Check that all inputs are signed. (Are all inputs signed?)

View File

@ -375,12 +375,10 @@ void OverviewPage::darkSendStatus()
/* ** @TODO this string creation really needs some clean ups ---vertoe ** */ /* ** @TODO this string creation really needs some clean ups ---vertoe ** */
std::ostringstream convert; std::ostringstream convert;
if(state == POOL_STATUS_IDLE) { if(state == POOL_STATUS_ACCEPTING_ENTRIES) {
convert << tr("Darksend is idle.").toStdString();
} else if(state == POOL_STATUS_ACCEPTING_ENTRIES) {
if(entries == 0) { if(entries == 0) {
if(darkSendPool.strAutoDenomResult.size() == 0){ if(darkSendPool.strAutoDenomResult.size() == 0){
convert << tr("Mixing in progress...").toStdString(); convert << tr("Darksend is idle.").toStdString();
} else { } else {
convert << darkSendPool.strAutoDenomResult; convert << darkSendPool.strAutoDenomResult;
} }
@ -393,15 +391,15 @@ void OverviewPage::darkSendStatus()
} }
} else { } else {
if(showingDarkSendMessage % 70 <= 40) convert << tr("Submitted following entries to masternode:").toStdString() << " " << entries << "/" << darkSendPool.GetMaxPoolTransactions(); if(showingDarkSendMessage % 70 <= 40) convert << tr("Submitted following entries to masternode:").toStdString() << " " << entries << "/" << darkSendPool.GetMaxPoolTransactions();
else if(showingDarkSendMessage % 70 <= 50) convert << tr("Submitted to masternode, waiting for more entries").toStdString() << " (" << entries << "/" << darkSendPool.GetMaxPoolTransactions() << " ) ."; else if(showingDarkSendMessage % 70 <= 50) convert << tr("Submitted to masternode, Waiting for more entries").toStdString() << " (" << entries << "/" << darkSendPool.GetMaxPoolTransactions() << " ) .";
else if(showingDarkSendMessage % 70 <= 60) convert << tr("Submitted to masternode, waiting for more entries").toStdString() << " (" << entries << "/" << darkSendPool.GetMaxPoolTransactions() << " ) .."; else if(showingDarkSendMessage % 70 <= 60) convert << tr("Submitted to masternode, Waiting for more entries").toStdString() << " (" << entries << "/" << darkSendPool.GetMaxPoolTransactions() << " ) ..";
else if(showingDarkSendMessage % 70 <= 70) convert << tr("Submitted to masternode, waiting for more entries").toStdString() << " (" << entries << "/" << darkSendPool.GetMaxPoolTransactions() << " ) ..."; else if(showingDarkSendMessage % 70 <= 70) convert << tr("Submitted to masternode, Waiting for more entries").toStdString() << " (" << entries << "/" << darkSendPool.GetMaxPoolTransactions() << " ) ...";
} }
} else if(state == POOL_STATUS_SIGNING) { } else if(state == POOL_STATUS_SIGNING) {
if(showingDarkSendMessage % 70 <= 10) convert << tr("Found enough users, signing ...").toStdString(); if(showingDarkSendMessage % 70 <= 10) convert << tr("Found enough users, signing ...").toStdString();
else if(showingDarkSendMessage % 70 <= 20) convert << tr("Found enough users, signing ( waiting").toStdString() << ". )"; else if(showingDarkSendMessage % 70 <= 20) convert << tr("Found enough users, signing ( waiting. )").toStdString();
else if(showingDarkSendMessage % 70 <= 30) convert << tr("Found enough users, signing ( waiting").toStdString() << ".. )"; else if(showingDarkSendMessage % 70 <= 30) convert << tr("Found enough users, signing ( waiting.. )").toStdString();
else if(showingDarkSendMessage % 70 <= 40) convert << tr("Found enough users, signing ( waiting").toStdString() << "... )"; else if(showingDarkSendMessage % 70 <= 40) convert << tr("Found enough users, signing ( waiting... )").toStdString();
} else if(state == POOL_STATUS_TRANSMISSION) { } else if(state == POOL_STATUS_TRANSMISSION) {
convert << tr("Transmitting final transaction.").toStdString(); convert << tr("Transmitting final transaction.").toStdString();
} else if (state == POOL_STATUS_IDLE) { } else if (state == POOL_STATUS_IDLE) {
@ -413,9 +411,9 @@ void OverviewPage::darkSendStatus()
} else if(state == POOL_STATUS_SUCCESS) { } else if(state == POOL_STATUS_SUCCESS) {
convert << tr("Darksend request complete:").toStdString() << " " << darkSendPool.lastMessage; convert << tr("Darksend request complete:").toStdString() << " " << darkSendPool.lastMessage;
} else if(state == POOL_STATUS_QUEUE) { } else if(state == POOL_STATUS_QUEUE) {
if(showingDarkSendMessage % 70 <= 50) convert << tr("Submitted to masternode, waiting in queue").toStdString() << " ."; if(showingDarkSendMessage % 70 <= 50) convert << tr("Submitted to masternode, waiting in queue .").toStdString();
else if(showingDarkSendMessage % 70 <= 60) convert << tr("Submitted to masternode, waiting in queue").toStdString() << " .."; else if(showingDarkSendMessage % 70 <= 60) convert << tr("Submitted to masternode, waiting in queue ..").toStdString();
else if(showingDarkSendMessage % 70 <= 70) convert << tr("Submitted to masternode, waiting in queue").toStdString() << " ..."; else if(showingDarkSendMessage % 70 <= 70) convert << tr("Submitted to masternode, waiting in queue ...").toStdString();
} else { } else {
convert << tr("Unknown state:").toStdString() << " id = " << state; convert << tr("Unknown state:").toStdString() << " id = " << state;
} }