Daily upstream merge.

This commit is contained in:
crowning2 2015-03-04 20:32:56 +01:00
commit 8702795d9d
20 changed files with 1209 additions and 621 deletions

View File

@ -41,6 +41,7 @@ BITCOIN_CORE_H = \
core.h \
crypter.h \
darksend.h \
darksend-relay.h \
db.h \
hash.h \
init.h \
@ -151,6 +152,7 @@ libdarkcoin_common_a_SOURCES = \
chainparams.cpp \
core.cpp \
darksend.cpp \
darksend-relay.cpp \
masternode.cpp \
masternodeman.cpp \
masternodeconfig.cpp \

View File

@ -217,8 +217,8 @@ bool CActiveMasternode::Dseep(CTxIn vin, CService service, CKey keyMasternode, C
}
//send to all peers
LogPrintf("CActiveMasternode::Dseep() - SendDarkSendElectionEntryPing vin = %s\n", vin.ToString().c_str());
SendDarkSendElectionEntryPing(vin, vchMasterNodeSignature, masterNodeSignatureTime, stop);
LogPrintf("CActiveMasternode::Dseep() - RelayMasternodeEntryPing vin = %s\n", vin.ToString().c_str());
mnodeman.RelayMasternodeEntryPing(vin, vchMasterNodeSignature, masterNodeSignatureTime, stop);
return true;
}
@ -277,8 +277,8 @@ bool CActiveMasternode::Register(CTxIn vin, CService service, CKey keyCollateral
}
//send to all peers
LogPrintf("CActiveMasternode::Register() - SendDarkSendElectionEntry vin = %s\n", vin.ToString().c_str());
SendDarkSendElectionEntry(vin, service, vchMasterNodeSignature, masterNodeSignatureTime, pubKeyCollateralAddress, pubKeyMasternode, -1, -1, masterNodeSignatureTime, PROTOCOL_VERSION);
LogPrintf("CActiveMasternode::Register() - RelayElectionEntry vin = %s\n", vin.ToString().c_str());
mnodeman.RelayMasternodeEntry(vin, service, vchMasterNodeSignature, masterNodeSignatureTime, pubKeyCollateralAddress, pubKeyMasternode, -1, -1, masterNodeSignatureTime, PROTOCOL_VERSION);
return true;
}

View File

@ -12,6 +12,8 @@ class CCoinControl
{
public:
CTxDestination destChange;
bool useDarkSend;
bool useInstantX;
CCoinControl()
{
@ -22,6 +24,8 @@ public:
{
destChange = CNoDestination();
setSelected.clear();
useInstantX = false;
useDarkSend = true;
}
bool HasSelected() const

View File

@ -43,6 +43,8 @@ static const int64_t DARKSEND_POOL_MAX = (999.99*COIN);
#define MASTERNODE_EXPIRATION_SECONDS (65*60)
#define MASTERNODE_REMOVAL_SECONDS (70*60)
static const int MIN_POOL_PEER_PROTO_VERSION = 70067; // minimum peer version accepted by DarkSendPool
class CTransaction;
/** No amount larger than this (in satoshi) is valid */

132
src/darksend-relay.cpp Normal file
View File

@ -0,0 +1,132 @@
#include "darksend-relay.h"
CDarkSendRelay::CDarkSendRelay()
{
vinMasternode = CTxIn();
nBlockHeight = 0;
nRelayType = 0;
in = CTxIn();
out = CTxOut();
strSharedKey = "";
}
CDarkSendRelay::CDarkSendRelay(CTxIn& vinMasternodeIn, vector<unsigned char>& vchSigIn, int nBlockHeightIn, int nRelayTypeIn, CTxIn& in2, CTxOut& out2, std::string strSharedKeyIn)
{
vinMasternode = vinMasternodeIn;
vchSig = vchSigIn;
nBlockHeight = nBlockHeightIn;
nRelayType = nRelayTypeIn;
in = in2;
out = out2;
strSharedKey = strSharedKeyIn;
}
std::string CDarkSendRelay::ToString()
{
std::ostringstream info;
info << "vin: " << vinMasternode.ToString() <<
" nBlockHeight: " << (int)nBlockHeight <<
" nRelayType: " << (int)nRelayType <<
" in " << in.ToString() <<
" out " << out.ToString();
return info.str();
}
bool CDarkSendRelay::Sign()
{
if(!fMasterNode) return false;
std::string strMessage = in.ToString() + out.ToString();
CKey key2;
CPubKey pubkey2;
std::string errorMessage = "";
if(!darkSendSigner.SetKey(strSharedKey, errorMessage, key2, pubkey2))
{
LogPrintf("CDarkSendRelay():Relay - ERROR: Invalid masternodeprivkey: '%s'\n", errorMessage.c_str());
return false;
}
if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchSig2, key2)) {
LogPrintf("CDarkSendRelay():Relay - Sign message failed");
return false;
}
if(!darkSendSigner.VerifyMessage(pubkey2, vchSig, strMessage, errorMessage)) {
LogPrintf("CDarkSendRelay():Relay - Verify message failed");
return false;
}
return true;
}
bool CDarkSendRelay::VerifyMessage(std::string strSharedKey)
{
if(!fMasterNode) return false;
std::string strMessage = in.ToString() + out.ToString();
CKey key2;
CPubKey pubkey2;
std::string errorMessage = "";
if(!darkSendSigner.SetKey(strSharedKey, errorMessage, key2, pubkey2))
{
LogPrintf("CDarkSendRelay():Relay - ERROR: Invalid masternodeprivkey: '%s'\n", errorMessage.c_str());
return false;
}
if(!darkSendSigner.SignMessage(strMessage, errorMessage, vchSig2, key2)) {
LogPrintf("CDarkSendRelay():Relay - Sign message failed");
return false;
}
if(!darkSendSigner.VerifyMessage(pubkey2, vchSig, strMessage, errorMessage)) {
LogPrintf("CDarkSendRelay():Relay - Verify message failed");
return false;
}
return true;
}
void CDarkSendRelay::Relay()
{
int nCount = std::min(mnodeman.CountEnabled(), 20);
int nRank1 = (rand() % nCount)+1;
int nRank2 = (rand() % nCount)+1;
//keep picking another second number till we get one that doesn't match
while(nRank1 == nRank2) nRank2 = (rand() % nCount)+1;
//printf("rank 1 - rank2 %d %d \n", nRank1, nRank2);
//relay this message through 2 separate nodes for redundancy
RelayThroughNode(nRank1);
RelayThroughNode(nRank2);
}
void CDarkSendRelay::RelayThroughNode(int nRank)
{
CMasternode* pmn = mnodeman.GetMasternodeByRank(nRank, nBlockHeight, MIN_POOL_PEER_PROTO_VERSION);
if(pmn){
//printf("RelayThroughNode %s\n", pmn->addr.ToString().c_str());
if(ConnectNode((CAddress)pmn->addr, NULL, true)){
//printf("Connected\n");
CNode* pNode = FindNode(pmn->addr);
if(pNode)
{
//printf("Found\n");
pNode->PushMessage("dsr", (*this));
return;
}
}
} else {
//printf("RelayThroughNode NULL\n");
}
}

