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

Commit 5f3d000

Browse files
authored
Merge pull request #5713 from ethereum/propagate-blocks-pow
Propagate blocks after PoW validation
2 parents 7e6095d + 8739dd0 commit 5f3d000

File tree

7 files changed

+226
-170
lines changed

7 files changed

+226
-170
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
- Changed: [#5675](https://github.com/ethereum/aleth/pull/5675) Disconnect from peer when syncing is disabled for peer.
3535
- Changed: [#5676](https://github.com/ethereum/aleth/pull/5676) When receiving large batches of new block hashes, process up to 1024 hashes instead of disabling the peer.
3636
- Changed: [#5719](https://github.com/ethereum/aleth/pull/5719) Enable support for Visual Studio 2017 on Windows.
37+
- Changed: [#5713](https://github.com/ethereum/aleth/pull/5713) Propagate new blocks after PoW check rather than after import into the blockchain.
3738
- Removed: [#5631](https://github.com/ethereum/aleth/pull/5631) Removed PARANOID build option.
3839
- Fixed: [#5562](https://github.com/ethereum/aleth/pull/5562) Don't send header request messages to peers that haven't sent us Status yet.
3940
- Fixed: [#5581](https://github.com/ethereum/aleth/pull/5581) Fixed finding neighbour nodes in Discovery.

libethcore/Common.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ struct ImportRoute
9090
{
9191
h256s deadBlocks;
9292
h256s liveBlocks;
93-
std::vector<Transaction> goodTranactions;
93+
std::vector<Transaction> goodTransactions;
9494
};
9595

9696
enum class ImportResult

libethereum/BlockChain.cpp

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,6 @@
1-
/*
2-
This file is part of cpp-ethereum.
3-
4-
cpp-ethereum is free software: you can redistribute it and/or modify
5-
it under the terms of the GNU General Public License as published by
6-
the Free Software Foundation, either version 3 of the License, or
7-
(at your option) any later version.
8-
9-
cpp-ethereum is distributed in the hope that it will be useful,
10-
but WITHOUT ANY WARRANTY; without even the implied warranty of
11-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12-
GNU General Public License for more details.
13-
14-
You should have received a copy of the GNU General Public License
15-
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16-
*/
17-
/** @file BlockChain.cpp
18-
* @author Gav Wood <i@gavwood.com>
19-
* @date 2014
20-
*/
1+
// Aleth: Ethereum C++ client, tools and libraries.
2+
// Copyright 2019 Aleth Authors.
3+
// Licensed under the GNU General Public License, Version 3.
214

225
#include "BlockChain.h"
236

@@ -436,19 +419,28 @@ string BlockChain::dumpDatabase() const
436419
return oss.str();
437420
}
438421

439-
tuple<ImportRoute, bool, unsigned> BlockChain::sync(BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max)
422+
tuple<ImportRoute, bool, unsigned> BlockChain::sync(
423+
BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max)
440424
{
441-
// _bq.tick(*this);
425+
// _bq.tick(*this);
442426

443427
VerifiedBlocks blocks;
444428
_bq.drain(blocks, _max);
445429

430+
std::tuple<ImportRoute, h256s, unsigned> const importResult = sync(blocks, _stateDB);
431+
bool const moreBlocks = _bq.doneDrain(std::get<1>(importResult));
432+
return {std::get<0>(importResult), moreBlocks, std::get<2>(importResult)};
433+
}
434+
435+
tuple<ImportRoute, h256s, unsigned> BlockChain::sync(
436+
VerifiedBlocks const& _blocks, OverlayDB const& _stateDB)
437+
{
446438
h256s fresh;
447439
h256s dead;
448-
h256s badBlocks;
449440
Transactions goodTransactions;
450441
unsigned count = 0;
451-
for (VerifiedBlock const& block: blocks)
442+
h256s badBlockHashes;
443+
for (VerifiedBlock const& block : _blocks)
452444
{
453445
do {
454446
try
@@ -459,8 +451,8 @@ tuple<ImportRoute, bool, unsigned> BlockChain::sync(BlockQueue& _bq, OverlayDB c
459451
r = import(block.verified, _stateDB, (ImportRequirements::Everything & ~ImportRequirements::ValidSeal & ~ImportRequirements::CheckUncles) != 0);
460452
fresh += r.liveBlocks;
461453
dead += r.deadBlocks;
462-
goodTransactions.reserve(goodTransactions.size() + r.goodTranactions.size());
463-
std::move(std::begin(r.goodTranactions), std::end(r.goodTranactions), std::back_inserter(goodTransactions));
454+
goodTransactions.reserve(goodTransactions.size() + r.goodTransactions.size());
455+
std::move(std::begin(r.goodTransactions), std::end(r.goodTransactions), std::back_inserter(goodTransactions));
464456
++count;
465457
}
466458
catch (dev::eth::AlreadyHaveBlock const&)
@@ -473,7 +465,7 @@ tuple<ImportRoute, bool, unsigned> BlockChain::sync(BlockQueue& _bq, OverlayDB c
473465
cwarn << "ODD: Import queue contains block with unknown parent.";// << LogTag::Error << boost::current_exception_diagnostic_information();
474466
// NOTE: don't reimport since the queue should guarantee everything in the right order.
475467
// Can't continue - chain bad.
476-
badBlocks.push_back(block.verified.info.hash());
468+
badBlockHashes.push_back(block.verified.info.hash());
477469
}
478470
catch (dev::eth::FutureTime const&)
479471
{
@@ -488,16 +480,16 @@ tuple<ImportRoute, bool, unsigned> BlockChain::sync(BlockQueue& _bq, OverlayDB c
488480
}
489481
catch (Exception& ex)
490482
{
491-
// cnote << "Exception while importing block. Someone (Jeff? That you?) seems to be giving us dodgy blocks!";// << LogTag::Error << diagnostic_information(ex);
483+
// cnote << "Exception while importing block. Someone (Jeff? That you?) seems to be giving us dodgy blocks!";// << LogTag::Error << diagnostic_information(ex);
492484
if (m_onBad)
493485
m_onBad(ex);
494486
// NOTE: don't reimport since the queue should guarantee everything in the right order.
495487
// Can't continue - chain bad.
496-
badBlocks.push_back(block.verified.info.hash());
488+
badBlockHashes.push_back(block.verified.info.hash());
497489
}
498490
} while (false);
499491
}
500-
return make_tuple(ImportRoute{dead, fresh, goodTransactions}, _bq.doneDrain(badBlocks), count);
492+
return {ImportRoute{dead, fresh, goodTransactions}, badBlockHashes, count};
501493
}
502494

503495
pair<ImportResult, ImportRoute> BlockChain::attemptImport(bytes const& _block, OverlayDB const& _stateDB, bool _mustBeNew) noexcept

libethereum/BlockChain.h

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,6 @@
1-
/*
2-
This file is part of cpp-ethereum.
3-
4-
cpp-ethereum is free software: you can redistribute it and/or modify
5-
it under the terms of the GNU General Public License as published by
6-
the Free Software Foundation, either version 3 of the License, or
7-
(at your option) any later version.
8-
9-
cpp-ethereum is distributed in the hope that it will be useful,
10-
but WITHOUT ANY WARRANTY; without even the implied warranty of
11-
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12-
GNU General Public License for more details.
13-
14-
You should have received a copy of the GNU General Public License
15-
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
16-
*/
17-
/** @file BlockChain.h
18-
* @author Gav Wood <i@gavwood.com>
19-
* @date 2014
20-
*/
1+
// Aleth: Ethereum C++ client, tools and libraries.
2+
// Copyright 2019 Aleth Authors.
3+
// Licensed under the GNU General Public License, Version 3.
214

225
#pragma once
236

@@ -118,8 +101,18 @@ class BlockChain
118101
void process();
119102

120103
/// Sync the chain with any incoming blocks. All blocks should, if processed in order.
121-
/// @returns fresh blocks, dead blocks and true iff there are additional blocks to be processed waiting.
122-
std::tuple<ImportRoute, bool, unsigned> sync(BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max);
104+
/// @returns tuple with three members - the first (ImportRoute) contains hashes of fresh blocks
105+
/// and dead blocks as well as a list of imported transactions. The second is a bool which is
106+
/// true iff there are additional blocks to be processed. The third is the imported block count.
107+
std::tuple<ImportRoute, bool, unsigned> sync(
108+
BlockQueue& _bq, OverlayDB const& _stateDB, unsigned _max);
109+
110+
/// Import the supplied blocks into the chain. Blocks should be processed in order.
111+
/// @returns a tuple with three members - the first (ImportRoute) contains fresh blocks, dead
112+
/// blocks and imported transactions. The second contains hashes of bad blocks. The third
113+
/// contains the imported block count.
114+
std::tuple<ImportRoute, h256s, unsigned> sync(
115+
VerifiedBlocks const& _blocks, OverlayDB const& _stateDB);
123116

124117
/// Attempt to import the given block directly into the BlockChain and sync with the state DB.
125118
/// @returns the block hashes of any blocks that came into/went out of the canonical block chain.

libethereum/Client.cpp

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

4444
namespace
4545
{
46+
constexpr unsigned c_syncMinBlockCount = 1;
47+
constexpr unsigned c_syncMaxBlockCount = 1000;
48+
constexpr double c_targetDurationS = 1;
49+
4650
std::string filtersToString(h256Hash const& _fs)
4751
{
4852
std::stringstream str;
@@ -377,18 +381,29 @@ void Client::appendFromBlock(h256 const& _block, BlockPolarity _polarity, h256Ha
377381
}
378382
}
379383

380-
unsigned static const c_syncMin = 1;
381-
unsigned static const c_syncMax = 1000;
382-
double static const c_targetDuration = 1;
383-
384384
void Client::syncBlockQueue()
385385
{
386386
// cdebug << "syncBlockQueue()";
387387

388388
ImportRoute ir;
389+
h256s badBlockHashes;
389390
unsigned count;
390391
Timer t;
391-
tie(ir, m_syncBlockQueue, count) = bc().sync(m_bq, m_stateDB, m_syncAmount);
392+
393+
// The verified blocks list needs to be a shared_ptr since we propagate them on the network
394+
// thread and import them into our local chain on the client thread.
395+
std::shared_ptr<VerifiedBlocks> verifiedBlocks = std::make_shared<VerifiedBlocks>();
396+
m_bq.drain(*verifiedBlocks, m_syncAmount);
397+
398+
// Propagate new blocks to peers before importing them into the chain.
399+
auto h = m_host.lock();
400+
assert(h); // capability is owned by Host and should be available for the duration of the
401+
// Client's lifetime
402+
h->propagateNewBlocks(verifiedBlocks);
403+
404+
std::tie(ir, badBlockHashes, count) = bc().sync(*verifiedBlocks, m_stateDB);
405+
m_syncBlockQueue = m_bq.doneDrain(badBlockHashes);
406+
392407
double elapsed = t.elapsed();
393408

394409
if (count)
@@ -397,10 +412,10 @@ void Client::syncBlockQueue()
397412
<< (count / elapsed) << " blocks/s) in #" << bc().number();
398413
}
399414

400-
if (elapsed > c_targetDuration * 1.1 && count > c_syncMin)
401-
m_syncAmount = max(c_syncMin, count * 9 / 10);
402-
else if (count == m_syncAmount && elapsed < c_targetDuration * 0.9 && m_syncAmount < c_syncMax)
403-
m_syncAmount = min(c_syncMax, m_syncAmount * 11 / 10 + 1);
415+
if (elapsed > c_targetDurationS * 1.1 && count > c_syncMinBlockCount)
416+
m_syncAmount = max(c_syncMinBlockCount, count * 9 / 10);
417+
else if (count == m_syncAmount && elapsed < c_targetDurationS * 0.9 && m_syncAmount < c_syncMaxBlockCount)
418+
m_syncAmount = min(c_syncMaxBlockCount, m_syncAmount * 11 / 10 + 1);
404419
if (ir.liveBlocks.empty())
405420
return;
406421
onChainChanged(ir);
@@ -557,8 +572,8 @@ void Client::onChainChanged(ImportRoute const& _ir)
557572
h256Hash changeds;
558573
onDeadBlocks(_ir.deadBlocks, changeds);
559574
vector<h256> goodTransactions;
560-
goodTransactions.reserve(_ir.goodTranactions.size());
561-
for (auto const& t: _ir.goodTranactions)
575+
goodTransactions.reserve(_ir.goodTransactions.size());
576+
for (auto const& t: _ir.goodTransactions)
562577
{
563578
LOG(m_loggerDetail) << "Safely dropping transaction " << t.sha3();
564579
m_tq.dropGood(t);

0 commit comments

Comments
 (0)