Skip to content

Commit

Permalink
Merge pull request #4 from barrystyle/0.14-posheaderissues
Browse files Browse the repository at this point in the history
Move checking of PoS blocks to AcceptBlock, migrate net_processing.cp…
  • Loading branch information
barrystyle authored Aug 2, 2019
2 parents f18a751 + 64b71d3 commit 0551217
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 55 deletions.
6 changes: 4 additions & 2 deletions src/init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2129,11 +2129,13 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler)
pwalletMain->postInitProcess(scheduler);
#endif

threadGroup.create_thread(boost::bind(&ThreadSendAlert, boost::ref(connman)));

#ifdef ENABLE_WALLET
if(GetBoolArg("-staking", true)) {
threadGroup.create_thread(std::bind(&ThreadStakeMinter, boost::ref(chainparams), boost::ref(connman)));
}

threadGroup.create_thread(boost::bind(&ThreadSendAlert, boost::ref(connman)));
#endif

return !fRequestShutdown;
}
16 changes: 4 additions & 12 deletions src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ bool ComputeNextStakeModifier(const CBlockIndex* pindexCurrent, uint64_t &nStake
return true;
}

static bool GetKernelStakeModifierV03(uint256 hashBlockFrom, unsigned int nTimeTx, uint64_t& nStakeModifier, int& nStakeModifierHeight, int64_t& nStakeModifierTime, bool fPrintProofOfStake)
static bool GetKernelStakeModifier(uint256 hashBlockFrom, unsigned int nTimeTx, uint64_t& nStakeModifier, int& nStakeModifierHeight, int64_t& nStakeModifierTime, bool fPrintProofOfStake)
{
nStakeModifier = 0;
if (!mapBlockIndex.count(hashBlockFrom))
Expand Down Expand Up @@ -264,12 +264,6 @@ static bool GetKernelStakeModifierV03(uint256 hashBlockFrom, unsigned int nTimeT
return true;
}

// Get the stake modifier specified by the protocol to hash for a stake kernel
static bool GetKernelStakeModifier(uint256 hashBlockFrom, unsigned int nTimeTx, uint64_t& nStakeModifier, int& nStakeModifierHeight, int64_t& nStakeModifierTime, bool fPrintProofOfStake)
{
return GetKernelStakeModifierV03(hashBlockFrom, nTimeTx, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, fPrintProofOfStake);
}

uint256 stakeHash(unsigned int nTimeTx, CDataStream ss, unsigned int prevoutIndex, uint256 prevoutHash, unsigned int nTimeBlockFrom)
{
ss << nTimeBlockFrom << prevoutIndex << prevoutHash << nTimeTx;
Expand All @@ -292,10 +286,6 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned
bnTargetPerCoinDay.SetCompact(nBits);
CAmount nValueIn = txPrev->vout[prevout.n].nValue;

// stake input must be of a minimum value
if (nValueIn < COIN)
return error("CheckStakeKernelHash() : nValueIn is less than COIN (nValueIn=%llu)", nValueIn);

// v0.3 protocol kernel hash weight starts from 0 at the 30-day min age
// this change increases active coins participating the hash and helps
// to secure the network when proof-of-stake difficulty is low
Expand All @@ -310,6 +300,7 @@ bool CheckStakeKernelHash(unsigned int nBits, const CBlock& blockFrom, unsigned

if (!GetKernelStakeModifier(blockFrom.GetHash(), nTimeTx, nStakeModifier, nStakeModifierHeight, nStakeModifierTime, false))
return false;

ss << nStakeModifier;
ss << nTimeBlockFrom << nTxPrevOffset << txPrevTime << prevout.n << nTimeTx;
hashProofOfStake = Hash(ss.begin(), ss.end());
Expand Down Expand Up @@ -363,8 +354,9 @@ bool CheckProofOfStake(const CBlock &block, uint256& hashProofOfStake)

const auto &cons = Params().GetConsensus();

if (!GetTransaction(txin.prevout.hash, txPrev, cons, hashBlock, true))
if (!GetTransaction(txin.prevout.hash, txPrev, cons, hashBlock, true)) {
return error("CheckProofOfStake() : INFO: read txPrev failed");
}

CTxOut prevTxOut = txPrev->vout[txin.prevout.n];
CBlockIndex* pindex = NULL;
Expand Down
18 changes: 13 additions & 5 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1368,10 +1368,14 @@ void CConnman::ThreadSocketHandler()
}
}

//
// Service each socket
//
std::vector<CNode*> vNodesCopy = CopyNodeVector();
std::vector<CNode*> vNodesCopy;
{
LOCK(cs_vNodes);
vNodesCopy = vNodes;
for (CNode* pnode : vNodesCopy)
pnode->AddRef();
}

BOOST_FOREACH(CNode* pnode, vNodesCopy)
{
if (interruptNet)
Expand Down Expand Up @@ -1494,7 +1498,11 @@ void CConnman::ThreadSocketHandler()
}
}
}
ReleaseNodeVector(vNodesCopy);
{
LOCK(cs_vNodes);
for (CNode* pnode : vNodesCopy)
pnode->Release();
}
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ static const int WARNING_INTERVAL = 10 * 60;
static const int FEELER_INTERVAL = 120;
/** The maximum number of entries in an 'inv' protocol message */
static const unsigned int MAX_INV_SZ = 50000;
/** The maximum number of entries in a locator */
static const unsigned int MAX_LOCATOR_SZ = 101;
/** The maximum number of new addresses to accumulate before announcing. */
static const unsigned int MAX_ADDR_TO_SEND = 1000;
/** Maximum length of incoming protocol messages (no message over 3 MiB is currently acceptable). */
Expand Down
60 changes: 50 additions & 10 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,9 @@ struct CNodeState {
*/
bool fSupportsDesiredCmpctVersion;

//! Time of last new block announcement
int64_t m_last_block_announcement;

CNodeState(CAddress addrIn, std::string addrNameIn) : address(addrIn), name(addrNameIn) {
fCurrentlyConnected = false;
nMisbehavior = 0;
Expand All @@ -251,6 +254,7 @@ struct CNodeState {
fPreferHeaderAndIDs = false;
fProvidesHeaderAndIDs = false;
fSupportsDesiredCmpctVersion = false;
m_last_block_announcement = 0;
}
};

Expand Down Expand Up @@ -452,6 +456,7 @@ void MaybeSetPeerAsAnnouncingHeaderAndIDs(NodeId nodeid, CConnman& connman) {
}
}
connman.ForNode(nodeid, [&connman](CNode* pfrom){
AssertLockHeld(cs_main);
bool fAnnounceUsingCMPCTBLOCK = false;
uint64_t nCMPCTBLOCKVersion = 1;
if (lNodesAnnouncingHeaderAndIDs.size() >= 3) {
Expand Down Expand Up @@ -975,7 +980,6 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 0)) || // Best effort: only try output 0 and 1
pcoinsTip->HaveCoinInCache(COutPoint(inv.hash, 1));
}