51
src/darksend-relay.h Normal file
View File

@ -0,0 +1,51 @@
// Copyright (c) 2014-2015 The Darkcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef DARKSEND_RELAY_H
#define DARKSEND_RELAY_H
#include "core.h"
#include "main.h"
#include "activemasternode.h"
#include "masternodeman.h"
class CDarkSendRelay
{
public:
CTxIn vinMasternode;
vector<unsigned char> vchSig;
vector<unsigned char> vchSig2;
int nBlockHeight;
int nRelayType;
CTxIn in;
CTxOut out;
std::string strSharedKey;
CDarkSendRelay();
CDarkSendRelay(CTxIn& vinMasternodeIn, vector<unsigned char>& vchSigIn, int nBlockHeightIn, int nRelayTypeIn, CTxIn& in2, CTxOut& out2, std::string strSharedKeyIn);
IMPLEMENT_SERIALIZE
(
READWRITE(vinMasternode);
READWRITE(vchSig);
READWRITE(vchSig2);
READWRITE(nBlockHeight);
READWRITE(nRelayType);
READWRITE(in);
READWRITE(out);
)
std::string ToString();
bool Sign();
bool VerifyMessage(std::string strSharedKey);
void Relay();
void RelayThroughNode(int nRank);
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -9,9 +9,10 @@
#include "main.h"
#include "activemasternode.h"
#include "masternodeman.h"
#include "darksend-relay.h"
class CTxIn;
class CDarkSendPool;
class CDarksendPool;
class CDarkSendSigner;
class CMasterNodeVote;
class CBitcoinAddress;
@ -19,7 +20,9 @@ class CDarksendQueue;
class CDarksendBroadcastTx;
class CActiveMasternode;
// pool states for mixing
#define POOL_MAX_TRANSACTIONS 3 // wait for X transactions to merge and publish
#define POOL_MAX_TRANSACTIONS_TESTNET 2 // 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_QUEUE 2 // waiting in a queue
@ -37,43 +40,49 @@ class CActiveMasternode;
#define DARKSEND_QUEUE_TIMEOUT 120
#define DARKSEND_SIGNING_TIMEOUT 30
#define DARKSEND_DOWNGRADE_TIMEOUT 30
static const int MIN_POOL_PEER_PROTO_VERSION = 70067; // minimum peer version accepted by DarkSendPool
// used for anonymous relaying of inputs/outputs/sigs
#define DARKSEND_RELAY_IN 1
#define DARKSEND_RELAY_OUT 2
#define DARKSEND_RELAY_SIG 3
extern CDarkSendPool darkSendPool;
extern CDarksendPool darkSendPool;
extern CDarkSendSigner darkSendSigner;
extern std::vector<CDarksendQueue> vecDarksendQueue;
extern std::string strMasterNodePrivKey;
extern map<uint256, CDarksendBroadcastTx> mapDarksendBroadcastTxes;
extern CActiveMasternode activeMasternode;
//specific messages for the Darksend protocol
void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
// get the darksend chain depth for a given input
int GetInputDarksendRounds(CTxIn in, int rounds=0);
//
// Holds an Darksend input
//
// An input in the darksend pool
class CDarkSendEntryVin
class CTxDSIn : public CTxIn
{
public:
bool isSigSet;
CTxIn vin;
bool fHasSig;
CDarkSendEntryVin()
CTxDSIn(const CTxIn& in)
{
isSigSet = false;
vin = CTxIn();
prevout = in.prevout;
scriptSig = in.scriptSig;
prevPubKey = in.prevPubKey;
nSequence = in.nSequence;
}
};
// A clients transaction in the darksend pool
// -- holds the input/output mapping for each user in the pool
class CDarkSendEntry
{
public:
bool isSet;
std::vector<CDarkSendEntryVin> sev;
std::vector<CTxIn> sev;
int64_t amount;
CTransaction collateral;
std::vector<CTxOut> vout;
@ -91,11 +100,7 @@ public:
{
if(isSet){return false;}
BOOST_FOREACH(const CTxIn v, vinIn) {
CDarkSendEntryVin s = CDarkSendEntryVin();
s.vin = v;
sev.push_back(s);
}
sev = vinIn;
vout = voutIn;
amount = amountIn;
collateral = collateralIn;
@ -105,28 +110,13 @@ public:
return true;
}
bool AddSig(const CTxIn& vin)
{
BOOST_FOREACH(CDarkSendEntryVin& s, sev) {
if(s.vin.prevout == vin.prevout && s.vin.nSequence == vin.nSequence){
if(s.isSigSet){return false;}
s.vin.scriptSig = vin.scriptSig;
s.vin.prevPubKey = vin.prevPubKey;
s.isSigSet = true;
return true;
}
}
return false;
}
bool IsExpired()
{
return (GetTime() - addedTime) > DARKSEND_QUEUE_TIMEOUT;// 120 seconds
}
};
//
// A currently inprogress darksend merge and denomination information
//
@ -139,12 +129,20 @@ 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;
CDarksendQueue()
{
nDenom = 0;
vin = CTxIn();
time = 0;
vchSig.clear();
vchRelaySig.clear();
nBlockHeight = 0;
strSharedKey = "";
ready = false;
}
@ -155,6 +153,12 @@ public:
READWRITE(time);
READWRITE(ready);
READWRITE(vchSig);
if(ready){
READWRITE(vchRelaySig);
READWRITE(nBlockHeight);
READWRITE(strSharedKey);
}
)
bool GetAddress(CService &addr)
@ -213,15 +217,29 @@ public:
bool VerifyMessage(CPubKey pubkey, std::vector<unsigned char>& vchSig, std::string strMessage, std::string& errorMessage);
};
class CDarksendSession
//
// Build a transaction anonymously
//
class CDSAnonTx
{
public:
std::vector<CTxDSIn> vin;
std::vector<CTxOut> vout;
bool IsTransactionValid();
bool AddOutput(const CTxOut out);
bool AddInput(const CTxIn in);
bool AddSig(const CTxIn in);
int CountEntries() {return (int)vin.size() + (int)vout.size();}
};
void ConnectToDarkSendMasterNodeWinner();
//
// Used to keep track of current status of darksend pool
//
class CDarkSendPool
class CDarksendPool
{
public:
@ -231,6 +249,10 @@ public:
std::vector<CDarkSendEntry> entries;
// the finalized transaction ready for signing
CTransaction finalTransaction;
// anonymous inputs/outputs
CDSAnonTx anonTx;
bool fSubmitAnonymousFailed;
int nCountAttempts;
int64_t lastTimeChanged;
int64_t lastAutoDenomination;
@ -250,7 +272,7 @@ public:
std::string lastMessage;
bool completedTransaction;
bool unitTest;
CService submittedToMasternode;
CMasternode* pSubmittedToMasternode;
int sessionID;
int sessionDenom; //Users must submit an denom matching this
@ -269,10 +291,16 @@ public:
//debugging data
std::string strAutoDenomResult;
// used for securing the anonymous relay system
vector<unsigned char> vchMasternodeRelaySig;
int nMasternodeBlockHeight;
std::string strMasternodeSharedKey;
bool fResentInputsOutputs;
//incremented whenever a DSQ comes through
int64_t nDsqCount;
CDarkSendPool()
CDarksendPool()
{
/* DarkSend uses collateral addresses to trust parties entering the pool
to behave themselves. If they don't it takes their money. */
@ -284,11 +312,14 @@ public:
minBlockSpacing = 1;
nDsqCount = 0;
lastNewBlock = 0;
strMasternodeSharedKey = "";
fResentInputsOutputs = false;
SetNull();
}
void ProcessMasternodeConnections();
//specific messages for the Darksend protocol
void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
void InitCollateralAddress(){
std::string strAddress = "";
@ -306,6 +337,9 @@ public:
bool SetCollateralAddress(std::string strAddress);
void Reset();
bool Downgrade();
bool ResendMissingInputsOutputs();
void SetNull(bool clearEverything=false);
void UnlockCoins();
@ -347,15 +381,15 @@ public:
void UpdateState(unsigned int newState)
{
if (fMasterNode && (newState == POOL_STATUS_ERROR || newState == POOL_STATUS_SUCCESS)){
LogPrintf("CDarkSendPool::UpdateState() - Can't set state to ERROR or SUCCESS as a masternode. \n");
LogPrintf("CDarksendPool::UpdateState() - Can't set state to ERROR or SUCCESS as a masternode. \n");
return;
}
LogPrintf("CDarkSendPool::UpdateState() == %d | %d \n", state, newState);
LogPrintf("CDarksendPool::UpdateState() == %d | %d \n", state, newState);
if(state != newState){
lastTimeChanged = GetTimeMillis();
if(fMasterNode) {
RelayDarkSendStatus(darkSendPool.sessionID, darkSendPool.GetState(), darkSendPool.GetEntriesCount(), MASTERNODE_RESET);
RelayStatus(darkSendPool.sessionID, darkSendPool.GetState(), darkSendPool.GetEntriesCount(), MASTERNODE_RESET);
}
}
state = newState;
@ -364,7 +398,7 @@ public:
int GetMaxPoolTransactions()
{
//if we're on testnet, just use two transactions per merge
if(Params().NetworkID() == CChainParams::TESTNET || Params().NetworkID() == CChainParams::REGTEST) return 2;
if(Params().NetworkID() == CChainParams::TESTNET || Params().NetworkID() == CChainParams::REGTEST) return POOL_MAX_TRANSACTIONS_TESTNET;
//use the production amount
return POOL_MAX_TRANSACTIONS;
@ -376,7 +410,8 @@ public:
}
// Are these outputs compatible with other client in the pool?
bool IsCompatibleWithEntries(std::vector<CTxOut> vout);
bool IsCompatibleWithEntries(std::vector<CTxOut>& vout);
// Is this amount compatible with other client in the pool?
bool IsCompatibleWithSession(int64_t nAmount, CTransaction txCollateral, std::string& strReason);
@ -384,20 +419,33 @@ public:
bool DoAutomaticDenominating(bool fDryRun=false, bool ready=false);
bool PrepareDarksendDenominate();
// check for process in Darksend
void Check();
void CheckFinalTransaction();
// charge fees to bad actors
void ChargeFees();
// rarely charge fees to pay miners
void ChargeRandomFees();
void CheckTimeout();
void CheckForCompleteQueue();
// check to make sure a signature matches an input in the pool
bool SignatureValid(const CScript& newSig, const CTxIn& newVin);
// if the collateral is valid given by a client
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);
// are all inputs signed?
@ -418,21 +466,32 @@ public:
void ClearLastMessage();
// used for liquidity providers
bool SendRandomPaymentToSelf();
// split up large inputs or make fee sized inputs
bool MakeCollateralAmounts();
bool CreateDenominated(int64_t nTotalValue);
// get the denominations for a list of outputs (returns a bitshifted integer)
int GetDenominations(const std::vector<CTxOut>& vout);
void GetDenominationsToString(int nDenom, std::string& strDenom);
// get the denominations for a specific amount of darkcoin.
int GetDenominationsByAmount(int64_t nAmount, int nDenomTarget=0);
int GetDenominationsByAmounts(std::vector<int64_t>& vecAmount);
//
// Relay Darksend Messages
//
void RelayFinalTransaction(const int sessionID, const CTransaction& txNew);
void RelaySignaturesAnon(std::vector<CTxIn>& vin);
void RelayInAnon(std::vector<CTxIn>& vin, std::vector<CTxOut>& vout);
void RelayIn(const std::vector<CTxIn>& vin, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxOut>& vout);
void RelayStatus(const int sessionID, const int newState, const int newEntriesCount, const int newAccepted, const std::string error="");
void RelayCompletedTransaction(const int sessionID, const bool error, const std::string errorMessage);
};
void ConnectToDarkSendMasterNodeWinner();
void ThreadCheckDarkSendPool();
#endif

View File

@ -4061,9 +4061,8 @@ void static ProcessGetData(CNode* pfrom)
if (!pushed && inv.type == MSG_MASTERNODE_WINNER) {
if(mapSeenMasternodeVotes.count(inv.hash)){
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
int a = 0;
ss.reserve(1000);
ss << mapSeenMasternodeVotes[inv.hash] << a;
ss << mapSeenMasternodeVotes[inv.hash];
pfrom->PushMessage("mnw", ss);
pushed = true;
}
@ -4824,7 +4823,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
else
{
//probably one the extensions
ProcessMessageDarksend(pfrom, strCommand, vRecv);
darkSendPool.ProcessMessageDarksend(pfrom, strCommand, vRecv);
mnodeman.ProcessMessage(pfrom, strCommand, vRecv);
ProcessMessageMasternodePayments(pfrom, strCommand, vRecv);
ProcessMessageInstantX(pfrom, strCommand, vRecv);

View File

@ -353,7 +353,7 @@ int CMasternodeMan::GetMasternodeRank(const CTxIn& vin, int64_t nBlockHeight, in
sort(vecMasternodeScores.rbegin(), vecMasternodeScores.rend(), CompareValueOnly());
unsigned int rank = 0;
int rank = 0;
BOOST_FOREACH (PAIRTYPE(unsigned int, CTxIn)& s, vecMasternodeScores){
rank++;
if(s.second == vin) {
@ -364,6 +364,71 @@ int CMasternodeMan::GetMasternodeRank(const CTxIn& vin, int64_t nBlockHeight, in
return -1;
}
CMasternode* CMasternodeMan::GetMasternodeByRank(int nRank, int64_t nBlockHeight, int minProtocol)
{
std::vector<pair<unsigned int, CTxIn> > vecMasternodeScores;
// scan for winner
BOOST_FOREACH(CMasternode& mn, vMasternodes) {
mn.Check();
if(mn.protocolVersion < minProtocol) continue;
if(!mn.IsEnabled()) {
continue;
}
uint256 n = mn.CalculateScore(1, nBlockHeight);
unsigned int n2 = 0;
memcpy(&n2, &n, sizeof(n2));
vecMasternodeScores.push_back(make_pair(n2, mn.vin));
}
sort(vecMasternodeScores.rbegin(), vecMasternodeScores.rend(), CompareValueOnly());
int rank = 0;
BOOST_FOREACH (PAIRTYPE(unsigned int, CTxIn)& s, vecMasternodeScores){
rank++;
if(rank == nRank) {
return Find(s.second);
}
}
return NULL;
}
void CMasternodeMan::ProcessMasternodeConnections()
{
LOCK(cs_vNodes);
if(!darkSendPool.pSubmittedToMasternode) return;
BOOST_FOREACH(CNode* pnode, vNodes)
{
if(darkSendPool.pSubmittedToMasternode->addr == pnode->addr) continue;
if(pnode->fDarkSendMaster){
LogPrintf("Closing masternode connection %s \n", pnode->addr.ToString().c_str());
pnode->CloseSocketDisconnect();
}
}
}
void CMasternodeMan::RelayMasternodeEntry(const CTxIn vin, const CService addr, const std::vector<unsigned char> vchSig, const int64_t nNow, const CPubKey pubkey, const CPubKey pubkey2, const int count, const int current, const int64_t lastUpdated, const int protocolVersion)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
pnode->PushMessage("dsee", vin, addr, vchSig, nNow, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
}
void CMasternodeMan::RelayMasternodeEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64_t nNow, const bool stop)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
pnode->PushMessage("dseep", vin, vchSig, nNow, stop);
}
void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
{
@ -457,7 +522,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
pmn->addr = addr;
pmn->Check();
if(pmn->IsEnabled())
RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
mnodeman.RelayMasternodeEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
}
}
@ -523,7 +588,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
}
if(count == -1 && !isLocal)
RelayDarkSendElectionEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
mnodeman.RelayMasternodeEntry(vin, addr, vchSig, sigTime, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
} else {
LogPrintf("dsee - Rejected masternode entry %s\n", addr.ToString().c_str());
@ -588,7 +653,7 @@ void CMasternodeMan::ProcessMessage(CNode* pfrom, std::string& strCommand, CData
pmn->Check();
if(!pmn->IsEnabled()) return;
}
RelayDarkSendElectionEntryPing(vin, vchSig, sigTime, stop);
mnodeman.RelayMasternodeEntryPing(vin, vchSig, sigTime, stop);
}
}
return;

View File

@ -107,14 +107,25 @@ public:
std::vector<CMasternode> GetFullMasternodeVector() { Check(); return vMasternodes; }
int GetMasternodeRank(const CTxIn &vin, int64_t nBlockHeight, int minProtocol=0);
CMasternode* GetMasternodeByRank(int nRank, int64_t nBlockHeight, int minProtocol=0);
void ProcessMessage(CNode* pfrom, std::string& strCommand, CDataStream& vRecv);
void ProcessMasternodeConnections();
// Return the number of (unique) masternodes
int size() { return vMasternodes.size(); }
std::string ToString();
//
// Relay Masternode Messages
//
void RelayMasternodeEntry(const CTxIn vin, const CService addr, const std::vector<unsigned char> vchSig, const int64_t nNow, const CPubKey pubkey, const CPubKey pubkey2, const int count, const int current, const int64_t lastUpdated, const int protocolVersion);
void RelayMasternodeEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64_t nNow, const bool stop);
};
#endif

