Added dstx support for free transactions

This commit is contained in:
Evan Duffield 2015-02-02 04:42:41 -07:00
parent 7e38235e5a
commit 13246598b8

View File

@ -26,6 +26,7 @@
#include <boost/algorithm/string/replace.hpp>
#include <boost/filesystem.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/lexical_cast.hpp>
using namespace std;
using namespace boost;
@ -4002,13 +4003,27 @@ void static ProcessGetData(CNode* pfrom)
}
}
if (!pushed && inv.type == MSG_TX) {
CTransaction tx;
if (mempool.lookup(inv.hash, tx)) {
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 {
CTransaction tx;
if (mempool.lookup(inv.hash, tx)) {
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
ss.reserve(1000);
ss << tx;
pfrom->PushMessage("tx", ss);
pushed = true;
}
}
}
if (!pushed) {
@ -4381,12 +4396,58 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
}
else if (strCommand == "tx")
else if (strCommand == "tx"|| strCommand == "dstx")
{
vector<uint256> vWorkQueue;
vector<uint256> vEraseQueue;
CTransaction tx;
vRecv >> tx;
//masternode signed transaction
bool allowFree = false;
CTxIn vin;
vector<unsigned char> vchSig;
int64_t sigTime;
if(strCommand == "tx") {
vRecv >> tx;
} else if (strCommand == "dstx") {
//these allow masternodes to publish a limited amount of free transactions
vRecv >> tx >> vin >> vchSig >> sigTime;
BOOST_FOREACH(CMasterNode& mn, vecMasternodes) {
if(mn.vin == vin) {
if(!mn.allowFreeTx){
//multiple peers can send us a valid masternode transaction
if(fDebug) LogPrintf("dstx: Masternode sending too many transactions %s\n", tx.GetHash().ToString().c_str());
return true;
}
std::string strMessage = tx.GetHash().ToString() + boost::lexical_cast<std::string>(sigTime);
std::string errorMessage = "";
if(!darkSendSigner.VerifyMessage(mn.pubkey2, vchSig, strMessage, errorMessage)){
LogPrintf("dstx: Got bad masternode address signature %s \n", vin.ToString().c_str());
//pfrom->Misbehaving(20);
return false;
}
LogPrintf("dstx: Got Masternode transaction %s\n", tx.GetHash().ToString().c_str());
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));
}
}
}
}
CInv inv(MSG_TX, tx.GetHash());
pfrom->AddInventoryKnown(inv);
@ -4395,7 +4456,7 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
bool fMissingInputs = false;
CValidationState state;
if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs))
if (AcceptToMemoryPool(mempool, state, tx, true, &fMissingInputs, allowFree))
{
mempool.check(pcoinsTip);
RelayTransaction(tx, inv.hash);