case MSG_BLOCK:
return mapBlockIndex.count(inv.hash);

Expand Down Expand Up @@ -1022,7 +1026,6 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
case MSG_ISLOCK:
return llmq::quorumInstantSendManager->AlreadyHave(inv);
}

// Don't know what it is, just say we already got one
return true;
}
Expand Down Expand Up @@ -1929,6 +1932,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
uint256 hashStop;
vRecv >> locator >> hashStop;

if (locator.vHave.size() > MAX_LOCATOR_SZ) {
LogPrint("net", "getblocks locator size %lld > %d, disconnect peer=%d\n", locator.vHave.size(), MAX_LOCATOR_SZ, pfrom->GetId());
pfrom->fDisconnect = true;
return true;
}

// We might have announced the currently-being-connected tip using a
// compact block, which resulted in the peer sending a getblocks
// request, which we would otherwise respond to without the new block.
Expand Down Expand Up @@ -2040,6 +2049,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
uint256 hashStop;
vRecv >> locator >> hashStop;

if (locator.vHave.size() > MAX_LOCATOR_SZ) {
LogPrint("net", "getheaders locator size %lld > %d, disconnect peer=%d\n", locator.vHave.size(), MAX_LOCATOR_SZ, pfrom->GetId());
pfrom->fDisconnect = true;
return true;
}