View File

@ -1874,85 +1874,6 @@ void RelayTransactionLockReq(const CTransaction& tx, const uint256& hash, bool r
}
void RelayDarkSendFinalTransaction(const int sessionID, const CTransaction& txNew)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
pnode->PushMessage("dsf", sessionID, txNew);
}
}
void RelayDarkSendIn(const std::vector<CTxIn>& in, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxOut>& out)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
if((CNetAddr)darkSendPool.submittedToMasternode != (CNetAddr)pnode->addr) continue;
LogPrintf("RelayDarkSendIn - found master, relaying message - %s \n", pnode->addr.ToString().c_str());
pnode->PushMessage("dsi", in, nAmount, txCollateral, out);
}
}
void RelayDarkSendStatus(const int sessionID, const int newState, const int newEntriesCount, const int newAccepted, const std::string error)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
pnode->PushMessage("dssu", sessionID, newState, newEntriesCount, newAccepted, error);
}
}
void RelayDarkSendElectionEntry(const CTxIn vin, const CService addr, const std::vector<unsigned char> vchSig, const int64_t nNow, const CPubKey pubkey, const CPubKey pubkey2, const int count, const int current, const int64_t lastUpdated, const int protocolVersion)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
if(!pnode->fRelayTxes) continue;
pnode->PushMessage("dsee", vin, addr, vchSig, nNow, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
}
}
void SendDarkSendElectionEntry(const CTxIn vin, const CService addr, const std::vector<unsigned char> vchSig, const int64_t nNow, const CPubKey pubkey, const CPubKey pubkey2, const int count, const int current, const int64_t lastUpdated, const int protocolVersion)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
pnode->PushMessage("dsee", vin, addr, vchSig, nNow, pubkey, pubkey2, count, current, lastUpdated, protocolVersion);
}
}
void RelayDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64_t nNow, const bool stop)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
if(!pnode->fRelayTxes) continue;
pnode->PushMessage("dseep", vin, vchSig, nNow, stop);
}
}
void SendDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64_t nNow, const bool stop)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
pnode->PushMessage("dseep", vin, vchSig, nNow, stop);
}
}
void RelayDarkSendCompletedTransaction(const int sessionID, const bool error, const std::string errorMessage)
{
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes)
{
pnode->PushMessage("dsc", sessionID, error, errorMessage);
}
}
void CNode::RecordBytesRecv(uint64_t bytes)
{
LOCK(cs_totalBytesRecv);
@ -2103,3 +2024,4 @@ bool CAddrDB::Read(CAddrMan& addr)
return true;
}

