Removed non-denomational inputs (UdjinM6)

Exact amounts are now allocated directly to denominated
funds then submitted to the pool. This improves anonymity
by never having non-denomination inputs enter or exit the pool.
Randomness has also been added to the amount of each session to
improve anonymity.
This commit is contained in:
Evan Duffield 2015-01-19 14:25:03 -07:00
parent b7f436bb5c
commit 2737edbbf3
7 changed files with 40 additions and 31 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, 0) define(_CLIENT_VERSION_REVISION, 0)
define(_CLIENT_VERSION_BUILD, 8) define(_CLIENT_VERSION_BUILD, 9)
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 0 #define CLIENT_VERSION_REVISION 0
#define CLIENT_VERSION_BUILD 8 #define CLIENT_VERSION_BUILD 9

View File

@ -91,6 +91,7 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream&
} }
else if (strCommand == "dsa") { //DarkSend Acceptable else if (strCommand == "dsa") { //DarkSend Acceptable
if (pfrom->nVersion < darkSendPool.MIN_PEER_PROTO_VERSION) { if (pfrom->nVersion < darkSendPool.MIN_PEER_PROTO_VERSION) {
std::string strError = "incompatible version"; std::string strError = "incompatible version";
LogPrintf("dsa -- incompatible version! \n"); LogPrintf("dsa -- incompatible version! \n");
@ -140,6 +141,7 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream&
return; return;
} }
} else if (strCommand == "dsq") { //DarkSend Queue } else if (strCommand == "dsq") { //DarkSend Queue
if (pfrom->nVersion < darkSendPool.MIN_PEER_PROTO_VERSION) { if (pfrom->nVersion < darkSendPool.MIN_PEER_PROTO_VERSION) {
return; return;
} }
@ -147,6 +149,7 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream&
CDarksendQueue dsq; CDarksendQueue dsq;
vRecv >> dsq; vRecv >> dsq;
CService addr; CService addr;
if(!dsq.GetAddress(addr)) return; if(!dsq.GetAddress(addr)) return;
if(!dsq.CheckSignature()) return; if(!dsq.CheckSignature()) return;
@ -156,7 +159,6 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream&
int mn = GetMasternodeByVin(dsq.vin); int mn = GetMasternodeByVin(dsq.vin);
if(mn == -1) return; if(mn == -1) return;
// if the queue is ready, submit if we can // if the queue is ready, submit if we can
if(dsq.ready) { if(dsq.ready) {
if((CNetAddr)darkSendPool.submittedToMasternode != (CNetAddr)addr){ if((CNetAddr)darkSendPool.submittedToMasternode != (CNetAddr)addr){
@ -324,6 +326,7 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream&
} }
else if (strCommand == "dssu") { //DarkSend status update else if (strCommand == "dssu") { //DarkSend status update
if (pfrom->nVersion < darkSendPool.MIN_PEER_PROTO_VERSION) { if (pfrom->nVersion < darkSendPool.MIN_PEER_PROTO_VERSION) {
return; return;
} }
@ -1527,6 +1530,9 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
if(!dsq.GetProtocolVersion(protocolVersion)) continue; if(!dsq.GetProtocolVersion(protocolVersion)) continue;
if(protocolVersion < MIN_PEER_PROTO_VERSION) continue; if(protocolVersion < MIN_PEER_PROTO_VERSION) continue;
//non-denom's are incompatible
if((dsq.nDenom & (1 << 4))) continue;
//don't reuse masternodes //don't reuse masternodes
BOOST_FOREACH(CTxIn usedVin, vecMasternodesUsed){ BOOST_FOREACH(CTxIn usedVin, vecMasternodesUsed){
if(dsq.vin == usedVin) { if(dsq.vin == usedVin) {
@ -1537,7 +1543,7 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
// Try to match their denominations if possible // Try to match their denominations if possible
if (!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, nValueMin, balanceNeedsAnonymized, vCoins, nValueIn, 0, nDarksendRounds)){ if (!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, nValueMin, balanceNeedsAnonymized, vCoins, nValueIn, 0, nDarksendRounds)){
// if (!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, nValueMin, balanceNeedsAnonymized, vCoins, nValueIn, -2, 0)){ // if (!pwalletMain->SelectCoinsByDenominations(dsq.nDenom, nValueMin, balanceNeedsAnonymized, vCoins, nValueIn, -2, 0)){
LogPrintf("DoAutomaticDenominating - Couldn't match denominations\n"); LogPrintf("DoAutomaticDenominating - Couldn't match denominations %d\n", dsq.nDenom);
continue; continue;
// } // }
} }
@ -1545,6 +1551,7 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
// connect to masternode and submit the queue request // connect to masternode and submit the queue request
if(ConnectNode((CAddress)addr, NULL, true)){ if(ConnectNode((CAddress)addr, NULL, true)){
submittedToMasternode = addr; submittedToMasternode = addr;
LOCK(cs_vNodes); LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes) BOOST_FOREACH(CNode* pnode, vNodes)
{ {
@ -1602,6 +1609,7 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun, bool ready)
LogPrintf("DoAutomaticDenominating -- attempt %d connection to masternode %s\n", sessionTries, vecMasternodes[i].addr.ToString().c_str()); LogPrintf("DoAutomaticDenominating -- attempt %d connection to masternode %s\n", sessionTries, vecMasternodes[i].addr.ToString().c_str());
if(ConnectNode((CAddress)vecMasternodes[i].addr, NULL, true)){ if(ConnectNode((CAddress)vecMasternodes[i].addr, NULL, true)){
submittedToMasternode = vecMasternodes[i].addr; submittedToMasternode = vecMasternodes[i].addr;
LOCK(cs_vNodes); LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes) BOOST_FOREACH(CNode* pnode, vNodes)
{ {
@ -1947,6 +1955,7 @@ void CDarkSendPool::GetDenominationsToString(int nDenom, std::string& strDenom){
// bit 1 - 10DRK+1 // bit 1 - 10DRK+1
// bit 2 - 1DRK+1 // bit 2 - 1DRK+1
// bit 3 - .1DRK+1 // bit 3 - .1DRK+1
// bit 3 - non-denom
strDenom = ""; strDenom = "";
@ -1970,7 +1979,6 @@ void CDarkSendPool::GetDenominationsToString(int nDenom, std::string& strDenom){
if(strDenom.size() > 0) strDenom += "+"; if(strDenom.size() > 0) strDenom += "+";
strDenom += "0.1"; strDenom += "0.1";
} }
} }
// return a bitshifted integer representing the denominations in this list // return a bitshifted integer representing the denominations in this list
@ -2010,6 +2018,7 @@ int CDarkSendPool::GetDenominations(const std::vector<CTxOut>& vout){
return denom; return denom;
} }
int CDarkSendPool::GetDenominationsByAmounts(std::vector<int64_t>& vecAmount){ int CDarkSendPool::GetDenominationsByAmounts(std::vector<int64_t>& vecAmount){
CScript e = CScript(); CScript e = CScript();
std::vector<CTxOut> vout1; std::vector<CTxOut> vout1;

View File

@ -223,7 +223,7 @@ class CDarksendSession
class CDarkSendPool class CDarkSendPool
{ {
public: public:
static const int MIN_PEER_PROTO_VERSION = 70052; static const int MIN_PEER_PROTO_VERSION = 70053;
// clients entries // clients entries
std::vector<CDarkSendEntry> myEntries; std::vector<CDarkSendEntry> myEntries;

View File

@ -344,29 +344,6 @@ void OverviewPage::darkSendStatus()
// Balance and number of transactions might have changed // Balance and number of transactions might have changed
darkSendPool.cachedNumBlocks = nBestHeight; darkSendPool.cachedNumBlocks = nBestHeight;
if (pwalletMain->GetBalance() - pwalletMain->GetAnonymizedBalance() > 2*COIN){
if (walletModel->getEncryptionStatus() != WalletModel::Unencrypted){
if((nAnonymizeDarkcoinAmount*COIN)-pwalletMain->GetAnonymizedBalance() > 1.1*COIN &&
walletModel->getEncryptionStatus() == WalletModel::Locked){
WalletModel::UnlockContext ctx(walletModel->requestUnlock(false));
if(!ctx.isValid()){
//unlock was cancelled
fEnableDarksend = false;
darkSendPool.cachedNumBlocks = 0;
LogPrintf("Wallet is locked and user declined to unlock. Disabling Darksend.\n");
}
}
if((nAnonymizeDarkcoinAmount*COIN)-pwalletMain->GetAnonymizedBalance() <= 1.1*COIN &&
walletModel->getEncryptionStatus() == WalletModel::Unlocked &&
darkSendPool.GetMyTransactionCount() == 0){
LogPrintf("Darksend is complete, locking wallet.\n");
walletModel->setWalletLocked(true);
}
}
}
/* *******************************************************/ /* *******************************************************/
ui->darksendEnabled->setText("Enabled"); ui->darksendEnabled->setText("Enabled");
@ -472,6 +449,24 @@ void OverviewPage::toggleDarksend(){
QMessageBox::Ok, QMessageBox::Ok); QMessageBox::Ok, QMessageBox::Ok);
return; return;
} }
if (pwalletMain->GetBalance() - pwalletMain->GetAnonymizedBalance() > 2*COIN){
if (walletModel->getEncryptionStatus() != WalletModel::Unencrypted){
if((nAnonymizeDarkcoinAmount*COIN)-pwalletMain->GetAnonymizedBalance() > 1.1*COIN &&
walletModel->getEncryptionStatus() == WalletModel::Locked){
WalletModel::UnlockContext ctx(walletModel->requestUnlock(false));
if(!ctx.isValid()){
//unlock was cancelled
fEnableDarksend = false;
darkSendPool.cachedNumBlocks = 0;
LogPrintf("Wallet is locked and user declined to unlock. Disabling Darksend.\n");
}
}
}
}
} }
darkSendPool.cachedNumBlocks = 0; darkSendPool.cachedNumBlocks = 0;

View File

@ -27,7 +27,7 @@ extern const std::string CLIENT_DATE;
// network protocol versioning // network protocol versioning
// //
static const int PROTOCOL_VERSION = 70052; static const int PROTOCOL_VERSION = 70053;
// intial proto version, to be increased after version/verack negotiation // intial proto version, to be increased after version/verack negotiation
static const int INIT_PROTO_VERSION = 209; static const int INIT_PROTO_VERSION = 209;

View File

@ -1554,6 +1554,11 @@ bool CWallet::SelectCoinsByDenominations(int nDenom, int64_t nValueMin, int64_t
if(rounds < nDarksendRoundsMin) continue; if(rounds < nDarksendRoundsMin) continue;
if(fFound100 && fFound10 && fFound1 && fFoundDot1){ //if fulfilled if(fFound100 && fFound10 && fFound1 && fFoundDot1){ //if fulfilled
//we can return this for submission
if(nValueRet >= nValueMin){
//random reduce the max amount we'll submit for anonymity
nValueMax -= (rand() % (nValueMax/5));
}
//Denomination criterion has been met, we can take any matching denominations //Denomination criterion has been met, we can take any matching denominations
if((nDenom & (1 << 0)) && out.tx->vout[out.i].nValue == ((100*COIN)+1)) {fAccepted = true;} if((nDenom & (1 << 0)) && out.tx->vout[out.i].nValue == ((100*COIN)+1)) {fAccepted = true;}
else if((nDenom & (1 << 1)) && out.tx->vout[out.i].nValue == ((10*COIN)+1)) {fAccepted = true;} else if((nDenom & (1 << 1)) && out.tx->vout[out.i].nValue == ((10*COIN)+1)) {fAccepted = true;}