This commit is contained in:
Evan Duffield 2014-08-03 07:40:29 -07:00
parent 291b195fa1
commit 940e898419
10 changed files with 163 additions and 49 deletions

View File

@ -1190,7 +1190,6 @@ bool AppInit2(boost::thread_group& threadGroup)
threadGroup.create_thread(boost::bind(&ThreadCheckDarkSendPool));
// ********************************************************* Step 11: load peers
uiInterface.InitMessage(_("Loading addresses..."));

View File

@ -3960,6 +3960,15 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
BOOST_FOREACH(const CTxOut o, out){
nValueOut += o.nValue;
tx.vout.push_back(o);
if(o.scriptPubKey.size() != 25){
printf("dsi - non-standard pubkey detected! %s\n", o.scriptPubKey.ToString().c_str());
accepted = 0;
error = "non-standard pubkey detected";
pfrom->PushMessage("dssu", darkSendPool.GetState(), darkSendPool.GetEntriesCount(), accepted, error);
return false;
}
}
BOOST_FOREACH(const CTxIn i, in){
@ -5942,7 +5951,7 @@ struct CompareValueOnly
int randomizeList (int i) { return std::rand()%i;}
void CDarkSendPool::SetNull(){
void CDarkSendPool::SetNull(bool clearEverything){
//printf("CDarkSendPool::SetNull()\n");
if(fMasterNode){
@ -5961,6 +5970,10 @@ void CDarkSendPool::SetNull(){
entriesCount = 0;
lastEntryAccepted = 0;
countEntriesAccepted = 0;
if(clearEverything){
myEntries.clear();
}
}
bool CDarkSendPool::SetCollateralAddress(std::string strAddress){
@ -6078,7 +6091,7 @@ void CDarkSendPool::Check()
// move on to next phase, allow 3 seconds incase the masternode wants to send us anything else
if((state == POOL_STATUS_TRANSMISSION && fMasterNode) || (state == POOL_STATUS_SIGNING && completedTransaction) ) {
printf("CDarkSendPool::Check() -- COMPLETED -- RESETTING \n");
SetNull();
SetNull(true);
UnlockCoins();
if(fMasterNode) RelayDarkSendStatus(darkSendPool.GetState(), darkSendPool.GetEntriesCount(), -1);
pwalletMain->Lock();
@ -6086,7 +6099,7 @@ void CDarkSendPool::Check()
if((state == POOL_STATUS_ERROR || state == POOL_STATUS_SUCCESS) && GetTimeMillis()-lastTimeChanged >= 10000) {
printf("CDarkSendPool::Check() -- RESETTING MESSAGE \n");
SetNull();
SetNull(true);
UnlockCoins();
}
}
@ -6176,7 +6189,7 @@ bool CDarkSendPool::SignatureValid(const CScript& newSig, const CTxIn& newVin){
bool CDarkSendPool::IsCollateralValid(const CTransaction& txCollateral){
if(txCollateral.vout[0].scriptPubKey != collateralPubKey ||
txCollateral.vout[0].nValue != POOL_FEE_AMOUNT) {
txCollateral.vout[0].nValue != DARKSEND_COLLATERAL) {
if(fDebug) printf ("CDarkSendPool::IsCollateralValid - not correct amount or addr (0)\n");
return false;
}
@ -6374,8 +6387,8 @@ bool CDarkSendPool::SignFinalTransaction(CTransaction& finalTransactionNew, CNod
return false;
}
finalTransaction = finalTransactionNew;
finalTransaction = finalTransactionNew;
printf("CDarkSendPool::SignFinalTransaction %s\n", finalTransaction.ToString().c_str());
//make sure node is master
@ -6833,14 +6846,12 @@ void CDarkSendPool::NewBlock()
resetEntries = true;
}
SetNull();
SetNull(true);
if(resetEntries){
UpdateState(POOL_STATUS_ERROR);
lastMessage = "masternode switched, please resubmit";
}
myEntries.clear();
}
}
@ -6965,12 +6976,18 @@ int CDarkSendPool::GetCurrentMasterNode(int mod, int64 nBlockHeight)
bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun)
{
if(fDisableDarksend) return false;
if (!fDryRun){
if(GetTime() - (60*2) > lastAutoDenomination) return false;
lastAutoDenomination = GetTime();
if(fDisableDarksend) {
printf("CDarkSendPool::DoAutomaticDenominating - Darksend is disabled\n");
return false;
}
/*
if (!fDryRun){
if(lastAutoDenomination + (60*2) > GetTime()) {
printf("CDarkSendPool::DoAutomaticDenominating - Not enough time has passed to Darksend again\n");
return false;
}
lastAutoDenomination = GetTime();
}*/
if (!fDryRun && pwalletMain->IsLocked()){
printf("DoAutomaticDenominating Error: Wallet is locked. Please unlock wallet to autodenominate..\n");
@ -7019,21 +7036,27 @@ bool CDarkSendPool::DoAutomaticDenominating(bool fDryRun)
if(strError == "") return true;
if(strError == "Error: Darksend requires a collateral transaction and could not locate an acceptable input!" || strError == "Insufficient funds") {
if(strError == "Insufficient funds") {
if(!fDryRun) SplitUpMoney();
return true;
} else if(strError == "Error: Darksend requires a collateral transaction and could not locate an acceptable input!"){
if(!fDryRun) SplitUpMoney(true);
return true;
} else {
printf("DoAutomaticDenominating : Error running denominate, %s\n", strError.c_str());
}
return false;
}
bool CDarkSendPool::SplitUpMoney()
bool CDarkSendPool::SplitUpMoney(bool justCollateral)
{
int64 nTotalBalance = pwalletMain->GetNonDenominatedBalance();
if(justCollateral && nTotalBalance > 2*COIN) nTotalBalance = 2*COIN;
int64 nTotalOut = 0;
printf("DoAutomaticDenominating: Split up large input:\n");
printf("DoAutomaticDenominating: Split up large input (justCollateral %d):\n", justCollateral);
printf(" auto -- nTotalBalance %"PRI64d"\n", nTotalBalance);
printf(" auto-- nTotalOut %"PRI64d"\n", nTotalOut);
// make our change address
CReserveKey reservekey(pwalletMain);
@ -7048,17 +7071,37 @@ bool CDarkSendPool::SplitUpMoney()
std::string strFail = "";
vector< pair<CScript, int64> > vecSend;
int64 FEE = 0.002*COIN;
int64 a = nTotalBalance/5;
if(a > 900*COIN) a = 900*COIN;
while(nTotalOut + a + (a/5) + (POOL_FEE_AMOUNT*4) < nTotalBalance-FEE){
printf(" nTotalOut %"PRI64d"\n", nTotalOut/COIN);
printf(" nTotalOut + ((nTotalBalance/5) + (nTotalBalance/5/5) + 0.01*COIN) %"PRI64d"\n", nTotalOut + ((a) + (a/5) + ((POOL_FEE_AMOUNT*4)))/COIN);
printf(" nTotalBalance-(FEE) %"PRI64d"\n", (nTotalBalance-FEE)/COIN);
vecSend.push_back(make_pair(scriptChange, a));
vecSend.push_back(make_pair(scriptChange, a/5));
vecSend.push_back(make_pair(scriptChange, POOL_FEE_AMOUNT*4));
nTotalOut += (a) + (a/5) + (POOL_FEE_AMOUNT*4);
printf(" auto-- split amount %"PRI64d"\n", a);
int64 addingEachRound = (DARKSEND_FEE*5);
if(!justCollateral) addingEachRound += (a) + (a/5);
while(nTotalOut + addingEachRound < nTotalBalance-DARKSEND_FEE){
printf(" nTotalOut %"PRI64d"\n", nTotalOut);
printf(" nTotalOut + ((nTotalBalance/5) + (nTotalBalance/5/5) + 0.01*COIN) %"PRI64d"\n", nTotalOut + ((a) + (a/5) + ((DARKSEND_FEE*4))));
printf(" nTotalBalance-(DARKSEND_COLLATERAL) %"PRI64d"\n", (nTotalBalance-DARKSEND_COLLATERAL));
if(!justCollateral){
vecSend.push_back(make_pair(scriptChange, a));
vecSend.push_back(make_pair(scriptChange, a/5));
nTotalOut += (a) + (a/5);
}
vecSend.push_back(make_pair(scriptChange, DARKSEND_COLLATERAL*5));
vecSend.push_back(make_pair(scriptChange, DARKSEND_FEE*5));
nTotalOut += (DARKSEND_COLLATERAL*5)+(DARKSEND_FEE*5);
}
printf(" auto2-- nTotalBalance %"PRI64d"\n", nTotalBalance);
printf(" auto2-- nTotalOut %"PRI64d"\n", nTotalOut);
if(!justCollateral){
if(nTotalOut <= 1.1*COIN || vecSend.size() < 4)
return false;
} else {
if(nTotalOut <= 0.1*COIN || vecSend.size() < 2)
return false;
}
CCoinControl *coinControl=NULL;
@ -7071,8 +7114,8 @@ bool CDarkSendPool::SplitUpMoney()
pwalletMain->CommitTransaction(wtx, reservekey);
printf("SplitUpMoney Success: tx %s\n", wtx.GetHash().GetHex().c_str());
return true;
return true;
}
int CDarkSendPool::GetMasternodeRank(CTxIn& vin, int mod)

View File

@ -36,7 +36,7 @@ class CBitcoinAddress;
#define START_MASTERNODE_PAYMENTS_TESTNET 1403568776 //Tue, 24 Jun 2014 00:12:56 GMT
#define START_MASTERNODE_PAYMENTS 1403728576 //Wed, 25 Jun 2014 20:36:16 GMT
#define POOL_MAX_TRANSACTIONS 1 // wait for X transactions to merge and publish
#define POOL_MAX_TRANSACTIONS 3 // wait for X transactions to merge and publish
#define POOL_STATUS_UNKNOWN 0 // waiting for update
#define POOL_STATUS_IDLE 1 // waiting for update
#define POOL_STATUS_ACCEPTING_ENTRIES 2 // accepting entries
@ -2568,7 +2568,8 @@ public:
bool VerifyMessage(CPubKey pubkey, std::vector<unsigned char>& vchSig, std::string strMessage, std::string& errorMessage);
};
static const int64 POOL_FEE_AMOUNT = 0.025*COIN;
static const int64 DARKSEND_COLLATERAL = 0.025*COIN;
static const int64 DARKSEND_FEE = 0.001*COIN;
/** Used to keep track of current status of darksend pool
*/
@ -2633,7 +2634,7 @@ public:
}
bool SetCollateralAddress(std::string strAddress);
void SetNull();
void SetNull(bool clearEverything=false);
void UnlockCoins();
@ -2737,7 +2738,7 @@ public:
void ClearLastMessage();
bool DoConcessusVote(int64 nBlockHeight);
int GetInputDarksendRounds(CTxIn in, int rounds=0);
bool SplitUpMoney();
bool SplitUpMoney(bool justCollateral=false);
int GetDenominations(std::vector<CTxOut> vout);
};

View File

@ -38,6 +38,7 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
//
BOOST_FOREACH(const CTxOut& txout, wtx.vout)
{
if(wallet->IsMine(txout))
{
TransactionRecord sub(hash, nTime);
@ -62,6 +63,13 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
sub.type = TransactionRecord::Generated;
}
BOOST_FOREACH(int64 d, darkSendDenominations){
if(txout.nValue == d) {
sub.type = TransactionRecord::RecvWithDarksend;
}
}
parts.append(sub);
}
}
@ -78,6 +86,18 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
if (fAllFromMe && fAllToMe)
{
for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++)
{
const CTxOut& txout = wtx.vout[nOut];
TransactionRecord sub(hash, nTime);
sub.idx = parts.size();
if(txout.nValue == DARKSEND_COLLATERAL*5) {
sub.type = TransactionRecord::DarksendSplitUpLarge;
}
}
// Payment to self
int64 nChange = wtx.GetChange();
@ -118,6 +138,13 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
sub.address = mapValue["to"];
}
if(txout.nValue == DARKSEND_COLLATERAL){
sub.type = TransactionRecord::DarksendCollateralPayment;
}
if(txout.nValue == DARKSEND_COLLATERAL*5){
sub.type = TransactionRecord::DarksendSplitUpLarge;
}
int64 nValue = txout.nValue;
/* Add fee to first output */
if (nTxFee > 0)
@ -133,9 +160,25 @@ QList<TransactionRecord> TransactionRecord::decomposeTransaction(const CWallet *
else
{
//
// Mixed debit transaction, can't break down payees
// Mixed Debit
//
parts.append(TransactionRecord(hash, nTime, TransactionRecord::Other, "", nNet, 0));
TransactionRecord sub(hash, nTime);
sub.idx = parts.size();
sub.type = TransactionRecord::Other;
for (unsigned int nOut = 0; nOut < wtx.vout.size(); nOut++)
{
const CTxOut& txout = wtx.vout[nOut];
BOOST_FOREACH(int64 d, darkSendDenominations){
if(txout.nValue == d) {
sub.type = TransactionRecord::DarksendDenominate;
}
}
}
parts.append(sub);
}
}

View File

@ -69,8 +69,12 @@ public:
SendToAddress,
SendToOther,
RecvWithAddress,
RecvWithDarksend,
RecvFromOther,
SendToSelf
SendToSelf,
DarksendDenominate,
DarksendCollateralPayment,
DarksendSplitUpLarge
};
/** Number of confirmation needed for transaction */

View File

@ -353,6 +353,8 @@ QString TransactionTableModel::formatTxType(const TransactionRecord *wtx) const
return tr("Received with");
case TransactionRecord::RecvFromOther:
return tr("Received from");
case TransactionRecord::RecvWithDarksend:
return tr("Received via Darksend");
case TransactionRecord::SendToAddress:
case TransactionRecord::SendToOther:
return tr("Sent to");
@ -360,6 +362,14 @@ QString TransactionTableModel::formatTxType(const TransactionRecord *wtx) const
return tr("Payment to yourself");
case TransactionRecord::Generated:
return tr("Mined");
case TransactionRecord::DarksendDenominate:
return tr("Darksend Denominate");
case TransactionRecord::DarksendCollateralPayment:
return tr("Darksend Collateral Payment");
case TransactionRecord::DarksendSplitUpLarge:
return tr("Darksend Split Up Large Inputs");
default:
return QString();
}
@ -371,6 +381,7 @@ QVariant TransactionTableModel::txAddressDecoration(const TransactionRecord *wtx
{
case TransactionRecord::Generated:
return QIcon(":/icons/tx_mined");
case TransactionRecord::RecvWithDarksend:
case TransactionRecord::RecvWithAddress:
case TransactionRecord::RecvFromOther:
return QIcon(":/icons/tx_input");
@ -390,6 +401,7 @@ QString TransactionTableModel::formatTxToAddress(const TransactionRecord *wtx, b
case TransactionRecord::RecvFromOther:
return QString::fromStdString(wtx->address);
case TransactionRecord::RecvWithAddress:
case TransactionRecord::RecvWithDarksend:
case TransactionRecord::SendToAddress:
case TransactionRecord::Generated:
return lookupAddress(wtx->address, tooltip);

View File

@ -18,7 +18,7 @@ Value darksend(const Array& params, bool fHelp)
if (fHelp || params.size() == 0)
throw runtime_error(
"darksend <darkcoinaddress> <amount>\n"
"darkcoinaddress, denominate, or auto (AutoDenominate)"
"darkcoinaddress, reset, or auto (AutoDenominate)"
"<amount> is a real and is rounded to the nearest 0.00000001"
+ HelpRequiringPassphrase());
@ -33,6 +33,11 @@ Value darksend(const Array& params, bool fHelp)
return "DoAutomaticDenominating";
}
if(params[0].get_str() == "reset"){
darkSendPool.SetNull(true);
return "successfully reset darksend";
}
if (params.size() != 2)
throw runtime_error(
"darksend <darkcoinaddress> <amount>\n"
@ -41,7 +46,7 @@ Value darksend(const Array& params, bool fHelp)
+ HelpRequiringPassphrase());
CBitcoinAddress address(params[0].get_str());
if (!address.IsValid() && params[0].get_str() != "denominate")
if (!address.IsValid())
throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Invalid DarkCoin address");
// Amount

View File

@ -228,7 +228,7 @@ const char* GetOpName(opcodetype opcode)
}
bool IsCanonicalPubKey(const valtype &vchPubKey) {
if (vchPubKey.size() < 33)
if (vchPubKey.size() < 25)
return error("Non-canonical public key: too short");
if (vchPubKey[0] == 0x04) {
if (vchPubKey.size() != 65)
@ -237,7 +237,7 @@ bool IsCanonicalPubKey(const valtype &vchPubKey) {
if (vchPubKey.size() != 33)
return error("Non-canonical public key: invalid length for compressed key");
} else {
return error("Non-canonical public key: compressed nor uncompressed");
return error("Non-canonical public key: compressed nor uncompressed : size %d", vchPubKey.size());
}
return true;
}

View File

@ -1268,7 +1268,7 @@ bool CWallet::SelectCoinsDark(int64 nValueMin, int64 nValueMax, std::vector<CTxI
BOOST_FOREACH(const COutput& out, vCoins)
{
if(out.tx->vout[out.i].nValue == POOL_FEE_AMOUNT*4) continue; //these are made for collateral
if(out.tx->vout[out.i].nValue <= 1*COIN) continue; //these are made for collateral/fees/etc
if(fMasterNode && out.tx->vout[out.i].nValue == 1000*COIN) continue; //masternode input
if(nValueRet + out.tx->vout[out.i].nValue <= nValueMax){
@ -1294,7 +1294,7 @@ bool CWallet::SelectCoinsDark(int64 nValueMin, int64 nValueMax, std::vector<CTxI
return false;
}
bool CWallet::SelectCoinsCollateral(int64 nValueMin, int64 nValueMax, std::vector<CTxIn>& setCoinsRet, int64& nValueRet) const
bool CWallet::SelectCoinsCollateral(std::vector<CTxIn>& setCoinsRet, int64& nValueRet) const
{
CCoinControl *coinControl=NULL;
@ -1307,7 +1307,13 @@ bool CWallet::SelectCoinsCollateral(int64 nValueMin, int64 nValueMax, std::vecto
BOOST_FOREACH(const COutput& out, vCoins)
{
if(nValueRet + out.tx->vout[out.i].nValue <= nValueMax){
if(
out.tx->vout[out.i].nValue == DARKSEND_COLLATERAL ||
out.tx->vout[out.i].nValue == DARKSEND_COLLATERAL * 2 ||
out.tx->vout[out.i].nValue == DARKSEND_COLLATERAL * 3 ||
out.tx->vout[out.i].nValue == DARKSEND_COLLATERAL * 4 ||
out.tx->vout[out.i].nValue == DARKSEND_COLLATERAL * 5
){
CTxIn vin = CTxIn(out.tx->GetHash(),out.i);
printf(" vin nValue %"PRI64d"\n", out.tx->vout[out.i].nValue);
@ -1316,12 +1322,10 @@ bool CWallet::SelectCoinsCollateral(int64 nValueMin, int64 nValueMax, std::vecto
setCoinsRet.push_back(vin);
setCoinsRet2.insert(make_pair(out.tx, out.i));
printf(" -- nValueRet %"PRI64d"\n", nValueRet);
if(nValueRet >= nValueMax) return true;
return true;
}
}
if(nValueRet >= nValueMin) return true;
return false;
}
@ -1381,6 +1385,7 @@ bool CWallet::CreateTransaction(std::vector<pair<CScript, int64> >& vecSend,
return false;
}
wtxNew.BindWallet(this);
{
@ -1492,6 +1497,8 @@ bool CWallet::CreateTransaction(std::vector<pair<CScript, int64> >& vecSend,
BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
wtxNew.vin.push_back(CTxIn(coin.first->GetHash(),coin.second));
if(fDebug) printf("CreateTransaction %s\n", wtxNew.ToString().c_str());
// Sign
int nIn = 0;
BOOST_FOREACH(const PAIRTYPE(const CWalletTx*,unsigned int)& coin, setCoins)
@ -1696,7 +1703,7 @@ string CWallet::DarkSendDenominate()
int64 nValueIn2 = 0;
std::vector<CTxIn> vCoinsCollateral;
if (!SelectCoinsCollateral(POOL_FEE_AMOUNT, 1*COIN, vCoinsCollateral, nValueIn2))
if (!SelectCoinsCollateral(vCoinsCollateral, nValueIn2))
{
BOOST_FOREACH(CTxIn v, vCoins)
UnlockCoin(v.prevout);
@ -1713,15 +1720,15 @@ string CWallet::DarkSendDenominate()
reservedKeys.push_back(reservekey.GetIndex());
reservekey.Reset();
CTxOut vout2 = CTxOut(POOL_FEE_AMOUNT, darkSendPool.collateralPubKey);
CTxOut vout2 = CTxOut(DARKSEND_COLLATERAL, darkSendPool.collateralPubKey);
BOOST_FOREACH(CTxIn v, vCoinsCollateral)
txCollateral.vin.push_back(v);
txCollateral.vout.push_back(vout2);
if(nValueIn2 - POOL_FEE_AMOUNT > 0) {
CTxOut vout3 = CTxOut(nValueIn2 - POOL_FEE_AMOUNT, scriptChange);
if(nValueIn2 - DARKSEND_COLLATERAL > 0) {
CTxOut vout3 = CTxOut(nValueIn2 - DARKSEND_COLLATERAL, scriptChange);
txCollateral.vout.push_back(vout3);
}

View File

@ -91,7 +91,7 @@ public:
bool SelectCoinsDarkDenominated(int64 nTargetValue, std::vector<CTxIn>& setCoinsRet, int64& nValueRet) const;
bool SelectCoinsExactOutput(int64 nTargetValue, CTxIn& vin, int64& nValueRet, CScript& pubScript, bool confirmed) const;
bool SelectCoinsCollateral(int64 nValueMin, int64 nValueMax, std::vector<CTxIn>& setCoinsRet, int64& nValueRet) const;
bool SelectCoinsCollateral(std::vector<CTxIn>& setCoinsRet, int64& nValueRet) const ;
bool SelectCoinsWithoutDenomination(int64 nTargetValue, std::set<std::pair<const CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet) const;
bool SelectCoinsMoreThanOutput(int64 nTargetValue, CTxIn& vin, int64& nValueRet, bool confirmed) const;