View File

@ -760,15 +760,6 @@ class CTransaction;
void RelayTransaction(const CTransaction& tx, const uint256& hash);
void RelayTransaction(const CTransaction& tx, const uint256& hash, const CDataStream& ss);
void RelayTransactionLockReq(const CTransaction& tx, const uint256& hash, bool relayToAll=false);
void RelayDarkSendFinalTransaction(const int sessionID, const CTransaction& txNew);
void RelayDarkSendIn(const std::vector<CTxIn>& in, const int64_t& nAmount, const CTransaction& txCollateral, const std::vector<CTxOut>& out);
void RelayDarkSendStatus(const int sessionID, const int newState, const int newEntriesCount, const int newAccepted, const std::string error="");
void RelayDarkSendElectionEntry(const CTxIn vin, const CService addr, const std::vector<unsigned char> vchSig, const int64_t nNow, const CPubKey pubkey, const CPubKey pubkey2, const int count, const int current, const int64_t lastUpdated, const int protocolVersion);
void SendDarkSendElectionEntry(const CTxIn vin, const CService addr, const std::vector<unsigned char> vchSig, const int64_t nNow, const CPubKey pubkey, const CPubKey pubkey2, const int count, const int current, const int64_t lastUpdated, const int protocolVersion);
void RelayDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64_t nNow, const bool stop);
void SendDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64_t nNow, const bool stop);
void RelayDarkSendCompletedTransaction(const int sessionID, const bool error, const std::string errorMessage);
void RelayDarkSendMasterNodeContestant();
/** Access to the (IP) address database (peers.dat) */

