dstx using headers first inv messages

This commit is contained in:
Evan Duffield 2014-12-01 09:41:30 -07:00
parent f3696ba602
commit bbfcf6c359
8 changed files with 80 additions and 36 deletions

View File

@ -9,7 +9,7 @@
#define CLIENT_VERSION_MAJOR 0
#define CLIENT_VERSION_MINOR 10
#define CLIENT_VERSION_REVISION 17
#define CLIENT_VERSION_BUILD 4
#define CLIENT_VERSION_BUILD 5
// Set to true for release, false for prerelease or test build
#define CLIENT_VERSION_IS_RELEASE true

View File

@ -28,6 +28,9 @@ std::vector<int64> darkSendDenominations;
std::vector<CDarksendQueue> vecDarksendQueue;
/** Keep track of the used masternodes */
std::vector<CTxIn> vecMasternodesUsed;
// keep track of the scanning errors I've seen
map<uint256, CDarksendBroadcastTx> mapDarksendBroadcastTxes;
// count peers we've requested the list from
int RequestedMasterNodeList = 0;
@ -162,7 +165,7 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream&
//don't allow a few nodes to dominate the queuing process
if(darkSendMasterNodes[mn].nLastDsq != 0 &&
darkSendMasterNodes[mn].nLastDsq + (int)darkSendMasterNodes.size()/5 > darkSendPool.nDsqCount){
LogPrintf("dsq -- masternode sending too many dsq messages. %s \n", darkSendMasterNodes[mn].addr.ToString().c_str());
if(fDebug) LogPrintf("dsq -- masternode sending too many dsq messages. %s \n", darkSendMasterNodes[mn].addr.ToString().c_str());
return;
}
darkSendPool.nDsqCount++;
@ -234,7 +237,7 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream&
BOOST_FOREACH(const CTxIn i, in){
tx.vin.push_back(i);
LogPrintf("dsi -- tx in %s\n", i.ToString().c_str());
if(fDebug) LogPrintf("dsi -- tx in %s\n", i.ToString().c_str());
CTransaction tx2;
uint256 hash;
@ -270,7 +273,7 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream&
bool missing = false;
if (!tx.IsAcceptable(state, true, false, &missing, false)){ //AcceptableInputs(state, true)){
LogPrintf("dsi -- transactione not valid! \n");
LogPrintf("dsi -- transaction not valid! \n");
error = "transaction not valid";
pfrom->PushMessage("dssu", darkSendPool.sessionID, darkSendPool.GetState(), darkSendPool.GetEntriesCount(), MASTERNODE_REJECTED, error);
return;
@ -317,7 +320,7 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream&
std::string error;
vRecv >> sessionID >> state >> entriesCount >> accepted >> error;
LogPrintf("dssu - state: %i entriesCount: %i accepted: %i error: %s \n", state, entriesCount, accepted, error.c_str());
if(fDebug) LogPrintf("dssu - state: %i entriesCount: %i accepted: %i error: %s \n", state, entriesCount, accepted, error.c_str());
if((accepted != 1 && accepted != 0) && darkSendPool.sessionID != sessionID){
LogPrintf("dssu - message doesn't match current darksend session %d %d\n", darkSendPool.sessionID, sessionID);
@ -344,7 +347,7 @@ void ProcessMessageDarksend(CNode* pfrom, std::string& strCommand, CDataStream&
BOOST_FOREACH(const CTxIn item, sigs)
{
if(darkSendPool.AddScriptSig(item)) success = true;
LogPrintf(" -- sigs count %d %d\n", (int)sigs.size(), count);
if(fDebug) LogPrintf(" -- sigs count %d %d\n", (int)sigs.size(), count);
count++;
}
@ -565,11 +568,21 @@ void CDarkSendPool::Check()
return;
}
if(!mapDarksendBroadcastTxes.count(txNew.GetHash())){
CDarksendBroadcastTx dstx;
dstx.tx = txNew;
dstx.vin = activeMasternode.vinMasternode;
dstx.vchSig = vchSig;
dstx.sigTime = sigTime;
mapDarksendBroadcastTxes.insert(make_pair(txNew.GetHash(), dstx));
}
// Broadcast the transaction to the network
txNew.AddSupportingTransactions();
txNew.fTimeReceivedIsTxTime = true;
RelayDarkSendTransaction((CTransaction)txNew, activeMasternode.vinMasternode, vchSig, sigTime);
txNew.fTimeReceivedIsTxTime = true;
txNew.RelayWalletTransaction();
// Tell the clients it was successful
RelayDarkSendCompletedTransaction(sessionID, false, "Transaction Created Successfully");
@ -581,7 +594,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) ) {
LogPrintf("CDarkSendPool::Check() -- COMPLETED -- RESETTING \n");
if(fDebug) LogPrintf("CDarkSendPool::Check() -- COMPLETED -- RESETTING \n");
SetNull(true);
UnlockCoins();
if(fMasterNode) RelayDarkSendStatus(darkSendPool.sessionID, darkSendPool.GetState(), darkSendPool.GetEntriesCount(), MASTERNODE_RESET);
@ -590,7 +603,7 @@ void CDarkSendPool::Check()
// reset if we're here for 10 seconds
if((state == POOL_STATUS_ERROR || state == POOL_STATUS_SUCCESS) && GetTimeMillis()-lastTimeChanged >= 10000) {
LogPrintf("CDarkSendPool::Check() -- RESETTING MESSAGE \n");
if(fDebug) LogPrintf("CDarkSendPool::Check() -- RESETTING MESSAGE \n");
SetNull(true);
if(fMasterNode) RelayDarkSendStatus(darkSendPool.sessionID, darkSendPool.GetState(), darkSendPool.GetEntriesCount(), MASTERNODE_RESET);
UnlockCoins();
@ -911,7 +924,7 @@ bool CDarkSendPool::IsCollateralValid(const CTransaction& txCollateral){
return false;
}
LogPrintf("CDarkSendPool::IsCollateralValid %s\n", txCollateral.ToString().c_str());
if(fDebug) LogPrintf("CDarkSendPool::IsCollateralValid %s\n", txCollateral.ToString().c_str());
CWalletTx wtxCollateral = CWalletTx(pwalletMain, txCollateral);
if (!wtxCollateral.IsAcceptable(true, false)){
@ -953,7 +966,7 @@ bool CDarkSendPool::AddEntry(const std::vector<CTxIn>& newInput, const int64& nA
}
BOOST_FOREACH(CTxIn in, newInput) {
LogPrintf("looking for vin -- %s\n", in.ToString().c_str());
if(fDebug) LogPrintf("looking for vin -- %s\n", in.ToString().c_str());
BOOST_FOREACH(const CDarkSendEntry v, entries) {
BOOST_FOREACH(const CDarkSendEntryVin s, v.sev){
if(s.vin == in) {
@ -971,7 +984,7 @@ bool CDarkSendPool::AddEntry(const std::vector<CTxIn>& newInput, const int64& nA
v.Add(newInput, nAmount, txCollateral, newOutput);
entries.push_back(v);
LogPrintf("CDarkSendPool::AddEntry -- adding %s\n", newInput[0].ToString().c_str());
if(fDebug) LogPrintf("CDarkSendPool::AddEntry -- adding %s\n", newInput[0].ToString().c_str());
error = "";
return true;
@ -1090,13 +1103,13 @@ void CDarkSendPool::SendDarksendDenominate(std::vector<CTxIn>& vin, std::vector<
BOOST_FOREACH(const CTxIn i, vin){
tx.vin.push_back(i);
LogPrintf("dsi -- tx in %s\n", i.ToString().c_str());
if(fDebug) LogPrintf("dsi -- tx in %s\n", i.ToString().c_str());
}
bool missing = false;
if (!tx.IsAcceptable(state, true, false, &missing, false)){ //AcceptableInputs(state, true)){
LogPrintf("dsi -- transactione not valid! %s \n", tx.ToString().c_str());
LogPrintf("dsi -- transaction not valid! %s \n", tx.ToString().c_str());
return;
}
}

View File

@ -16,6 +16,7 @@ class CDarkSendSigner;
class CMasterNodeVote;
class CBitcoinAddress;
class CDarksendQueue;
class CDarksendBroadcastTx;
#define POOL_MAX_TRANSACTIONS 3 // wait for X transactions to merge and publish
#define POOL_STATUS_UNKNOWN 0 // waiting for update
@ -40,7 +41,9 @@ extern CDarkSendPool darkSendPool;
extern CDarkSendSigner darkSendSigner;
extern std::vector<int64> darkSendDenominations;
extern std::vector<CDarksendQueue> vecDarksendQueue;
extern std::vector<CDarksendQueue> vecDarksendQueue;
extern std::string strMasterNodePrivKey;
extern map<uint256, CDarksendBroadcastTx> mapDarksendBroadcastTxes;
static const int64 DARKSEND_COLLATERAL = (0.1*COIN);
static const int64 DARKSEND_FEE = (0.0125*COIN);
@ -190,6 +193,16 @@ public:
};
// store darksend tx signature information
class CDarksendBroadcastTx
{
public:
CTransaction tx;
CTxIn vin;
vector<unsigned char> vchSig;
int64 sigTime;
};
//
// Helper object for signing and checking signatures
//
@ -213,7 +226,7 @@ class CDarksendSession
class CDarkSendPool
{
public:
static const int MIN_PEER_PROTO_VERSION = 70047;
static const int MIN_PEER_PROTO_VERSION = 70048;
// clients entries
std::vector<CDarkSendEntry> myEntries;

View File

@ -386,6 +386,7 @@ std::string HelpMessage()
" -masternode=<n> " + _("Enable the client to act as a masternode (0-1, default: 0)") + "\n" +
" -masternodeprivkey=<n> " + _("Set the masternode private key") + "\n" +
" -masternodeaddr=<n> " + _("Set external address:port to get to this masternode (example: address:port)") + "\n" +
" -masternodeminprotocol=<n> " + _("Ignore masternodes less than version (example: 70050; default : 0)") + "\n" +
"\n" + _("Darksend options:") + "\n" +
" -disabledarksend=<n> " + _("Disable use of automated darksend for funds stored in this wallet (0-1, default: 1)") + "\n" +

View File

@ -3926,6 +3926,8 @@ void static ProcessGetData(CNode* pfrom)
{
// Send stream from relay memory
bool pushed = false;
if(!mapDarksendBroadcastTxes.count(inv.hash))
{
LOCK(cs_mapRelay);
map<CInv, CDataStream>::iterator mi = mapRelay.find(inv);
@ -3934,15 +3936,30 @@ void static ProcessGetData(CNode* pfrom)
pushed = true;
}
}
if (!pushed && inv.type == MSG_TX) {
LOCK(mempool.cs);
if (mempool.exists(inv.hash)) {
CTransaction tx = mempool.lookup(inv.hash);
//check if it's a darksend mixing session
if(mapDarksendBroadcastTxes.count(inv.hash)){
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000);
ss << tx;
pfrom->PushMessage("tx", ss);
ss <<
mapDarksendBroadcastTxes[inv.hash].tx <<
mapDarksendBroadcastTxes[inv.hash].vin <<
mapDarksendBroadcastTxes[inv.hash].vchSig <<
mapDarksendBroadcastTxes[inv.hash].sigTime;
pfrom->PushMessage("dstx", ss);
pushed = true;
} else { //normal tx
LOCK(mempool.cs);
if (mempool.exists(inv.hash)) {
CTransaction tx = mempool.lookup(inv.hash);
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000);
ss << tx;
pfrom->PushMessage("tx", ss);
pushed = true;
}
}
}
if (!pushed) {
@ -4377,6 +4394,16 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
allowFree = true;
mn.allowFreeTx = false;
if(!mapDarksendBroadcastTxes.count(tx.GetHash())){
CDarksendBroadcastTx dstx;
dstx.tx = tx;
dstx.vin = vin;
dstx.vchSig = vchSig;
dstx.sigTime = sigTime;
mapDarksendBroadcastTxes.insert(make_pair(tx.GetHash(), dstx));
}
}
}
}
@ -4388,15 +4415,14 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
CValidationState state;
if (tx.AcceptToMemoryPool(state, true, true, &fMissingInputs, allowFree))
{
if(strCommand == "tx") RelayTransaction(tx, inv.hash);
else if(strCommand == "dstx") RelayDarkSendTransaction(tx, vin, vchSig, sigTime);
RelayTransaction(tx, inv.hash);
mapAlreadyAskedFor.erase(inv);
vWorkQueue.push_back(inv.hash);
vEraseQueue.push_back(inv.hash);
LogPrintf("AcceptToMemoryPool: %s %s : accepted %s (poolsz %"PRIszu")\n",
pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str(),
LogPrintf("AcceptToMemoryPool (%s): %s %s : accepted %s (poolsz %"PRIszu")\n",
strCommand.c_str(), pfrom->addr.ToString().c_str(), pfrom->cleanSubVer.c_str(),
tx.GetHash().ToString().c_str(),
mempool.mapTx.size());

View File

@ -1990,12 +1990,4 @@ void RelayDarkSendCompletedTransaction(const int sessionID, const bool error, co
{
pnode->PushMessage("dsc", sessionID, error, errorMessage);
}
}
void RelayDarkSendTransaction(const CTransaction txNew, const CTxIn vin, const std::vector<unsigned char> vchSig, const int64 sigTime){
LOCK(cs_vNodes);
BOOST_FOREACH(CNode* pnode, vNodes) {
if(!pnode->fRelayTxes) continue;
pnode->PushMessage("dstx", txNew, vin, vchSig, sigTime);
}
}

View File

@ -694,6 +694,5 @@ void RelayDarkSendElectionEntry(const CTxIn vin, const CService addr, const std:
void RelayDarkSendElectionEntryPing(const CTxIn vin, const std::vector<unsigned char> vchSig, const int64 nNow, const bool stop);
void RelayDarkSendCompletedTransaction(const int sessionID, const bool error, const std::string errorMessage);
void RelayDarkSendMasterNodeContestant();
void RelayDarkSendTransaction(const CTransaction txNew, const CTxIn vin, const std::vector<unsigned char> vchSig, const int64 sigTime);
#endif

View File

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