Reverting some DS changes
- Some changes caused instability of DS, this should fix that.
This commit is contained in:
parent
e29b66d1dc
commit
f0192b1bb3
458
src/darksend.cpp
458
src/darksend.cpp
@ -130,9 +130,6 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
|
||||
}
|
||||
|
||||
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());
|
||||
PrepareDarksendDenominate();
|
||||
}
|
||||
@ -158,138 +155,7 @@ void CDarksendPool::ProcessMessageDarksend(CNode* pfrom, std::string& strCommand
|
||||
dsq.time = GetTime();
|
||||
}
|
||||
|
||||
} else if (strCommand == "dsr") { //Darksend Relay
|
||||
|
||||
//* 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
|
||||
|
||||
} else if (strCommand == "dsi") { //DarkSend vIn
|
||||
std::string error = "";
|
||||
if (pfrom->nVersion < MIN_POOL_PEER_PROTO_VERSION) {
|
||||
LogPrintf("dsi -- incompatible version! \n");
|
||||
@ -617,9 +483,6 @@ void CDarksendPool::SetNull(bool clearEverything){
|
||||
finalTransaction.vout.clear();
|
||||
|
||||
entries.clear();
|
||||
anonTx.vin.clear();
|
||||
anonTx.vout.clear();
|
||||
nTrickleInputsOutputs = 0;
|
||||
|
||||
state = POOL_STATUS_IDLE;
|
||||
|
||||
@ -629,7 +492,6 @@ void CDarksendPool::SetNull(bool clearEverything){
|
||||
lastEntryAccepted = 0;
|
||||
countEntriesAccepted = 0;
|
||||
lastNewBlock = 0;
|
||||
fSubmitAnonymousFailed = false;
|
||||
|
||||
sessionUsers = 0;
|
||||
sessionDenom = 0;
|
||||
@ -637,18 +499,11 @@ void CDarksendPool::SetNull(bool clearEverything){
|
||||
vecSessionCollateral.clear();
|
||||
txCollateral = CTransaction();
|
||||
|
||||
vchMasternodeRelaySig.clear();
|
||||
nMasternodeBlockHeight = 0;
|
||||
|
||||
if(clearEverything){
|
||||
myEntries.clear();
|
||||
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)
|
||||
unsigned int seed = 0;
|
||||
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);
|
||||
|
||||
// If entries is full, then move on to the next phase
|
||||
if(state == POOL_STATUS_ACCEPTING_ENTRIES && (
|
||||
(int)entries.size() >= GetMaxPoolTransactions() ||
|
||||
(GetTimeMillis()-lastTimeChanged > 5000 && anonTx.CountEntries() > GetMaxPoolTransactions()*5)
|
||||
))
|
||||
if(state == POOL_STATUS_ACCEPTING_ENTRIES && (int)entries.size() >= GetMaxPoolTransactions())
|
||||
{
|
||||
if(fDebug) LogPrintf("CDarksendPool::Check() -- TRYING TRANSACTION \n");
|
||||
UpdateState(POOL_STATUS_FINALIZE_TRANSACTION);
|
||||
nCountAttempts++;
|
||||
}
|
||||
|
||||
// create the finalized transaction for distribution to the clients
|
||||
@ -705,26 +556,19 @@ void CDarksendPool::Check()
|
||||
CTransaction txNew;
|
||||
|
||||
// make our new transaction
|
||||
if((int)entries.size() >= GetMaxPoolTransactions()) {
|
||||
for(unsigned int i = 0; i < entries.size(); i++){
|
||||
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)
|
||||
for(unsigned int i = 0; i < entries.size(); i++){
|
||||
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);
|
||||
|
||||
|
||||
if(fDebug) LogPrintf("Transaction 1: %s\n", txNew.ToString().c_str());
|
||||
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(state == POOL_STATUS_SIGNING && SignaturesComplete()) {
|
||||
if(fDebug) LogPrintf("CDarksendPool::Check() -- SIGNING\n");
|
||||
@ -764,17 +606,13 @@ void CDarksendPool::CheckFinalTransaction()
|
||||
// See if the transaction is valid
|
||||
if (!txNew.AcceptToMemoryPool(false))
|
||||
{
|
||||
if(nCountAttempts > 60) {
|
||||
LogPrintf("CDarksendPool::Check() - CommitTransaction : Error: Transaction not valid\n");
|
||||
SetNull();
|
||||
pwalletMain->Lock();
|
||||
}
|
||||
LogPrintf("CDarksendPool::Check() - CommitTransaction : Error: Transaction not valid\n");
|
||||
SetNull();
|
||||
pwalletMain->Lock();
|
||||
|
||||
// not much we can do in this case]
|
||||
UpdateState(POOL_STATUS_ACCEPTING_ENTRIES);
|
||||
|
||||
if(!fSubmitAnonymousFailed && nCountAttempts > 30)
|
||||
fSubmitAnonymousFailed = true;
|
||||
RelayCompletedTransaction(sessionID, true, "Transaction not valid, please try again");
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1039,13 +877,6 @@ void CDarksendPool::CheckTimeout(){
|
||||
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){
|
||||
lastTimeChanged = GetTimeMillis();
|
||||
|
||||
@ -1068,7 +899,6 @@ void CDarksendPool::CheckTimeout(){
|
||||
}
|
||||
|
||||
if(state == POOL_STATUS_SIGNING && GetTimeMillis()-lastTimeChanged >= (DARKSEND_SIGNING_TIMEOUT*1000)+addLagTime ) {
|
||||
if(fSubmitAnonymousFailed){
|
||||
if(fDebug) LogPrintf("CDarksendPool::CheckTimeout() -- Session timed out -- restting\n");
|
||||
ChargeFees();
|
||||
SetNull();
|
||||
@ -1077,13 +907,6 @@ void CDarksendPool::CheckTimeout(){
|
||||
|
||||
UpdateState(POOL_STATUS_ERROR);
|
||||
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
|
||||
//
|
||||
if(state == POOL_STATUS_QUEUE && sessionUsers == GetMaxPoolTransactions()) {
|
||||
LogPrintf("Q ready");
|
||||
UpdateState(POOL_STATUS_ACCEPTING_ENTRIES);
|
||||
|
||||
if(strMasternodeSharedKey == ""){
|
||||
CKey secret;
|
||||
secret.MakeNewKey(false);
|
||||
strMasternodeSharedKey = CBitcoinSecret(secret).ToString();
|
||||
}
|
||||
|
||||
CDarksendQueue dsq;
|
||||
dsq.nDenom = sessionDenom;
|
||||
dsq.vin = activeMasternode.vin;
|
||||
dsq.time = GetTime();
|
||||
dsq.ready = true;
|
||||
dsq.SetSharedKey(strMasternodeSharedKey);
|
||||
dsq.Sign();
|
||||
dsq.Relay();
|
||||
}
|
||||
@ -1299,13 +1114,6 @@ bool CDarksendPool::AddScriptSig(const CTxIn& newVin){
|
||||
|
||||
// Check to make sure everything is signed
|
||||
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 CTxDSIn& s, v.sev){
|
||||
if(!s.fHasSig) return false;
|
||||
@ -1388,9 +1196,7 @@ void CDarksendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
|
||||
e.Add(vin, amount, txCollateral, vout);
|
||||
myEntries.push_back(e);
|
||||
|
||||
// submit inputs/outputs through relays
|
||||
TrickleInputsOutputs();
|
||||
|
||||
RelayIn(myEntries[0].sev, myEntries[0].amount, txCollateral, myEntries[0].vout);
|
||||
Check();
|
||||
}
|
||||
|
||||
@ -1448,7 +1254,6 @@ bool CDarksendPool::StatusUpdate(int newState, int newEntriesCount, int newAccep
|
||||
//
|
||||
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;
|
||||
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?
|
||||
//already signed
|
||||
CScript scriptOld = finalTransaction.vin[mine].scriptSig;
|
||||
if(!fSubmitAnonymousFailed && sigs.size() > 7) break; //send 7 each signing
|
||||
|
||||
int foundOutputs = 0;
|
||||
int64_t nValue1 = 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
|
||||
// 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);
|
||||
TrickleInputsOutputs();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1508,8 +1309,6 @@ bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNod
|
||||
// not sure what to do here, it will timeout...?
|
||||
}
|
||||
|
||||
if(scriptOld != CScript() && finalTransaction.vin[mine].scriptSig == scriptOld) continue;
|
||||
|
||||
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());
|
||||
}
|
||||
@ -1519,22 +1318,10 @@ bool CDarksendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNod
|
||||
if(fDebug) LogPrintf("CDarksendPool::Sign - txNew:\n%s", finalTransaction.ToString().c_str());
|
||||
}
|
||||
|
||||
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);
|
||||
// push all of our signatures to the Masternode
|
||||
if(sigs.size() > 0 && node != NULL)
|
||||
node->PushMessage("dss", sigs);
|
||||
|
||||
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;
|
||||
}
|
||||
@ -1867,90 +1654,6 @@ bool CDarksendPool::PrepareDarksendDenominate()
|
||||
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()
|
||||
{
|
||||
int64_t nBalance = pwalletMain->GetBalance();
|
||||
@ -2140,7 +1843,6 @@ bool CDarksendPool::IsCompatibleWithSession(int64_t nDenom, CTransaction txColla
|
||||
dsq.vin = activeMasternode.vin;
|
||||
dsq.time = GetTime();
|
||||
dsq.Sign();
|
||||
strMasternodeSharedKey = dsq.strSharedKey;
|
||||
dsq.Relay();
|
||||
}
|
||||
|
||||
@ -2400,29 +2102,9 @@ bool CDarksendQueue::Sign()
|
||||
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;
|
||||
}
|
||||
|
||||
void CDarksendQueue::SetSharedKey(std::string strSharedKeyIn)
|
||||
{
|
||||
strSharedKey = strSharedKeyIn;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
// -- 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;
|
||||
}
|
||||
|
||||
@ -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)
|
||||
{
|
||||
|
||||
@ -2544,57 +2182,6 @@ void CDarksendPool::RelayCompletedTransaction(const int sessionID, const bool er
|
||||
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
|
||||
void ThreadCheckDarkSendPool()
|
||||
{
|
||||
@ -2613,10 +2200,7 @@ void ThreadCheckDarkSendPool()
|
||||
MilliSleep(1000);
|
||||
//LogPrintf("ThreadCheckDarkSendPool::check timeout\n");
|
||||
|
||||
if(c % 10 == 0) darkSendPool.Check();
|
||||
if(c % 3 == 0) darkSendPool.TrickleInputsOutputs();
|
||||
darkSendPool.CheckTimeout();
|
||||
darkSendPool.CheckForCompleteQueue();
|
||||
|
||||
if(c % 60 == 0)
|
||||
{
|
||||
|
@ -39,9 +39,8 @@ class CActiveMasternode;
|
||||
#define MASTERNODE_REJECTED 0
|
||||
#define MASTERNODE_RESET -1
|
||||
|
||||
#define DARKSEND_QUEUE_TIMEOUT 180 // in seconds
|
||||
#define DARKSEND_SIGNING_TIMEOUT 30 // in seconds
|
||||
#define DARKSEND_DOWNGRADE_TIMEOUT 60 // in seconds
|
||||
#define DARKSEND_QUEUE_TIMEOUT 120
|
||||
#define DARKSEND_SIGNING_TIMEOUT 30
|
||||
|
||||
// used for anonymous relaying of inputs/outputs/sigs
|
||||
#define DARKSEND_RELAY_IN 1
|
||||
@ -92,9 +91,7 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/** A clients transaction in the Darksend pool
|
||||
* -- holds the input/output mapping for each user in the pool
|
||||
*/
|
||||
// A clients transaction in the darksend pool
|
||||
class CDarkSendEntry
|
||||
{
|
||||
public:
|
||||
@ -152,20 +149,12 @@ public:
|
||||
bool ready; //ready for submit
|
||||
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()
|
||||
{
|
||||
nDenom = 0;
|
||||
vin = CTxIn();
|
||||
time = 0;
|
||||
vchSig.clear();
|
||||
vchRelaySig.clear();
|
||||
nBlockHeight = 0;
|
||||
strSharedKey = "";
|
||||
ready = false;
|
||||
}
|
||||
|
||||
@ -176,12 +165,6 @@ public:
|
||||
READWRITE(time);
|
||||
READWRITE(ready);
|
||||
READWRITE(vchSig);
|
||||
|
||||
if(ready){
|
||||
READWRITE(vchRelaySig);
|
||||
READWRITE(nBlockHeight);
|
||||
READWRITE(strSharedKey);
|
||||
}
|
||||
)
|
||||
|
||||
bool GetAddress(CService &addr)
|
||||
@ -207,9 +190,6 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Set the 'strSharedKey'
|
||||
void SetSharedKey(std::string strSharedKey);
|
||||
|
||||
/** Sign this Darksend transaction
|
||||
* \return true if all conditions are met:
|
||||
* 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);
|
||||
};
|
||||
|
||||
/** 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
|
||||
*/
|
||||
class CDarksendPool
|
||||
@ -293,9 +247,6 @@ public:
|
||||
std::vector<CDarkSendEntry> myEntries; // clients entries
|
||||
std::vector<CDarkSendEntry> entries; // Masternode entries
|
||||
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 lastAutoDenomination; // TODO; not used - Delete?
|
||||
@ -334,12 +285,6 @@ public:
|
||||
//debugging data
|
||||
std::string strAutoDenomResult;
|
||||
|
||||
// used for securing the anonymous relay system
|
||||
vector<unsigned char> vchMasternodeRelaySig;
|
||||
int nMasternodeBlockHeight;
|
||||
std::string strMasternodeSharedKey;
|
||||
int nTrickleInputsOutputs;
|
||||
|
||||
CDarksendPool()
|
||||
{
|
||||
/* Darksend uses collateral addresses to trust parties entering the pool
|
||||
@ -351,8 +296,6 @@ public:
|
||||
txCollateral = CTransaction();
|
||||
minBlockSpacing = 1;
|
||||
lastNewBlock = 0;
|
||||
strMasternodeSharedKey = "";
|
||||
nTrickleInputsOutputs = 0;
|
||||
|
||||
SetNull();
|
||||
}
|
||||
@ -390,9 +333,6 @@ public:
|
||||
|
||||
bool SetCollateralAddress(std::string strAddress);
|
||||
void Reset();
|
||||
bool Downgrade();
|
||||
bool TrickleInputsOutputs();
|
||||
|
||||
void SetNull(bool clearEverything=false);
|
||||
|
||||
void UnlockCoins();
|
||||
@ -492,18 +432,6 @@ public:
|
||||
bool IsCollateralValid(const CTransaction& txCollateral);
|
||||
/// 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);
|
||||
|
||||
/// 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
|
||||
bool AddScriptSig(const CTxIn& newVin);
|
||||
/// Check that all inputs are signed. (Are all inputs signed?)
|
||||
|
@ -375,12 +375,10 @@ void OverviewPage::darkSendStatus()
|
||||
/* ** @TODO this string creation really needs some clean ups ---vertoe ** */
|
||||
std::ostringstream convert;
|
||||
|
||||
if(state == POOL_STATUS_IDLE) {
|
||||
convert << tr("Darksend is idle.").toStdString();
|
||||
} else if(state == POOL_STATUS_ACCEPTING_ENTRIES) {
|
||||
if(state == POOL_STATUS_ACCEPTING_ENTRIES) {
|
||||
if(entries == 0) {
|
||||
if(darkSendPool.strAutoDenomResult.size() == 0){
|
||||
convert << tr("Mixing in progress...").toStdString();
|
||||
convert << tr("Darksend is idle.").toStdString();
|
||||
} else {
|
||||
convert << darkSendPool.strAutoDenomResult;
|
||||
}
|
||||
@ -393,15 +391,15 @@ void OverviewPage::darkSendStatus()
|
||||
}
|
||||
} else {
|
||||
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 <= 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 <= 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 <= 70) convert << tr("Submitted to masternode, Waiting for more entries").toStdString() << " (" << entries << "/" << darkSendPool.GetMaxPoolTransactions() << " ) ...";
|
||||
}
|
||||
} else if(state == POOL_STATUS_SIGNING) {
|
||||
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 <= 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 <= 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 <= 40) convert << tr("Found enough users, signing ( waiting... )").toStdString();
|
||||
} else if(state == POOL_STATUS_TRANSMISSION) {
|
||||
convert << tr("Transmitting final transaction.").toStdString();
|
||||
} else if (state == POOL_STATUS_IDLE) {
|
||||
@ -413,9 +411,9 @@ void OverviewPage::darkSendStatus()
|
||||
} else if(state == POOL_STATUS_SUCCESS) {
|
||||
convert << tr("Darksend request complete:").toStdString() << " " << darkSendPool.lastMessage;
|
||||
} else if(state == POOL_STATUS_QUEUE) {
|
||||
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 <= 70) 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 <= 70) convert << tr("Submitted to masternode, waiting in queue ...").toStdString();
|
||||
} else {
|
||||
convert << tr("Unknown state:").toStdString() << " id = " << state;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user