Full Spork Implementation
Many sporks are supported at once, with efficient broadcasting via inventory messages.
This commit is contained in:
parent
5dc643f9b0
commit
257078d2a4
@ -76,6 +76,7 @@ BITCOIN_CORE_H = \
|
||||
sph_simd.h \
|
||||
sph_skein.h \
|
||||
sph_types.h \
|
||||
spork.h \
|
||||
sync.h \
|
||||
threadsafety.h \
|
||||
tinyformat.h \
|
||||
@ -169,6 +170,7 @@ libdarkcoin_common_a_SOURCES = \
|
||||
shavite.c \
|
||||
keccak.c \
|
||||
skein.c \
|
||||
spork.cpp \
|
||||
bmw.c \
|
||||
simd.c \
|
||||
cubehash.c \
|
||||
|
@ -2113,6 +2113,7 @@ bool CDarksendQueue::CheckSignature()
|
||||
}
|
||||
|
||||
|
||||
//TODO: Rename/move to core
|
||||
void ThreadCheckDarkSendPool()
|
||||
{
|
||||
if(fLiteMode) return; //disable all darksend/masternode related functionality
|
||||
@ -2178,6 +2179,7 @@ void ThreadCheckDarkSendPool()
|
||||
|
||||
pnode->PushMessage("dseg", CTxIn()); //request full mn list
|
||||
pnode->PushMessage("mnget"); //sync payees
|
||||
pnode->PushMessage("getsporks"); //get current network sporks
|
||||
RequestedMasterNodeList++;
|
||||
}
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
#include "activemasternode.h"
|
||||
#include "spork.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "db.h"
|
||||
#include "wallet.h"
|
||||
@ -699,6 +700,8 @@ bool AppInit2(boost::thread_group& threadGroup)
|
||||
{
|
||||
if (!masternodePayments.SetPrivKey(GetArg("-masternodepaymentskey", "")))
|
||||
return InitError(_("Unable to sign masternode payment winner, wrong key?"));
|
||||
if (!sporkManager.SetPrivKey(GetArg("-masternodepaymentskey", "")))
|
||||
return InitError(_("Unable to sign spork message, wrong key?"));
|
||||
}
|
||||
|
||||
//ignore masternodes below protocol version
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "masternode.h"
|
||||
#include "activemasternode.h"
|
||||
#include "darksend.h"
|
||||
#include "spork.h"
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
using namespace std;
|
||||
@ -35,6 +36,7 @@ int nCompleteTXLocks;
|
||||
void ProcessMessageInstantX(CNode* pfrom, std::string& strCommand, CDataStream& vRecv)
|
||||
{
|
||||
if(fLiteMode) return; //disable all darksend/masternode related functionality
|
||||
if(!IsSporkActive(SPORK_2_INSTANTX)) return;
|
||||
|
||||
if (strCommand == "txlreq")
|
||||
{
|
||||
|
51
src/main.cpp
51
src/main.cpp
@ -20,6 +20,7 @@
|
||||
#include "txmempool.h"
|
||||
#include "ui_interface.h"
|
||||
#include "util.h"
|
||||
#include "spork.h"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@ -69,7 +70,6 @@ struct COrphanBlock {
|
||||
};
|
||||
map<uint256, COrphanBlock*> mapOrphanBlocks;
|
||||
multimap<uint256, COrphanBlock*> mapOrphanBlocksByPrev;
|
||||
bool fManyOrphansFound;
|
||||
|
||||
struct COrphanTx {
|
||||
CTransaction tx;
|
||||
@ -1177,6 +1177,7 @@ int CMerkleTx::GetDepthInMainChainINTERNAL(CBlockIndex* &pindexRet) const
|
||||
int CMerkleTx::GetTransactionLockSignatures() const
|
||||
{
|
||||
if(fLargeWorkForkFound || fLargeWorkInvalidChainFound) return -2;
|
||||
if(!IsSporkActive(SPORK_2_INSTANTX)) return -3;
|
||||
if(nInstantXDepth == 0) return -1;
|
||||
|
||||
//compile consessus vote
|
||||
@ -2827,23 +2828,27 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
|
||||
|
||||
// ----------- instantX transaction scanning -----------
|
||||
|
||||
if(!fLargeWorkForkFound && !fLargeWorkInvalidChainFound){
|
||||
BOOST_FOREACH(const CTransaction& tx, block.vtx){
|
||||
if (!tx.IsCoinBase()){
|
||||
//only reject blocks when it's based on complete consensus
|
||||
BOOST_FOREACH(const CTxIn& in, tx.vin){
|
||||
if(mapLockedInputs.count(in.prevout)){
|
||||
if(mapLockedInputs[in.prevout] != tx.GetHash()){
|
||||
LogPrintf("CheckBlock() : found conflicting transaction with transaction lock %s %s\n", mapLockedInputs[in.prevout].ToString().c_str(), tx.GetHash().ToString().c_str());
|
||||
return state.DoS(0, error("CheckBlock() : found conflicting transaction with transaction lock"),
|
||||
REJECT_INVALID, "conflicting-tx-ix");
|
||||
if(IsSporkActive(SPORK_3_INSTANTX_BLOCK_FILTERING)){
|
||||
if(!fLargeWorkForkFound && !fLargeWorkInvalidChainFound){
|
||||
BOOST_FOREACH(const CTransaction& tx, block.vtx){
|
||||
if (!tx.IsCoinBase()){
|
||||
//only reject blocks when it's based on complete consensus
|
||||
BOOST_FOREACH(const CTxIn& in, tx.vin){
|
||||
if(mapLockedInputs.count(in.prevout)){
|
||||
if(mapLockedInputs[in.prevout] != tx.GetHash()){
|
||||
LogPrintf("CheckBlock() : found conflicting transaction with transaction lock %s %s\n", mapLockedInputs[in.prevout].ToString().c_str(), tx.GetHash().ToString().c_str());
|
||||
return state.DoS(0, error("CheckBlock() : found conflicting transaction with transaction lock"),
|
||||
REJECT_INVALID, "conflicting-tx-ix");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
LogPrintf("CheckBlock() : fork detected, skipping transaction locking checks\n");
|
||||
}
|
||||
} else {
|
||||
LogPrintf("CheckBlock() : fork detected, skipping transaction locking checks\n");
|
||||
if(fDebug) LogPrintf("CheckBlock() : InstantX block filtering is off\n");
|
||||
}
|
||||
|
||||
|
||||
@ -2857,6 +2862,10 @@ bool CheckBlock(const CBlock& block, CValidationState& state, bool fCheckPOW, bo
|
||||
if(block.nTime > START_MASTERNODE_PAYMENTS) MasternodePayments = true;
|
||||
}
|
||||
|
||||
if(!IsSporkActive(SPORK_1_MASTERNODE_PAYMENTS_ENFORCEMENT)){
|
||||
MasternodePayments = false;
|
||||
if(fDebug) LogPrintf("CheckBlock() : Masternode payment enforcement is off\n");
|
||||
}
|
||||
|
||||
if(MasternodePayments && !fLargeWorkForkFound && !fLargeWorkInvalidChainFound)
|
||||
{
|
||||
@ -3175,8 +3184,8 @@ bool ProcessBlock(CValidationState &state, CNode* pfrom, CBlock* pblock, CDiskBl
|
||||
// Ask this guy to fill in what we're missing
|
||||
PushGetBlocks(pfrom, chainActive.Tip(), GetOrphanRoot(hash));
|
||||
|
||||
if(fLargeWorkForkFound || fLargeWorkInvalidChainFound){
|
||||
// Move backwards to tigger reprocessing both chains
|
||||
// Move backwards to tigger reprocessing both chains
|
||||
if(fLargeWorkForkFound || fLargeWorkInvalidChainFound || IsSporkActive(SPORK_4_RECONVERGE)){
|
||||
CValidationState state;
|
||||
DisconnectTip(state);
|
||||
}
|
||||
@ -3875,6 +3884,8 @@ bool static AlreadyHave(const CInv& inv)
|
||||
mapTxLockReqRejected.count(inv.hash);
|
||||
case MSG_TXLOCK_VOTE:
|
||||
return mapTxLockVote.count(inv.hash);
|
||||
case MSG_SPORK:
|
||||
return mapSporks.count(inv.hash);
|
||||
}
|
||||
// Don't know what it is, just say we already got one
|
||||
return true;
|
||||
@ -4017,6 +4028,16 @@ void static ProcessGetData(CNode* pfrom)
|
||||
pushed = true;
|
||||
}
|
||||
}
|
||||
if (!pushed && inv.type == MSG_SPORK) {
|
||||
if(mapSporks.count(inv.hash)){
|
||||
printf("have %s\n", inv.hash.ToString().c_str() );
|
||||
CDataStream ss(SER_NETWORK, PROTOCOL_VERSION);
|
||||
ss.reserve(1000);
|
||||
ss << mapSporks[inv.hash];
|
||||
pfrom->PushMessage("spork", ss);
|
||||
pushed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pushed) {
|
||||
vNotFound.push_back(inv);
|
||||
@ -4770,13 +4791,13 @@ bool static ProcessMessage(CNode* pfrom, string strCommand, CDataStream& vRecv)
|
||||
LogPrint("net", "Reject %s\n", SanitizeString(ss.str()));
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
//probably one the extensions
|
||||
ProcessMessageDarksend(pfrom, strCommand, vRecv);
|
||||
ProcessMessageMasternode(pfrom, strCommand, vRecv);
|
||||
ProcessMessageInstantX(pfrom, strCommand, vRecv);
|
||||
ProcessSpork(pfrom, strCommand, vRecv);
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,7 +18,8 @@ static const char* ppszTypeName[] =
|
||||
"block",
|
||||
"filtered block",
|
||||
"tx lock request",
|
||||
"tx lock vote"
|
||||
"tx lock vote",
|
||||
"spork"
|
||||
};
|
||||
|
||||
CMessageHeader::CMessageHeader()
|
||||
|
@ -137,6 +137,7 @@ enum
|
||||
MSG_FILTERED_BLOCK,
|
||||
MSG_TXLOCK_REQUEST,
|
||||
MSG_TXLOCK_VOTE,
|
||||
MSG_SPORK
|
||||
};
|
||||
|
||||
#endif // __INCLUDED_PROTOCOL_H__
|
||||
|
@ -178,6 +178,7 @@ Array RPCConvertValues(const std::string &strMethod, const std::vector<std::stri
|
||||
if (strMethod == "verifychain" && n > 1) ConvertTo<int64_t>(params[1]);
|
||||
if (strMethod == "keypoolrefill" && n > 0) ConvertTo<int64_t>(params[0]);
|
||||
if (strMethod == "getrawmempool" && n > 0) ConvertTo<bool>(params[0]);
|
||||
if (strMethod == "spork" && n > 1) ConvertTo<int64_t>(params[1]);
|
||||
|
||||
return params;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "netbase.h"
|
||||
#include "rpcserver.h"
|
||||
#include "util.h"
|
||||
#include "spork.h"
|
||||
#ifdef ENABLE_WALLET
|
||||
#include "wallet.h"
|
||||
#include "walletdb.h"
|
||||
@ -129,6 +130,45 @@ public:
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
Used for updating/reading spork settings on the network
|
||||
*/
|
||||
Value spork(const Array& params, bool fHelp)
|
||||
{
|
||||
if(params.size() == 1 && params[0].get_str() == "show"){
|
||||
std::map<int, CSporkMessage>::iterator it = mapSporksActive.begin();
|
||||
|
||||
Object ret;
|
||||
while(it != mapSporksActive.end()) {
|
||||
ret.push_back(Pair(sporkManager.GetSporkNameByID(it->second.nSporkID), it->second.nTimeStart));
|
||||
it++;
|
||||
}
|
||||
return ret;
|
||||
} else if (params.size() == 2){
|
||||
int nSporkID = sporkManager.GetSporkIDByName(params[0].get_str());
|
||||
if(nSporkID == -1){
|
||||
return "Invalid spork name";
|
||||
}
|
||||
|
||||
// EPOCH VALUE
|
||||
int64_t nEpochStart = params[1].get_int();
|
||||
|
||||
//broadcast new spork
|
||||
if(sporkManager.UpdateSpork(nSporkID, nEpochStart)){
|
||||
return "success";
|
||||
} else {
|
||||
return "failure";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
throw runtime_error(
|
||||
"spork <name> [<value>]\n"
|
||||
"<name> is the corresponding spork name, or 'show' to show all current spork settings"
|
||||
"<value> is a epoch datetime to enable or disable spork"
|
||||
+ HelpRequiringPassphrase());
|
||||
}
|
||||
|
||||
Value validateaddress(const Array& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
|
@ -271,6 +271,7 @@ static const CRPCCommand vRPCCommands[] =
|
||||
|
||||
/* Darkcoin features */
|
||||
{ "darksend", &darksend, false, false, true },
|
||||
{ "spork", &spork, true, false, false },
|
||||
{ "masternode", &masternode, true, false, true },
|
||||
|
||||
#ifdef ENABLE_WALLET
|
||||
|
@ -191,6 +191,7 @@ extern json_spirit::Value verifychain(const json_spirit::Array& params, bool fHe
|
||||
|
||||
|
||||
extern json_spirit::Value darksend(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value spork(const json_spirit::Array& params, bool fHelp);
|
||||
extern json_spirit::Value masternode(const json_spirit::Array& params, bool fHelp);
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user