Skip to content
This repository was archived by the owner on Oct 28, 2021. It is now read-only.

Commit f7f9b9e

Browse files
committed
Perform send new blocks check on p2p thread
We perform this check on the network thread because it turns out that std::atomic only supports types with noexcept ctors (i.e. no h256) and using a mutex to synchronize access to the latest block sent info seems like overkill.
1 parent 80ad6d1 commit f7f9b9e

File tree

3 files changed

+25
-24
lines changed

3 files changed

+25
-24
lines changed

libethereum/Client.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ static_assert(BOOST_VERSION >= 106400, "Wrong boost headers version");
4343

4444
namespace
4545
{
46-
unsigned constexpr c_syncMin = 1;
47-
unsigned constexpr c_syncMax = 1000;
48-
double constexpr c_targetDuration = 1;
46+
constexpr unsigned c_syncMin = 1;
47+
constexpr unsigned c_syncMax = 1000;
48+
constexpr double c_targetDuration = 1;
4949

5050
std::string filtersToString(h256Hash const& _fs)
5151
{

libethereum/EthereumCapability.cpp

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -395,9 +395,9 @@ std::vector<NodeID> randomPeers(std::vector<NodeID> const& _peers, size_t _count
395395
std::vector<NodeID> randomPeers;
396396
while (_count-- && !peers.empty())
397397
{
398-
auto const randomPeerIter = peers.begin() + randomNumber(0, peers.size() - 1);
399-
randomPeers.push_back(*randomPeerIter);
400-
peers.erase(randomPeerIter);
398+
auto const cIter = peers.begin() + randomNumber(0, peers.size() - 1);
399+
randomPeers.push_back(*cIter);
400+
peers.erase(cIter);
401401
}
402402

403403
return randomPeers;
@@ -413,14 +413,14 @@ EthereumCapability::EthereumCapability(shared_ptr<p2p::CapabilityHostFace> _host
413413
m_tq(_tq),
414414
m_bq(_bq),
415415
m_networkId(_networkId),
416-
m_hostData(new EthereumHostData(m_chain, m_db)),
417-
m_latestBlockHashSent{_ch.currentHash()},
418-
m_latestBlockSent{_ch.currentHash()}
416+
m_hostData(new EthereumHostData(m_chain, m_db))
419417
{
420418
// TODO: Composition would be better. Left like that to avoid initialization
421419
// issues as BlockChainSync accesses other EthereumHost members.
422420
m_sync.reset(new BlockChainSync(*this));
423421
m_peerObserver.reset(new EthereumPeerObserver(m_sync, m_tq));
422+
m_latestBlockHashSent = _ch.currentHash();
423+
m_latestBlockSent = _ch.currentHash();
424424
m_tq.onImport([this](ImportResult _ir, h256 const& _h, h512 const& _nodeId) { onTransactionImported(_ir, _h, _nodeId); });
425425
std::random_device seed;
426426
m_urng = std::mt19937_64(seed());
@@ -435,7 +435,7 @@ bool EthereumCapability::ensureInitialised()
435435
{
436436
if (!m_latestBlockHashSent)
437437
{
438-
assert(!m_latestBlockSent.load());
438+
assert(!m_latestBlockSent);
439439
// First time - just initialise.
440440
m_latestBlockHashSent = m_chain.currentHash();
441441
m_latestBlockSent = m_chain.currentHash();
@@ -455,7 +455,7 @@ void EthereumCapability::reset()
455455
// but we access m_latestBlockHashSent and m_transactionsSent only from the network thread
456456
m_host->postWork([this]() {
457457
m_latestBlockHashSent = {};
458-
m_latestBlockSent.exchange({});
458+
m_latestBlockSent = {};
459459
m_transactionsSent.clear();
460460
});
461461
}
@@ -543,8 +543,8 @@ std::pair<std::vector<NodeID>, std::vector<NodeID>> EthereumCapability::randomPa
543543
void EthereumCapability::maintainBlockHashes(h256 const& _currentHash)
544544
{
545545
// Send any new block hashes
546-
auto detailsFrom = m_chain.details(m_latestBlockHashSent);
547-
auto detailsTo = m_chain.details(_currentHash);
546+
auto const detailsFrom = m_chain.details(m_latestBlockHashSent);
547+
auto const detailsTo = m_chain.details(_currentHash);
548548
if (detailsFrom.totalDifficulty < detailsTo.totalDifficulty)
549549
{
550550
if (diff(detailsFrom.number, detailsTo.number) <= c_maxSendNewBlocksCount)
@@ -684,7 +684,7 @@ bool EthereumCapability::interpretCapabilityPacket(
684684
const auto skip = _r[2].toInt<u256>();
685685
const auto reverse = _r[3].toInt<bool>();
686686

687-
auto numHeadersToSend = maxHeaders <= c_maxSendHeadersCount ?
687+
auto const numHeadersToSend = maxHeaders <= c_maxSendHeadersCount ?
688688
static_cast<unsigned>(maxHeaders) :
689689
c_maxSendHeadersCount;
690690

@@ -957,23 +957,24 @@ void EthereumCapability::removeSentTransactions(std::vector<h256> const& _txHash
957957
}
958958
}
959959

960-
void EthereumCapability::propagateNewBlocks(std::shared_ptr<VerifiedBlocks const> const& _newBlocks)
960+
void EthereumCapability::propagateNewBlocks(shared_ptr<VerifiedBlocks const> const& _newBlocks)
961961
{
962962
// Safe to call isSyncing() from a non-network thread since the underlying variable is
963963
// std::atomic
964964
if (_newBlocks->empty() || isSyncing())
965965
return;
966966

967-
// Check if we're too far behind
968-
auto const currentHash = _newBlocks->back().verified.info.hash();
969-
auto const detailsFrom = m_chain.details(m_latestBlockSent);
970-
auto const detailsTo = m_chain.details(currentHash);
971-
if (diff(detailsFrom.number, detailsTo.number) > c_maxSendNewBlocksCount)
972-
return;
967+
m_host->postWork([this, _newBlocks]() {
968+
// Verify that we're not too far behind - we perform this check on the network thread rather
969+
// than before posting the work to simplify the synchronization story
970+
auto const latestHash = _newBlocks->back().verified.info.hash();
971+
auto const detailsFrom = m_chain.details(m_latestBlockSent);
972+
auto const detailsTo = m_chain.details(latestHash);
973+
if (diff(detailsFrom.number, detailsTo.number) > c_maxSendNewBlocksCount)
974+
return;
973975

974-
m_host->postWork([this, _newBlocks, currentHash]() {
975976
auto const peersWithoutBlock = selectPeers(
976-
[&](EthereumPeer const& _peer) { return !_peer.isBlockKnown(currentHash); });
977+
[&](EthereumPeer const& _peer) { return !_peer.isBlockKnown(latestHash); });
977978

978979
auto const peersToSendNumber =
979980
std::max<std::size_t>(c_minBlockBroadcastPeers, std::sqrt(m_peers.size()));

libethereum/EthereumCapability.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ class EthereumCapability : public p2p::CapabilityFace
189189
// the block queue and verified) but we propagate new block hashes after blocks have been
190190
// imported into the chain
191191
h256 m_latestBlockHashSent;
192-
std::atomic<h256> m_latestBlockSent = {h256{0}};
192+
h256 m_latestBlockSent;
193193
h256Hash m_transactionsSent;
194194

195195
std::atomic<bool> m_newTransactions = {false};

0 commit comments

Comments
 (0)