View File

@ -543,6 +543,9 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
// Fee
int64_t nFee = nTransactionFee * (1 + (int64_t)nBytes / 1000);
// IX Fee
if(coinControl->useInstantX) nFee = max(nFee, CENT);
// Min Fee
int64_t nMinFee = GetMinFee(txDummy, nBytes, AllowFree(dPriority), GMF_SEND);
@ -552,6 +555,13 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog)
{
nChange = nAmount - nPayFee - nPayAmount;
// DS Fee = overpay
if(coinControl->useDarkSend && nChange > 0)
{
nPayFee += nChange;
nChange = 0;
}
// if sub-cent change is required, the fee must be raised to at least CTransaction::nMinTxFee
if (nPayFee < CTransaction::nMinTxFee && nChange > 0 && nChange < CENT)
{

View File

@ -373,10 +373,12 @@ void OverviewPage::darkSendStatus()
/* ** @TODO this string creation really needs some clean ups ---vertoe ** */
std::ostringstream convert;
if(state == POOL_STATUS_ACCEPTING_ENTRIES) {
if(state == POOL_STATUS_IDLE) {
convert << tr("Darksend is idle.").toStdString();
} else if(state == POOL_STATUS_ACCEPTING_ENTRIES) {
if(entries == 0) {
if(darkSendPool.strAutoDenomResult.size() == 0){
convert << tr("Darksend is idle.").toStdString();
convert << tr("Mixing in progress...").toStdString();
} else {
convert << darkSendPool.strAutoDenomResult;
}

View File

@ -47,7 +47,7 @@ SendCoinsDialog::SendCoinsDialog(QWidget *parent) :
connect(ui->checkBoxCoinControlChange, SIGNAL(stateChanged(int)), this, SLOT(coinControlChangeChecked(int)));
connect(ui->lineEditCoinControlChange, SIGNAL(textEdited(const QString &)), this, SLOT(coinControlChangeEdited(const QString &)));
connect(ui->checkUseDarksend, SIGNAL(stateChanged ( int )), this, SLOT(updateDisplayUnit()));
connect(ui->checkInstantX, SIGNAL(stateChanged ( int )), this, SLOT(updateDisplayUnit()));
connect(ui->checkInstantX, SIGNAL(stateChanged ( int )), this, SLOT(updateInstantX()));
// Coin Control: clipboard actions
QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this);
@ -473,6 +473,14 @@ void SendCoinsDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint
void SendCoinsDialog::updateDisplayUnit()
{
setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance(), model->getAnonymizedBalance());
CoinControlDialog::coinControl->useDarkSend = ui->checkUseDarksend->isChecked();
coinControlUpdateLabels();
}
void SendCoinsDialog::updateInstantX()
{
CoinControlDialog::coinControl->useInstantX = ui->checkInstantX->isChecked();
coinControlUpdateLabels();
}
void SendCoinsDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg)

View File

@ -64,6 +64,7 @@ private slots:
void on_sendButton_clicked();
void removeEntry(SendCoinsEntry* entry);
void updateDisplayUnit();
void updateInstantX();
void coinControlFeatureChanged(bool);
void coinControlButtonClicked();
void coinControlChangeChecked(int);

View File

@ -579,17 +579,17 @@ Value masternodelist(const Array& params, bool fHelp)
"masternodelist ( \"mode\" \"filter\" )\n"
"Get a list of masternodes in different modes\n"
"\nArguments:\n"
"1. \"mode\" (string, optional, defauls = active) The mode to run list in\n"
"2. \"filter\" (string, optional) Filter results, can be applied in few modes only\n"
"1. \"mode\" (string, optional/required to use filter, defaults = active) The mode to run list in\n"
"2. \"filter\" (string, optional) Filter results. Partial match by IP by default in all modes, additional matches in some modes\n"
"\nAvailable modes:\n"
" active - Print '1' if active and '0' otherwise (can be filtered, exact match)\n"
" active - Print '1' if active and '0' otherwise (can be additionally filtered by 'true' (active only) / 'false' (non-active only))\n"
" activeseconds - Print number of seconds masternode recognized by the network as enabled\n"
" full - Print info in format 'active | protocol | pubkey | vin | lastseen | activeseconds' (can be filtered, partial match)\n"
" full - Print info in format 'active protocol pubkey vin lastseen activeseconds' (can be additionally filtered, partial match)\n"
" lastseen - Print timestamp of when a masternode was last seen on the network\n"
" protocol - Print protocol of a masternode (can be filtered, exact match)\n"
" pubkey - Print public key associated with a masternode (can be filtered, partial match)\n"
" protocol - Print protocol of a masternode (can be additionally filtered, exact match))\n"
" pubkey - Print public key associated with a masternode (can be additionally filtered, partial match)\n"
" rank - Print rank of a masternode based on current block\n"
" vin - Print vin associated with a masternode (can be filtered, partial match)\n"
" vin - Print vin associated with a masternode (can be additionally filtered, partial match)\n"
);
}
@ -599,13 +599,41 @@ Value masternodelist(const Array& params, bool fHelp)
std::string strAddr = mn.addr.ToString().c_str();
if(strMode == "active"){
if(strFilter !="" && strFilter != boost::lexical_cast<std::string>(mn.IsEnabled()) &&
if(strFilter !="" && strFilter != (mn.IsEnabled() ? "true" : "false") &&
mn.addr.ToString().find(strFilter) == string::npos) continue;
obj.push_back(Pair(strAddr, (int)mn.IsEnabled()));
} else if (strMode == "vin") {
if(strFilter !="" && mn.vin.prevout.hash.ToString().find(strFilter) == string::npos &&
} else if (strMode == "activeseconds") {
if(strFilter !="" && mn.addr.ToString().find(strFilter) == string::npos) continue;
obj.push_back(Pair(strAddr, (int64_t)(mn.lastTimeSeen - mn.sigTime)));
} else if (strMode == "full") {
CScript pubkey;
pubkey.SetDestination(mn.pubkey.GetID());
CTxDestination address1;
ExtractDestination(pubkey, address1);
CBitcoinAddress address2(address1);
std::ostringstream addrStream;
addrStream << setw(21) << strAddr;
std::ostringstream stringStream;
stringStream << (mn.IsEnabled() ? "1" : "0") << " " <<
mn.protocolVersion << " " <<
address2.ToString() << " " <<
mn.vin.prevout.hash.ToString() << " " <<
mn.lastTimeSeen << " " << setw(8) <<
(mn.lastTimeSeen - mn.sigTime);
std::string output = stringStream.str();
stringStream << " " << strAddr;
if(strFilter !="" && stringStream.str().find(strFilter) == string::npos &&
mn.addr.ToString().find(strFilter) == string::npos) continue;
obj.push_back(Pair(strAddr, mn.vin.prevout.hash.ToString().c_str()));
obj.push_back(Pair(addrStream.str(), output));
} else if (strMode == "lastseen") {
if(strFilter !="" && mn.addr.ToString().find(strFilter) == string::npos) continue;
obj.push_back(Pair(strAddr, (int64_t)mn.lastTimeSeen));
} else if (strMode == "protocol") {
if(strFilter !="" && strFilter != boost::lexical_cast<std::string>(mn.protocolVersion) &&
mn.addr.ToString().find(strFilter) == string::npos) continue;
obj.push_back(Pair(strAddr, (int64_t)mn.protocolVersion));
} else if (strMode == "pubkey") {
CScript pubkey;
pubkey.SetDestination(mn.pubkey.GetID());
@ -616,39 +644,13 @@ Value masternodelist(const Array& params, bool fHelp)
if(strFilter !="" && address2.ToString().find(strFilter) == string::npos &&
mn.addr.ToString().find(strFilter) == string::npos) continue;
obj.push_back(Pair(strAddr, address2.ToString().c_str()));
} else if (strMode == "protocol") {
if(strFilter !="" && strFilter != boost::lexical_cast<std::string>(mn.protocolVersion) &&
mn.addr.ToString().find(strFilter) == string::npos) continue;
obj.push_back(Pair(strAddr, (int64_t)mn.protocolVersion));
} else if (strMode == "lastseen") {
if(strFilter !="" && mn.addr.ToString().find(strFilter) == string::npos) continue;
obj.push_back(Pair(strAddr, (int64_t)mn.lastTimeSeen));
} else if (strMode == "activeseconds") {
if(strFilter !="" && mn.addr.ToString().find(strFilter) == string::npos) continue;
obj.push_back(Pair(strAddr, (int64_t)(mn.lastTimeSeen - mn.sigTime)));
} else if (strMode == "rank") {
if(strFilter !="" && mn.addr.ToString().find(strFilter) == string::npos) continue;
obj.push_back(Pair(strAddr, (int)(mnodeman.GetMasternodeRank(mn.vin, chainActive.Tip()->nHeight))));
} else if (strMode == "full") {
CScript pubkey;
pubkey.SetDestination(mn.pubkey.GetID());
CTxDestination address1;
ExtractDestination(pubkey, address1);
CBitcoinAddress address2(address1);
std::ostringstream stringStream;
stringStream << (mn.IsEnabled() ? "1" : "0") << " | " <<
mn.protocolVersion << " | " <<
address2.ToString() << " | " <<
mn.vin.prevout.hash.ToString() << " | " <<
mn.lastTimeSeen << " | " <<
(mn.lastTimeSeen - mn.sigTime);
std::string output = stringStream.str();
stringStream << " " << strAddr;
if(strFilter !="" && stringStream.str().find(strFilter) == string::npos) continue;
obj.push_back(Pair(strAddr, output));
} else if (strMode == "vin") {
if(strFilter !="" && mn.vin.prevout.hash.ToString().find(strFilter) == string::npos &&
mn.addr.ToString().find(strFilter) == string::npos) continue;
obj.push_back(Pair(strAddr, mn.vin.prevout.hash.ToString().c_str()));
}
}
return obj;

View File

@ -1787,7 +1787,7 @@ bool CWallet::CreateCollateralTransaction(CTransaction& txCollateral, std::strin
BOOST_FOREACH(CTxIn v, vCoinsCollateral)
UnlockCoin(v.prevout);
strReason = "CDarkSendPool::Sign - Unable to sign collateral transaction! \n";
strReason = "CDarksendPool::Sign - Unable to sign collateral transaction! \n";
return false;
}
vinNumber++;
@ -1838,7 +1838,7 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend,
LOCK2(cs_main, cs_wallet);
{
nFeeRet = nTransactionFee;
if(useIX && nFeeRet < CENT) nFeeRet = CENT;
if(useIX) nFeeRet = max(CENT, nFeeRet);
while (true)
{
wtxNew.vin.clear();
@ -1912,13 +1912,9 @@ bool CWallet::CreateTransaction(const vector<pair<CScript, int64_t> >& vecSend,
//over pay for denominated transactions
if(coin_type == ONLY_DENOMINATED) {
nFeeRet = nChange;
nFeeRet += nChange;
nChange = 0;
wtxNew.mapValue["DS"] = "1";
} else if(useIX && nFeeRet < CENT && nChange > (CENT-nFeeRet)) {
// IX has a minimum fee of 0.01 DRK
nChange -= CENT-nFeeRet;
nFeeRet = CENT;
}
if (nChange > 0)
@ -2173,7 +2169,6 @@ string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
int64_t nTotalValue = GetTotalValue(vCoins);
LogPrintf("PrepareDarksendDenominate - preparing darksend denominate . Got: %d \n", nTotalValue);
//--------------
BOOST_FOREACH(CTxIn v, vCoins)
LockCoin(v.prevout);
@ -2216,6 +2211,7 @@ string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
std::random_shuffle (vDenoms.begin() + (int)darkSendDenominations.size() + 1, vDenoms.end());
// Make outputs by looping through denominations randomly
BOOST_REVERSE_FOREACH(int64_t v, vDenoms){
//only use the ones that are approved
bool fAccepted = false;
@ -2270,7 +2266,6 @@ string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
if(nValueLeft == 0) break;
}
}
if(darkSendPool.GetDenominations(vOut) != darkSendPool.sessionDenom)
@ -2280,7 +2275,6 @@ string CWallet::PrepareDarksendDenominate(int minRounds, int maxRounds)
if(nValueLeft != 0)
return "Error: change left-over in pool. Must use denominations only";
//randomize the output order
std::random_shuffle (vOut.begin(), vOut.end());

View File

@ -290,6 +290,7 @@ public:
std::string SendMoney(CScript scriptPubKey, int64_t nValue, CWalletTx& wtxNew, AvailableCoinsType coin_type=ALL_COINS);
std::string SendMoneyToDestination(const CTxDestination &address, int64_t nValue, CWalletTx& wtxNew, AvailableCoinsType coin_type=ALL_COINS);
std::string PrepareDarksendDenominate(int minRounds, int maxRounds);
int GenerateDarksendOutputs(int nTotalValue, std::vector<CTxOut>& vout);
bool CreateCollateralTransaction(CTransaction& txCollateral, std::string strReason);
bool ConvertList(std::vector<CTxIn> vCoins, std::vector<int64_t>& vecAmounts);