LOCK(cs_main);
if (IsInitialBlockDownload() && !pfrom->fWhitelisted) {
LogPrint("net", "Ignoring getheaders from peer=%d because node is in initial block download\n", pfrom->id);
Expand Down Expand Up @@ -2362,6 +2377,8 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
CBlockHeaderAndShortTxIDs cmpctblock;
vRecv >> cmpctblock;

bool received_new_header = false;

{
LOCK(cs_main);

Expand All @@ -2371,6 +2388,10 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
connman.PushMessage(pfrom, msgMaker.Make(NetMsgType::GETHEADERS, chainActive.GetLocator(pindexBestHeader), uint256()));
return true;
}

if (!LookupBlockIndex(cmpctblock.header.GetHash())) {
received_new_header = true;
}
}

const CBlockIndex *pindex = NULL;
Expand All @@ -2380,7 +2401,9 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
if (state.IsInvalid(nDoS)) {
if (nDoS > 0) {
LOCK(cs_main);
Misbehaving(pfrom->GetId(), nDoS);
Misbehaving(pfrom->GetId(), nDoS /*, strprintf("Peer %d sent us invalid header via cmpctblock\n", pfrom->GetId())*/);
} else {
LogPrint("net", "Peer %d sent us invalid header via cmpctblock\n", pfrom->GetId());
}
LogPrintf("Peer %d sent us invalid header via cmpctblock\n", pfrom->id);
return true;
Expand Down Expand Up @@ -2410,6 +2433,14 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
assert(pindex);
UpdateBlockAvailability(pfrom->GetId(), pindex->GetBlockHash());

CNodeState *nodestate = State(pfrom->GetId());

// If this was a new header with more work than our tip, update the
// peer's last block announcement time
if (received_new_header && pindex->nChainWork > chainActive.Tip()->nChainWork) {
nodestate->m_last_block_announcement = GetTime();
}

std::map<uint256, std::pair<NodeId, std::list<QueuedBlock>::iterator> >::iterator blockInFlightIt = mapBlocksInFlight.find(pindex->GetBlockHash());
bool fAlreadyInFlight = blockInFlightIt != mapBlocksInFlight.end();

Expand All @@ -2432,8 +2463,6 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
if (!fAlreadyInFlight && !CanDirectFetch(chainparams.GetConsensus()))
return true;

CNodeState *nodestate = State(pfrom->GetId());

// We want to be a bit conservative just to be extra careful about DoS
// possibilities in compact block processing...
if (pindex->nHeight <= chainActive.Height() + 2) {
Expand Down Expand Up @@ -2532,9 +2561,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
}
bool fNewBlock = false;
ProcessNewBlock(chainparams, pblock, true, &fNewBlock);
if (fNewBlock)
if (fNewBlock) {
pfrom->nLastBlockTime = GetTime();

} else {
LOCK(cs_main);
mapBlockSource.erase(pblock->GetHash());
}
LOCK(cs_main); // hold cs_main for CBlockIndex::IsValid()
if (pindex->IsValid(BLOCK_VALID_TRANSACTIONS)) {
// Clear download state for this block, which is in
Expand Down Expand Up @@ -2609,8 +2641,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
// Since we requested this block (it was in mapBlocksInFlight), force it to be processed,
// even if it would not be a candidate for new tip (missing previous block, chain not long enough, etc)
ProcessNewBlock(chainparams, pblock, true, &fNewBlock);
if (fNewBlock)
if (fNewBlock) {
pfrom->nLastBlockTime = GetTime();
} else {
LOCK(cs_main);
mapBlockSource.erase(pblock->GetHash());
}
}
}

Expand Down Expand Up @@ -2759,7 +2795,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
}
}
}
}
}
}

else if (strCommand == NetMsgType::BLOCK && !fImporting && !fReindex) // Ignore blocks received while importing
Expand All @@ -2786,8 +2822,12 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr
}
bool fNewBlock = false;
ProcessNewBlock(chainparams, pblock, forceProcessing, &fNewBlock);
if (fNewBlock)
if (fNewBlock){
pfrom->nLastBlockTime = GetTime();
} else {
LOCK(cs_main);
mapBlockSource.erase(pblock->GetHash());
}
}


Expand Down
Loading

0 comments on commit 0551217

Please sign in to comment.