Skip to content

Commit 62d1b23

Browse files
authoredFeb 13, 2023
Fix catch-up finalization over sync (#1486)
* refactor: verbosity on some log msgs * exp: hold reason of recent request in sync * clean: remove old build artifact * refactor: improve some logs * refactor: continue load justification by condition Signed-off-by: Dmitriy Khaustov aka xDimon <[email protected]>
1 parent 59f2db0 commit 62d1b23

30 files changed

+585
-390
lines changed
 

‎.clang-format

+6-1
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
BasedOnStyle: Google
22
NamespaceIndentation: All
33
BreakBeforeBinaryOperators: NonAssignment
4-
AlignOperands: true
4+
AlignOperands: AlignAfterOperator
55
DerivePointerAlignment: false
66
PointerAlignment: Right
77
BinPackArguments: false
88
BinPackParameters: false
99
AllowShortFunctionsOnASingleLine: Empty
1010
IncludeBlocks: Preserve
1111
InsertBraces: true
12+
InsertTrailingCommas: Wrapped
13+
SortIncludes: CaseSensitive
14+
# uncomment in clang-format-16
15+
#RemoveSemicolon: true
16+
#InsertNewlineAtEOF: true

‎.githooks/pre-commit

100755100644
+8-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
#!/bin/sh
22

3-
RESULT=0
4-
53
if git rev-parse --verify HEAD >/dev/null 2>&1; then
64
BASE=HEAD
75
else
@@ -34,15 +32,13 @@ fi
3432
# check c++ files' format with clang-format
3533
CXX_RES=0
3634
if [ $CLANG_FORMAT_ENABLED ]; then
37-
for FILE in $(git diff-index --name-only ${BASE} | grep -e "\\.[ch]pp$"); do
38-
TMPFILE=$(mktemp /tmp/kagome_precommit_hook.XXXXXX)
39-
clang-format "$FILE" >"$TMPFILE"
40-
diff -q "$FILE" "$TMPFILE" >/dev/null
41-
if [ $? = 1 ]; then
35+
for FILE in $(git diff-index --name-only "${BASE}" --diff-filter=ACMR | grep -e "\\.[ch]pp$"); do
36+
O_HASH=$(shasum <"${FILE}")
37+
F_HASH=$(${CLANG_FORMAT} --style=file "$FILE" | shasum)
38+
if [ "${O_HASH}" != "${F_HASH}" ]; then
4239
echo "File looks nonformatted: $FILE"
4340
CXX_RES=1
4441
fi
45-
rm "$TMPFILE"
4642
done
4743

4844
if [ $CXX_RES = 1 ]; then
@@ -63,15 +59,13 @@ fi
6359
# check cmake-files' format with cmake-format
6460
CMAKE_RES=0
6561
if [ $CMAKE_FORMAT_ENABLED ]; then
66-
for FILE in $(git diff-index --name-only "${BASE}" | grep -e "\(\(CMakeLists\\.txt\)\|\(\\.cmake\)\)$"); do
67-
TMPFILE=$(mktemp /tmp/kagome_precommit_hook.XXXXXX)
68-
cmake-format "$FILE" >"$TMPFILE"
69-
diff -q "$FILE" "$TMPFILE" >/dev/null
70-
if [ $? = 1 ]; then
62+
for FILE in $(git diff-index --name-only "${BASE}" --diff-filter=ACMR | grep -e "\(\(CMakeLists\\.txt\)\|\(\\.cmake\)\)$"); do
63+
O_HASH=$(shasum <"${FILE}")
64+
F_HASH=$(${CMAKE_FORMAT} --style=file "$FILE" | shasum)
65+
if [ "${O_HASH}" != "${F_HASH}" ]; then
7166
echo "File looks nonformatted: $FILE"
7267
CMAKE_RES=1
7368
fi
74-
rm "$TMPFILE"
7569
done
7670

7771
if [ $CMAKE_RES = 1 ]; then

‎core/blockchain/impl/storage_util.cpp

+7-4
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ namespace kagome::blockchain {
4141
auto block_lookup_key = numberAndHashToLookupKey(num, block_hash);
4242
auto key_space = storage.getSpace(Space::kLookupKey);
4343
OUTCOME_TRY(key_space->put(block_hash, block_lookup_key.view()));
44-
OUTCOME_TRY(key_space->put(numberToIndexKey(num), block_lookup_key.view()));
4544

4645
auto target_space = storage.getSpace(space);
4746
return target_space->put(block_lookup_key, std::move(value));
@@ -51,7 +50,9 @@ namespace kagome::blockchain {
5150
storage::Space space,
5251
const primitives::BlockId &block_id) {
5352
OUTCOME_TRY(key, idToLookupKey(storage, block_id));
54-
if (!key.has_value()) return false;
53+
if (!key.has_value()) {
54+
return false;
55+
}
5556
auto target_space = storage.getSpace(space);
5657
return target_space->contains(key.value());
5758
}
@@ -61,7 +62,9 @@ namespace kagome::blockchain {
6162
storage::Space space,
6263
const primitives::BlockId &block_id) {
6364
OUTCOME_TRY(key, idToLookupKey(storage, block_id));
64-
if (!key.has_value()) return std::nullopt;
65+
if (!key.has_value()) {
66+
return std::nullopt;
67+
}
6568
auto target_space = storage.getSpace(space);
6669
return target_space->tryGet(key.value());
6770
}
@@ -89,7 +92,7 @@ namespace kagome::blockchain {
8992
return outcome::failure(KeyValueRepositoryError::INVALID_KEY);
9093
}
9194
return (uint64_t(key[0]) << 24u) | (uint64_t(key[1]) << 16u)
92-
| (uint64_t(key[2]) << 8u) | uint64_t(key[3]);
95+
| (uint64_t(key[2]) << 8u) | uint64_t(key[3]);
9396
}
9497

9598
} // namespace kagome::blockchain

‎core/consensus/authority/impl/authority_manager_impl.cpp

Whitespace-only changes.

‎core/consensus/babe/impl/babe_config_repository_impl.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -159,9 +159,9 @@ namespace kagome::consensus::babe {
159159
}
160160

161161
root_ = std::move(saved_state_res.value());
162-
SL_DEBUG(logger_,
163-
"State was initialized by savepoint on block {}",
164-
root_->block);
162+
SL_VERBOSE(logger_,
163+
"State was initialized by savepoint on block {}",
164+
root_->block);
165165
break;
166166
}
167167
}
@@ -182,7 +182,7 @@ namespace kagome::consensus::babe {
182182
{0, genesis_hash},
183183
std::make_shared<primitives::BabeConfiguration>(
184184
std::move(babe_config)));
185-
SL_DEBUG(logger_, "State was initialized by genesis block");
185+
SL_VERBOSE(logger_, "State was initialized by genesis block");
186186
}
187187

188188
BOOST_ASSERT_MSG(root_ != nullptr, "The root must be initialized by now");

‎core/consensus/babe/impl/babe_impl.cpp

+21-15
Original file line numberDiff line numberDiff line change
@@ -368,8 +368,9 @@ namespace kagome::consensus::babe {
368368
return current_state_;
369369
}
370370

371-
void BabeImpl::onRemoteStatus(const libp2p::peer::PeerId &peer_id,
372-
const network::Status &status) {
371+
void BabeImpl::onBlockAnnounceHandshake(
372+
const libp2p::peer::PeerId &peer_id,
373+
const network::BlockAnnounceHandshake &handshake) {
373374
// If state is loading, just to ping of loading
374375
if (current_state_ == Babe::State::STATE_LOADING) {
375376
startStateSyncing(peer_id);
@@ -383,7 +384,7 @@ namespace kagome::consensus::babe {
383384
BOOST_ASSERT(current_best_block_res.has_value());
384385
const auto &current_best_block = current_best_block_res.value();
385386

386-
if (current_best_block == status.best_block) {
387+
if (current_best_block == handshake.best_block) {
387388
if (current_state_ == Babe::State::HEADERS_LOADING) {
388389
current_state_ = Babe::State::HEADERS_LOADED;
389390
startStateSyncing(peer_id);
@@ -395,11 +396,11 @@ namespace kagome::consensus::babe {
395396
}
396397

397398
// Remote peer is lagged
398-
if (status.best_block.number <= last_finalized_block.number) {
399+
if (handshake.best_block.number <= last_finalized_block.number) {
399400
return;
400401
}
401402

402-
startCatchUp(peer_id, status.best_block);
403+
startCatchUp(peer_id, handshake.best_block);
403404
}
404405

405406
void BabeImpl::onBlockAnnounce(const libp2p::peer::PeerId &peer_id,
@@ -543,7 +544,9 @@ namespace kagome::consensus::babe {
543544
auto block_tree_leaves = block_tree_->getLeaves();
544545

545546
for (const auto &hash : block_tree_leaves) {
546-
if (hash == block_at_state.hash) continue;
547+
if (hash == block_at_state.hash) {
548+
continue;
549+
}
547550

548551
auto header_res = block_tree_->getBlockHeader(hash);
549552
if (header_res.has_error()) {
@@ -568,9 +571,13 @@ namespace kagome::consensus::babe {
568571
} while (affected);
569572

570573
if (app_config_.syncMethod() == SyncMethod::FastWithoutState) {
571-
SL_INFO(log_, "Stateless fast sync is finished; Application is stopping");
572-
log_->flush();
573-
app_state_manager_->shutdown();
574+
if (app_state_manager_->state()
575+
!= application::AppStateManager::State::ShuttingDown) {
576+
SL_INFO(log_,
577+
"Stateless fast sync is finished; Application is stopping");
578+
log_->flush();
579+
app_state_manager_->shutdown();
580+
}
574581
return;
575582
}
576583

@@ -639,9 +646,8 @@ namespace kagome::consensus::babe {
639646

640647
auto finish_time = babe_util_->slotFinishTime(current_slot_);
641648

642-
rewind_slots =
643-
now > finish_time
644-
and (now - finish_time) > babe_config_repo_->slotDuration();
649+
rewind_slots = now > finish_time
650+
and (now - finish_time) > babe_config_repo_->slotDuration();
645651

646652
if (rewind_slots) {
647653
// we are too far behind; after skipping some slots (but not epochs)
@@ -662,7 +668,7 @@ namespace kagome::consensus::babe {
662668

663669
// Slot processing begins in 1/3 slot time before end
664670
auto finish_time = babe_util_->slotFinishTime(current_slot_)
665-
- babe_config_repo_->slotDuration() / 3;
671+
- babe_config_repo_->slotDuration() / 3;
666672

667673
SL_VERBOSE(log_,
668674
"Starting a slot {} in epoch {} (remains {:.2f} sec.)",
@@ -953,8 +959,8 @@ namespace kagome::consensus::babe {
953959
return common::Buffer{scale::encode(ext).value()};
954960
}));
955961
return ext_root_res.has_value()
956-
and (ext_root_res.value()
957-
== common::Buffer(block.header.extrinsics_root));
962+
and (ext_root_res.value()
963+
== common::Buffer(block.header.extrinsics_root));
958964
}(),
959965
"Extrinsics root does not match extrinsics in the block");
960966

‎core/consensus/babe/impl/babe_impl.hpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,9 @@ namespace kagome::consensus::babe {
121121

122122
State getCurrentState() const override;
123123

124-
void onRemoteStatus(const libp2p::peer::PeerId &peer_id,
125-
const network::Status &status) override;
124+
void onBlockAnnounceHandshake(
125+
const libp2p::peer::PeerId &peer_id,
126+
const network::BlockAnnounceHandshake &handshake) override;
126127

127128
void onBlockAnnounce(const libp2p::peer::PeerId &peer_id,
128129
const network::BlockAnnounce &announce) override;

‎core/consensus/babe/impl/block_appender_impl.cpp

+8-6
Original file line numberDiff line numberDiff line change
@@ -272,12 +272,14 @@ namespace kagome::consensus::babe {
272272
auto block_delta = block_info.number - speed_data_.block_number;
273273
auto time_delta = now - speed_data_.time;
274274
if (block_delta >= 10000 or time_delta >= std::chrono::minutes(1)) {
275-
SL_INFO(logger_,
276-
"Imported {} more headers of blocks. Average speed is {} bps",
277-
block_delta,
278-
block_delta
279-
/ std::chrono::duration_cast<std::chrono::seconds>(time_delta)
280-
.count());
275+
SL_LOG(logger_,
276+
speed_data_.block_number ? log::Level::INFO
277+
: static_cast<log::Level>(-1),
278+
"Imported {} more headers of blocks. Average speed is {} bps",
279+
block_delta,
280+
block_delta
281+
/ std::chrono::duration_cast<std::chrono::seconds>(time_delta)
282+
.count());
281283
speed_data_.block_number = block_info.number;
282284
speed_data_.time = now;
283285
}

‎core/consensus/babe/impl/block_appender_impl.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ namespace kagome::consensus::babe {
7474

7575
struct {
7676
std::chrono::high_resolution_clock::time_point time;
77-
primitives::BlockNumber block_number;
77+
primitives::BlockNumber block_number = 0;
7878
} speed_data_ = {};
7979

8080
log::Logger logger_;

‎core/consensus/babe/impl/block_executor_impl.cpp

+25-5
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ namespace kagome::consensus::babe {
117117
}
118118

119119
// get current time to measure performance if block execution
120-
auto t_start = std::chrono::high_resolution_clock::now();
120+
auto start_time = std::chrono::high_resolution_clock::now();
121121

122122
bool block_was_applied_earlier = false;
123123

@@ -333,13 +333,33 @@ namespace kagome::consensus::babe {
333333
}
334334
}
335335

336-
auto t_end = std::chrono::high_resolution_clock::now();
336+
auto lag = std::chrono::system_clock::now()
337+
- babe_util_->slotStartTime(slot_number);
338+
std::string lag_msg;
339+
if (lag > std::chrono::hours(99)) {
340+
lag_msg = fmt::format(
341+
" (lag {} days)",
342+
std::chrono::duration_cast<std::chrono::hours>(lag).count() / 24);
343+
} else if (lag > std::chrono::minutes(99)) {
344+
lag_msg = fmt::format(
345+
" (lag {} hr.)",
346+
std::chrono::duration_cast<std::chrono::hours>(lag).count());
347+
} else if (lag >= std::chrono::minutes(1)) {
348+
lag_msg = fmt::format(
349+
" (lag {} min.)",
350+
std::chrono::duration_cast<std::chrono::minutes>(lag).count());
351+
} else if (lag > babe_config_repo_->slotDuration() * 2) {
352+
lag_msg = " (lag <1 min.)";
353+
}
354+
355+
auto now = std::chrono::high_resolution_clock::now();
337356

338357
logger_->info(
339-
"Imported block {} within {} ms",
358+
"Imported block {} within {} ms.{}",
340359
block_info,
341-
std::chrono::duration_cast<std::chrono::milliseconds>(t_end - t_start)
342-
.count());
360+
std::chrono::duration_cast<std::chrono::milliseconds>(now - start_time)
361+
.count(),
362+
lag_msg);
343363

344364
last_finalized_block = block_tree_->getLastFinalized();
345365
telemetry_->notifyBlockFinalized(last_finalized_block);

‎core/consensus/grandpa/impl/authority_manager_impl.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -163,9 +163,9 @@ namespace kagome::consensus::grandpa {
163163
}
164164

165165
root_ = std::move(saved_state_res.value());
166-
SL_DEBUG(logger_,
167-
"State was initialized by savepoint on block {}",
168-
root_->block);
166+
SL_VERBOSE(logger_,
167+
"State was initialized by savepoint on block {}",
168+
root_->block);
169169
break;
170170
}
171171
}
@@ -188,7 +188,7 @@ namespace kagome::consensus::grandpa {
188188
ScheduleNode::createAsRoot(std::make_shared<primitives::AuthoritySet>(
189189
0, std::move(initial_authorities)),
190190
{0, genesis_hash});
191-
SL_DEBUG(logger_, "State was initialized by genesis block");
191+
SL_VERBOSE(logger_, "State was initialized by genesis block");
192192
}
193193

194194
BOOST_ASSERT_MSG(root_ != nullptr, "The root must be initialized by now");

‎core/log/configurator.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ namespace kagome::log {
6161
- name: grandpa
6262
children:
6363
- name: voting_round
64+
- name: parachain
6465
- name: runtime
6566
children:
6667
- name: runtime_api
@@ -73,6 +74,7 @@ namespace kagome::log {
7374
- name: child_storage_extension
7475
- name: offchain_extension
7576
- name: misc_extension
77+
- name: runtime_cache
7678
- name: binaryen
7779
- name: wavm
7880
- name: metrics

‎core/network/block_announce_observer.hpp

+4-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
#include <libp2p/peer/peer_id.hpp>
1010

1111
#include "network/types/block_announce.hpp"
12-
#include "network/types/status.hpp"
12+
#include "network/types/block_announce_handshake.hpp"
1313

1414
namespace kagome::network {
1515
/**
@@ -22,8 +22,9 @@ namespace kagome::network {
2222
* Triggered when a Status arrives (as handshake of block announce protocol)
2323
* @param status - remote status
2424
*/
25-
virtual void onRemoteStatus(const libp2p::peer::PeerId &peer_id,
26-
const Status &remote_status) = 0;
25+
virtual void onBlockAnnounceHandshake(
26+
const libp2p::peer::PeerId &peer_id,
27+
const BlockAnnounceHandshake &block_announce_handshake) = 0;
2728

2829
/**
2930
* Triggered when a BlockAnnounce message arrives

‎core/network/impl/peer_manager_impl.cpp

+12-8
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,9 @@ namespace kagome::network {
282282
std::pair<network::CollatorPublicKey const &, network::ParachainId>>
283283
PeerManagerImpl::insertAdvertisement(PeerState &peer_state,
284284
primitives::BlockHash para_hash) {
285-
if (!peer_state.collator_state) return Error::UNDECLARED_COLLATOR;
285+
if (!peer_state.collator_state) {
286+
return Error::UNDECLARED_COLLATOR;
287+
}
286288

287289
auto my_view = peer_view_->getMyView();
288290
BOOST_ASSERT(my_view);
@@ -291,8 +293,10 @@ namespace kagome::network {
291293
return Error::OUT_OF_VIEW;
292294
}
293295

294-
if (peer_state.collator_state.value().advertisements.count(para_hash) != 0)
296+
if (peer_state.collator_state.value().advertisements.count(para_hash)
297+
!= 0) {
295298
return Error::DUPLICATE;
299+
}
296300

297301
peer_state.collator_state.value().advertisements.insert(
298302
std::move(para_hash));
@@ -539,12 +543,12 @@ namespace kagome::network {
539543
});
540544
}
541545

542-
void PeerManagerImpl::updatePeerState(const PeerId &peer_id,
543-
const Status &status) {
546+
void PeerManagerImpl::updatePeerState(
547+
const PeerId &peer_id, const BlockAnnounceHandshake &handshake) {
544548
auto [it, is_new] = peer_states_.emplace(peer_id, PeerState{});
545549
it->second.time = clock_->now();
546-
it->second.roles = status.roles;
547-
it->second.best_block = status.best_block;
550+
it->second.roles = handshake.roles;
551+
it->second.best_block = handshake.best_block;
548552
}
549553

550554
void PeerManagerImpl::updatePeerState(const PeerId &peer_id,
@@ -637,8 +641,8 @@ namespace kagome::network {
637641
return;
638642
}
639643
PeerType peer_type = connection->isInitiator()
640-
? PeerType::PEER_TYPE_OUT
641-
: PeerType::PEER_TYPE_IN;
644+
? PeerType::PEER_TYPE_OUT
645+
: PeerType::PEER_TYPE_IN;
642646

643647
// Add to active peer list
644648
if (auto [ap_it, added] = self->active_peers_.emplace(

‎core/network/impl/peer_manager_impl.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ namespace kagome::network {
119119
void startPingingPeer(const PeerId &peer_id) override;
120120

121121
/** @see PeerManager::updatePeerState */
122-
void updatePeerState(const PeerId &peer_id, const Status &status) override;
122+
void updatePeerState(const PeerId &peer_id,
123+
const BlockAnnounceHandshake &handshake) override;
123124

124125
/** @see PeerManager::updatePeerState */
125126
void updatePeerState(const PeerId &peer_id,

‎core/network/impl/protocols/block_announce_protocol.cpp

+128-110
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ namespace kagome::network {
5252
return base_.protocolName();
5353
}
5454

55-
outcome::result<Status> BlockAnnounceProtocol::createStatus() const {
55+
outcome::result<BlockAnnounceHandshake>
56+
BlockAnnounceProtocol::createHandshake() const {
5657
/// Roles
5758
Roles roles = app_config_.roles();
5859

@@ -66,59 +67,59 @@ namespace kagome::network {
6667
} else {
6768
base_.logger()->error("Could not get best block info: {}",
6869
best_res.error());
69-
return ProtocolError::CAN_NOT_CREATE_STATUS;
70+
return ProtocolError::CAN_NOT_CREATE_HANDSHAKE;
7071
}
7172

7273
auto &genesis_hash = block_tree_->getGenesisBlockHash();
7374

74-
return Status{
75+
return BlockAnnounceHandshake{
7576
.roles = roles, .best_block = best_block, .genesis_hash = genesis_hash};
7677
}
7778

7879
void BlockAnnounceProtocol::onIncomingStream(std::shared_ptr<Stream> stream) {
7980
BOOST_ASSERT(stream->remotePeerId().has_value());
8081

81-
readStatus(stream,
82-
Direction::INCOMING,
83-
[wp = weak_from_this(), stream](outcome::result<void> res) {
84-
auto self = wp.lock();
85-
if (not self) {
86-
stream->reset();
87-
return;
88-
}
82+
readHandshake(
83+
stream,
84+
Direction::INCOMING,
85+
[wp = weak_from_this(), stream](outcome::result<void> res) {
86+
auto self = wp.lock();
87+
if (not self) {
88+
stream->reset();
89+
return;
90+
}
8991

90-
auto peer_id = stream->remotePeerId().value();
92+
auto peer_id = stream->remotePeerId().value();
9193

92-
if (not res.has_value()) {
93-
SL_VERBOSE(
94-
self->base_.logger(),
94+
if (not res.has_value()) {
95+
SL_VERBOSE(self->base_.logger(),
9596
"Handshake failed on incoming {} stream with {}: {}",
9697
self->protocolName(),
97-
peer_id.toBase58(),
98+
peer_id,
9899
res.error());
99-
stream->reset();
100-
return;
101-
}
102-
103-
res = self->stream_engine_->addIncoming(stream, self);
104-
if (not res.has_value()) {
105-
SL_VERBOSE(self->base_.logger(),
106-
"Can't register incoming {} stream with {}: {}",
107-
self->protocolName(),
108-
peer_id.toBase58(),
109-
res.error());
110-
stream->reset();
111-
return;
112-
}
113-
114-
self->peer_manager_->reserveStreams(peer_id);
115-
self->peer_manager_->startPingingPeer(peer_id);
116-
117-
SL_VERBOSE(self->base_.logger(),
118-
"Fully established incoming {} stream with {}",
119-
self->protocolName(),
120-
peer_id);
121-
});
100+
stream->reset();
101+
return;
102+
}
103+
104+
res = self->stream_engine_->addIncoming(stream, self);
105+
if (not res.has_value()) {
106+
SL_VERBOSE(self->base_.logger(),
107+
"Can't register incoming {} stream with {}: {}",
108+
self->protocolName(),
109+
peer_id,
110+
res.error());
111+
stream->reset();
112+
return;
113+
}
114+
115+
self->peer_manager_->reserveStreams(peer_id);
116+
self->peer_manager_->startPingingPeer(peer_id);
117+
118+
SL_VERBOSE(self->base_.logger(),
119+
"Fully established incoming {} stream with {}",
120+
self->protocolName(),
121+
peer_id);
122+
});
122123
}
123124

124125
void BlockAnnounceProtocol::newOutgoingStream(
@@ -192,127 +193,143 @@ namespace kagome::network {
192193
cb(std::move(stream));
193194
};
194195

195-
self->writeStatus(std::move(stream_and_proto.stream),
196-
Direction::OUTGOING,
197-
std::move(cb2));
196+
self->writeHandshake(std::move(stream_and_proto.stream),
197+
Direction::OUTGOING,
198+
std::move(cb2));
198199
});
199200
}
200201

201-
void BlockAnnounceProtocol::readStatus(
202+
void BlockAnnounceProtocol::readHandshake(
202203
std::shared_ptr<Stream> stream,
203204
Direction direction,
204205
std::function<void(outcome::result<void>)> &&cb) {
205206
auto read_writer = std::make_shared<ScaleMessageReadWriter>(stream);
206207

207-
read_writer->read<Status>(
208+
read_writer->read<BlockAnnounceHandshake>(
208209
[stream, direction, wp = weak_from_this(), cb = std::move(cb)](
209-
auto &&remote_status_res) mutable {
210+
auto &&handshake_res) mutable {
210211
auto self = wp.lock();
211212
if (not self) {
212213
stream->reset();
213214
cb(ProtocolError::GONE);
214215
return;
215216
}
216217

217-
if (not remote_status_res.has_value()) {
218+
BOOST_ASSERT_MSG(stream->remotePeerId().has_value(),
219+
"peer_id must be known at this moment");
220+
auto peer_id = stream->remotePeerId().value();
221+
222+
if (not handshake_res.has_value()) {
218223
SL_VERBOSE(self->base_.logger(),
219-
"Can't read handshake from {}: {}",
220-
stream->remotePeerId().value(),
221-
remote_status_res.error());
224+
"Can't read handshake from {} over {} stream: {}",
225+
peer_id,
226+
to_string(direction),
227+
handshake_res.error());
222228
stream->reset();
223-
cb(remote_status_res.as_failure());
229+
cb(handshake_res.as_failure());
224230
return;
225231
}
226-
auto &remote_status = remote_status_res.value();
227-
228-
SL_TRACE(self->base_.logger(),
229-
"Handshake has received from {}",
230-
stream->remotePeerId().value());
232+
auto &handshake = handshake_res.value();
231233

232234
auto &genesis_hash = self->block_tree_->getGenesisBlockHash();
233235

234-
if (remote_status.genesis_hash != genesis_hash) {
235-
SL_VERBOSE(self->base_.logger(),
236-
"Error while processing status: genesis no match");
236+
if (handshake.genesis_hash != genesis_hash) {
237+
SL_VERBOSE(
238+
self->base_.logger(),
239+
"Error while processing handshake from {}: genesis no match",
240+
peer_id);
237241
stream->reset();
238242
cb(ProtocolError::GENESIS_NO_MATCH);
239243
return;
240244
}
241245

242-
auto peer_id = stream->remotePeerId().value();
243246
SL_TRACE(self->base_.logger(),
244-
"Received status from peer_id={} (best block {})",
247+
"Handshake has received from {} over {} stream: "
248+
"roles {}, best block {}",
245249
peer_id,
246-
remote_status.best_block.number);
247-
self->peer_manager_->updatePeerState(peer_id, remote_status);
250+
to_string(direction),
251+
to_string(handshake.roles),
252+
handshake.best_block);
253+
254+
self->peer_manager_->updatePeerState(peer_id, handshake);
248255

249256
switch (direction) {
250257
case Direction::OUTGOING:
251258
cb(outcome::success());
252259
break;
253260
case Direction::INCOMING:
254-
self->writeStatus(
261+
self->writeHandshake(
255262
std::move(stream), Direction::INCOMING, std::move(cb));
256263
break;
257264
}
258265

259-
self->observer_->onRemoteStatus(peer_id, remote_status);
266+
self->observer_->onBlockAnnounceHandshake(peer_id, handshake);
260267
});
261268
}
262269

263-
void BlockAnnounceProtocol::writeStatus(
270+
void BlockAnnounceProtocol::writeHandshake(
264271
std::shared_ptr<Stream> stream,
265272
Direction direction,
266273
std::function<void(outcome::result<void>)> &&cb) {
267274
auto read_writer = std::make_shared<ScaleMessageReadWriter>(stream);
268275

269-
auto status_res = createStatus();
270-
if (not status_res.has_value()) {
276+
auto handshake_res = createHandshake();
277+
if (not handshake_res.has_value()) {
271278
stream->reset();
272-
cb(ProtocolError::CAN_NOT_CREATE_STATUS);
279+
cb(ProtocolError::CAN_NOT_CREATE_HANDSHAKE);
273280
return;
274281
}
275282

276-
const auto &status = status_res.value();
277-
278-
read_writer->write(status,
279-
[stream = std::move(stream),
280-
direction,
281-
wp = weak_from_this(),
282-
cb = std::move(cb)](auto &&write_res) mutable {
283-
auto self = wp.lock();
284-
if (not self) {
285-
stream->reset();
286-
cb(ProtocolError::GONE);
287-
return;
288-
}
289-
290-
if (not write_res.has_value()) {
291-
SL_VERBOSE(self->base_.logger(),
292-
"Can't send handshake to {}: {}",
293-
stream->remotePeerId().value(),
294-
write_res.error());
295-
stream->reset();
296-
cb(write_res.as_failure());
297-
return;
298-
}
299-
300-
SL_TRACE(self->base_.logger(),
301-
"Handshake has sent to {}",
302-
stream->remotePeerId().value());
303-
304-
switch (direction) {
305-
case Direction::OUTGOING:
306-
self->readStatus(std::move(stream),
307-
Direction::OUTGOING,
308-
std::move(cb));
309-
break;
310-
case Direction::INCOMING:
311-
cb(outcome::success());
312-
self->readAnnounce(std::move(stream));
313-
break;
314-
}
315-
});
283+
const auto &handshake = handshake_res.value();
284+
285+
SL_TRACE(
286+
base_.logger(),
287+
"Handshake will sent to {} over {} stream: roles {}, best block {}",
288+
stream->remotePeerId().value(),
289+
to_string(direction),
290+
to_string(handshake.roles),
291+
handshake.best_block);
292+
293+
read_writer->write(
294+
handshake,
295+
[stream = std::move(stream),
296+
direction,
297+
wp = weak_from_this(),
298+
cb = std::move(cb)](auto &&write_res) mutable {
299+
auto self = wp.lock();
300+
if (not self) {
301+
stream->reset();
302+
cb(ProtocolError::GONE);
303+
return;
304+
}
305+
306+
if (not write_res.has_value()) {
307+
SL_VERBOSE(self->base_.logger(),
308+
"Can't send handshake to {} over {} stream: {}",
309+
stream->remotePeerId().value(),
310+
to_string(direction),
311+
write_res.error());
312+
stream->reset();
313+
cb(write_res.as_failure());
314+
return;
315+
}
316+
317+
SL_TRACE(self->base_.logger(),
318+
"Handshake has sent to {} over {} stream",
319+
stream->remotePeerId().value(),
320+
to_string(direction));
321+
322+
switch (direction) {
323+
case Direction::OUTGOING:
324+
self->readHandshake(
325+
std::move(stream), Direction::OUTGOING, std::move(cb));
326+
break;
327+
case Direction::INCOMING:
328+
cb(outcome::success());
329+
self->readAnnounce(std::move(stream));
330+
break;
331+
}
332+
});
316333
}
317334

318335
void BlockAnnounceProtocol::readAnnounce(std::shared_ptr<Stream> stream) {
@@ -336,7 +353,10 @@ namespace kagome::network {
336353
return;
337354
}
338355

356+
BOOST_ASSERT_MSG(stream->remotePeerId().has_value(),
357+
"peer_id must be known at this moment");
339358
auto peer_id = stream->remotePeerId().value();
359+
340360
auto &block_announce = block_announce_res.value();
341361

342362
SL_VERBOSE(self->base_.logger(),
@@ -346,8 +366,6 @@ namespace kagome::network {
346366

347367
self->observer_->onBlockAnnounce(peer_id, block_announce);
348368

349-
BOOST_ASSERT_MSG(stream->remotePeerId().has_value(),
350-
"peer_id must be known at this moment");
351369
self->peer_manager_->updatePeerState(stream->remotePeerId().value(),
352370
block_announce);
353371

‎core/network/impl/protocols/block_announce_protocol.hpp

+19-8
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include "network/impl/stream_engine.hpp"
2626
#include "network/peer_manager.hpp"
2727
#include "network/types/block_announce.hpp"
28-
#include "network/types/status.hpp"
28+
#include "network/types/block_announce_handshake.hpp"
2929
#include "utils/non_copyable.hpp"
3030

3131
namespace kagome::network {
@@ -64,16 +64,27 @@ namespace kagome::network {
6464
void blockAnnounce(BlockAnnounce &&announce);
6565

6666
private:
67-
outcome::result<Status> createStatus() const;
67+
outcome::result<BlockAnnounceHandshake> createHandshake() const;
6868

6969
enum class Direction { INCOMING, OUTGOING };
70-
void readStatus(std::shared_ptr<Stream> stream,
71-
Direction direction,
72-
std::function<void(outcome::result<void>)> &&cb);
7370

74-
void writeStatus(std::shared_ptr<Stream> stream,
75-
Direction direction,
76-
std::function<void(outcome::result<void>)> &&cb);
71+
friend inline std::string_view to_string(Direction direction) {
72+
switch (direction) {
73+
case Direction::INCOMING:
74+
return "incoming";
75+
case Direction::OUTGOING:
76+
return "outgoing";
77+
}
78+
return "unknown";
79+
}
80+
81+
void readHandshake(std::shared_ptr<Stream> handshake_res,
82+
Direction direction,
83+
std::function<void(outcome::result<void>)> &&cb);
84+
85+
void writeHandshake(std::shared_ptr<Stream> stream,
86+
Direction direction,
87+
std::function<void(outcome::result<void>)> &&cb);
7788

7889
void readAnnounce(std::shared_ptr<Stream> stream);
7990

‎core/network/impl/protocols/collation_protocol.hpp

+6-3
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,9 @@
2323
#include "network/impl/stream_engine.hpp"
2424
#include "network/peer_manager.hpp"
2525
#include "network/types/block_announce.hpp"
26+
#include "network/types/block_announce_handshake.hpp"
2627
#include "network/types/collator_messages.hpp"
2728
#include "network/types/roles.hpp"
28-
#include "network/types/status.hpp"
2929
#include "utils/non_copyable.hpp"
3030

3131
namespace kagome::network {
@@ -68,7 +68,9 @@ namespace kagome::network {
6868
func{std::forward<F>(func)},
6969
stream](auto &&result) mutable {
7070
auto self = wptr.lock();
71-
if (!result || !self) return std::forward<F>(func)(std::move(result));
71+
if (!result || !self) {
72+
return std::forward<F>(func)(std::move(result));
73+
}
7274

7375
auto read_writer = std::make_shared<ScaleMessageReadWriter>(stream);
7476
read_writer->write(
@@ -83,8 +85,9 @@ namespace kagome::network {
8385
[wptr{weak_from_this()}, func{std::forward<F>(func)}, stream](
8486
auto &&result) mutable {
8587
auto self = wptr.lock();
86-
if (!result || !self)
88+
if (!result || !self) {
8789
return std::forward<F>(func)(std::move(result));
90+
}
8891

8992
auto read_writer =
9093
std::make_shared<ScaleMessageReadWriter>(stream);

‎core/network/impl/protocols/protocol_error.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ OUTCOME_CPP_DEFINE_CATEGORY(kagome::network, ProtocolError, e) {
1212
return "Protocol was switched off";
1313
case E::PROTOCOL_NOT_IMPLEMENTED:
1414
return "Protocol is not implemented";
15-
case E::CAN_NOT_CREATE_STATUS:
16-
return "Can not create status";
15+
case E::CAN_NOT_CREATE_HANDSHAKE:
16+
return "Can not create handshake";
1717
case E::NODE_NOT_SYNCHRONIZED_YET:
1818
return "Node is not synchronized yet";
1919
case E::GENESIS_NO_MATCH:

‎core/network/impl/protocols/protocol_error.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace kagome::network {
1313
enum class ProtocolError {
1414
GONE = 1,
1515
PROTOCOL_NOT_IMPLEMENTED,
16-
CAN_NOT_CREATE_STATUS,
16+
CAN_NOT_CREATE_HANDSHAKE,
1717
NODE_NOT_SYNCHRONIZED_YET,
1818
GENESIS_NO_MATCH,
1919
HANDSHAKE_ERROR

‎core/network/impl/protocols/protocol_req_collation.hpp

-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
#include "network/protocols/req_collation_protocol.hpp"
2222
#include "network/types/collator_messages.hpp"
2323
#include "network/types/roles.hpp"
24-
#include "network/types/status.hpp"
2524
#include "utils/non_copyable.hpp"
2625

2726
namespace kagome::network {

‎core/network/impl/synchronizer_impl.cpp

+115-32
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ namespace {
6060
case SM::Fast:
6161
case SM::FastWithoutState:
6262
return kagome::network::BlockAttribute::HEADER
63-
| kagome::network::BlockAttribute::JUSTIFICATION;
63+
| kagome::network::BlockAttribute::JUSTIFICATION;
6464
}
6565
return kagome::network::BlocksRequest::kBasicAttributes;
6666
}
@@ -203,7 +203,9 @@ namespace kagome::network {
203203
it != known_blocks_.end()) {
204204
auto &block_in_queue = it->second;
205205
block_in_queue.peers.emplace(peer_id);
206-
if (handler) handler(block_info);
206+
if (handler) {
207+
handler(block_info);
208+
}
207209
return false;
208210
}
209211

@@ -229,7 +231,9 @@ namespace kagome::network {
229231

230232
// Provided block is equal our best one. Nothing needs to do.
231233
if (block_info == best_block) {
232-
if (handler) handler(block_info);
234+
if (handler) {
235+
handler(block_info);
236+
}
233237
return false;
234238
}
235239

@@ -264,7 +268,9 @@ namespace kagome::network {
264268

265269
// Finding the best common block was failed
266270
if (not res.has_value()) {
267-
if (handler) handler(res.as_failure());
271+
if (handler) {
272+
handler(res.as_failure());
273+
}
268274
return;
269275
}
270276

@@ -274,7 +280,9 @@ namespace kagome::network {
274280
it != self->known_blocks_.end()) {
275281
auto &block_in_queue = it->second;
276282
block_in_queue.peers.emplace(peer_id);
277-
if (handler) handler(std::move(block_info));
283+
if (handler) {
284+
handler(std::move(block_info));
285+
}
278286
return;
279287
}
280288

@@ -405,14 +413,16 @@ namespace kagome::network {
405413

406414
auto request_fingerprint = request.fingerprint();
407415

408-
if (not recent_requests_.emplace(peer_id, request_fingerprint).second) {
416+
if (auto r = recent_requests_.emplace(
417+
std::make_tuple(peer_id, request_fingerprint), "find common block");
418+
not r.second) {
409419
SL_VERBOSE(log_,
410420
"Can't check if block #{} in #{}..#{} is common with {}: {}",
411421
hint,
412422
lower,
413423
upper - 1,
414424
peer_id,
415-
make_error_code(Error::DUPLICATE_REQUEST));
425+
r.first->second);
416426
handler(Error::DUPLICATE_REQUEST);
417427
return;
418428
}
@@ -566,7 +576,9 @@ namespace kagome::network {
566576
SyncResultHandler &&handler) {
567577
// Interrupts process if node is shutting down
568578
if (node_is_shutting_down_) {
569-
if (handler) handler(Error::SHUTTING_DOWN);
579+
if (handler) {
580+
handler(Error::SHUTTING_DOWN);
581+
}
570582
return;
571583
}
572584

@@ -577,13 +589,17 @@ namespace kagome::network {
577589

578590
auto request_fingerprint = request.fingerprint();
579591

580-
if (not recent_requests_.emplace(peer_id, request_fingerprint).second) {
592+
if (auto r = recent_requests_.emplace(
593+
std::make_tuple(peer_id, request_fingerprint), "load blocks");
594+
not r.second) {
581595
SL_ERROR(log_,
582596
"Can't load blocks from {} beginning block {}: {}",
583597
peer_id,
584598
from,
585-
make_error_code(Error::DUPLICATE_REQUEST));
586-
if (handler) handler(Error::DUPLICATE_REQUEST);
599+
r.first->second);
600+
if (handler) {
601+
handler(Error::DUPLICATE_REQUEST);
602+
}
587603
return;
588604
}
589605

@@ -607,7 +623,9 @@ namespace kagome::network {
607623
peer_id,
608624
from,
609625
response_res.error());
610-
if (handler) handler(response_res.as_failure());
626+
if (handler) {
627+
handler(response_res.as_failure());
628+
}
611629
return;
612630
}
613631
auto &blocks = response_res.value().blocks;
@@ -620,7 +638,9 @@ namespace kagome::network {
620638
"Response does not have any blocks",
621639
peer_id,
622640
from);
623-
if (handler) handler(Error::EMPTY_RESPONSE);
641+
if (handler) {
642+
handler(Error::EMPTY_RESPONSE);
643+
}
624644
return;
625645
}
626646

@@ -641,7 +661,9 @@ namespace kagome::network {
641661
"Received block without header",
642662
peer_id,
643663
from);
644-
if (handler) handler(Error::RESPONSE_WITHOUT_BLOCK_HEADER);
664+
if (handler) {
665+
handler(Error::RESPONSE_WITHOUT_BLOCK_HEADER);
666+
}
645667
return;
646668
}
647669
// Check if body is provided
@@ -651,7 +673,9 @@ namespace kagome::network {
651673
"Received block without body",
652674
peer_id,
653675
from);
654-
if (handler) handler(Error::RESPONSE_WITHOUT_BLOCK_BODY);
676+
if (handler) {
677+
handler(Error::RESPONSE_WITHOUT_BLOCK_BODY);
678+
}
655679
return;
656680
}
657681
auto &header = block.header.value();
@@ -669,7 +693,9 @@ namespace kagome::network {
669693
peer_id,
670694
from,
671695
BlockInfo(header.number, block.hash));
672-
if (handler) handler(Error::DISCARDED_BLOCK);
696+
if (handler) {
697+
handler(Error::DISCARDED_BLOCK);
698+
}
673699
return;
674700
}
675701

@@ -700,7 +726,9 @@ namespace kagome::network {
700726
peer_id,
701727
from,
702728
BlockInfo(header.number, header.parent_hash));
703-
if (handler) handler(Error::DISCARDED_BLOCK);
729+
if (handler) {
730+
handler(Error::DISCARDED_BLOCK);
731+
}
704732
return;
705733
}
706734

@@ -716,7 +744,9 @@ namespace kagome::network {
716744
"block {}: Received block is not descendant of previous",
717745
peer_id,
718746
from);
719-
if (handler) handler(Error::WRONG_ORDER);
747+
if (handler) {
748+
handler(Error::WRONG_ORDER);
749+
}
720750
return;
721751
}
722752

@@ -730,7 +760,9 @@ namespace kagome::network {
730760
"Received block whose hash does not match the header",
731761
peer_id,
732762
from);
733-
if (handler) handler(Error::INVALID_HASH);
763+
if (handler) {
764+
handler(Error::INVALID_HASH);
765+
}
734766
return;
735767
}
736768

@@ -788,7 +820,9 @@ namespace kagome::network {
788820
std::optional<uint32_t> limit,
789821
SyncResultHandler &&handler) {
790822
if (node_is_shutting_down_) {
791-
if (handler) handler(Error::SHUTTING_DOWN);
823+
if (handler) {
824+
handler(Error::SHUTTING_DOWN);
825+
}
792826
return;
793827
}
794828

@@ -807,12 +841,15 @@ namespace kagome::network {
807841
limit};
808842

809843
auto request_fingerprint = request.fingerprint();
810-
if (not recent_requests_.emplace(peer_id, request_fingerprint).second) {
844+
if (auto r = recent_requests_.emplace(
845+
std::make_tuple(peer_id, request_fingerprint),
846+
"load justifications");
847+
not r.second) {
811848
SL_ERROR(log_,
812849
"Can't load justification from {} for block {}: {}",
813850
peer_id,
814851
target_block,
815-
make_error_code(Error::DUPLICATE_REQUEST));
852+
r.first->second);
816853
if (handler) {
817854
handler(Error::DUPLICATE_REQUEST);
818855
}
@@ -824,6 +861,7 @@ namespace kagome::network {
824861
auto response_handler = [wp = weak_from_this(),
825862
peer_id,
826863
target_block,
864+
limit,
827865
handler = std::move(handler)](
828866
auto &&response_res) mutable {
829867
auto self = wp.lock();
@@ -851,26 +889,42 @@ namespace kagome::network {
851889
"Response does not have any contents",
852890
peer_id,
853891
target_block);
854-
if (handler) handler(Error::EMPTY_RESPONSE);
892+
if (handler) {
893+
handler(Error::EMPTY_RESPONSE);
894+
}
855895
return;
856896
}
857897

898+
// Use decreasing limit,
899+
// to avoid race between block and justification requests
900+
if (limit.has_value()) {
901+
if (blocks.size() >= limit.value()) {
902+
limit = 0;
903+
} else {
904+
limit.value() -= (blocks.size() - 1);
905+
}
906+
}
907+
858908
bool justification_received = false;
859909
BlockInfo last_justified_block;
910+
BlockInfo last_observed_block;
860911
for (auto &block : blocks) {
861912
if (not block.header) {
862913
SL_ERROR(self->log_,
863914
"No header was provided from {} for block {} while "
864915
"requesting justifications",
865916
peer_id,
866917
target_block);
867-
if (handler) handler(Error::RESPONSE_WITHOUT_BLOCK_HEADER);
918+
if (handler) {
919+
handler(Error::RESPONSE_WITHOUT_BLOCK_HEADER);
920+
}
868921
return;
869922
}
923+
last_observed_block =
924+
primitives::BlockInfo{block.header->number, block.hash};
870925
if (block.justification) {
871926
justification_received = true;
872-
last_justified_block =
873-
primitives::BlockInfo{block.header->number, block.hash};
927+
last_justified_block = last_observed_block;
874928
{
875929
std::lock_guard lock(self->justifications_mutex_);
876930
self->justifications_.emplace(last_justified_block,
@@ -887,6 +941,25 @@ namespace kagome::network {
887941
}
888942
});
889943
}
944+
945+
// Continue justifications requesting till limit is non-zero and last
946+
// observed block is not target (no block anymore)
947+
if ((not limit.has_value() or limit.value() > 0)
948+
and last_observed_block != target_block) {
949+
SL_TRACE(self->log_, "Request next block pack");
950+
self->scheduler_->schedule([wp,
951+
peer_id,
952+
target_block = last_observed_block,
953+
limit,
954+
handler = std::move(handler)]() mutable {
955+
if (auto self = wp.lock()) {
956+
self->loadJustifications(
957+
peer_id, target_block, limit, std::move(handler));
958+
}
959+
});
960+
return;
961+
}
962+
890963
if (handler) {
891964
handler(last_justified_block);
892965
}
@@ -1043,7 +1116,9 @@ namespace kagome::network {
10431116
"Block {} {} not applied as discarded",
10441117
block_info,
10451118
n ? fmt::format("and {} others have", n) : fmt::format("has"));
1046-
if (handler) handler(Error::DISCARDED_BLOCK);
1119+
if (handler) {
1120+
handler(Error::DISCARDED_BLOCK);
1121+
}
10471122
}
10481123

10491124
} else {
@@ -1068,7 +1143,9 @@ namespace kagome::network {
10681143
"state syncing on block in progress",
10691144
block_info,
10701145
n ? fmt::format("and {} others have", n) : fmt::format("has"));
1071-
if (handler) handler(Error::DISCARDED_BLOCK);
1146+
if (handler) {
1147+
handler(Error::DISCARDED_BLOCK);
1148+
}
10721149
return;
10731150
}
10741151
}
@@ -1086,15 +1163,21 @@ namespace kagome::network {
10861163
block_info,
10871164
n ? fmt::format("and {} others have", n) : fmt::format("has"),
10881165
applying_res.error());
1089-
if (handler) handler(Error::DISCARDED_BLOCK);
1166+
if (handler) {
1167+
handler(Error::DISCARDED_BLOCK);
1168+
}
10901169
} else {
10911170
SL_DEBUG(log_, "Block {} is skipped as existing", block_info);
1092-
if (handler) handler(block_info);
1171+
if (handler) {
1172+
handler(block_info);
1173+
}
10931174
}
10941175
} else {
10951176
telemetry_->notifyBlockImported(
10961177
block_info, telemetry::BlockOrigin::kNetworkInitialSync);
1097-
if (handler) handler(block_info);
1178+
if (handler) {
1179+
handler(block_info);
1180+
}
10981181

10991182
// Check if finality lag greater than justification saving interval
11001183
static const BlockNumber kJustificationInterval = 512;
@@ -1108,7 +1191,7 @@ namespace kagome::network {
11081191
syncMissingJustifications(
11091192
peer_id,
11101193
last_finalized,
1111-
std::nullopt,
1194+
kJustificationInterval * 2,
11121195
[wp = weak_from_this(), last_finalized, block_info](
11131196
auto res) {
11141197
if (auto self = wp.lock()) {

‎core/network/impl/synchronizer_impl.hpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,8 @@ namespace kagome::network {
289289
std::atomic_bool asking_blocks_portion_in_progress_ = false;
290290
std::set<libp2p::peer::PeerId> busy_peers_;
291291

292-
std::set<std::tuple<libp2p::peer::PeerId, BlocksRequest::Fingerprint>>
292+
std::map<std::tuple<libp2p::peer::PeerId, BlocksRequest::Fingerprint>,
293+
const char *>
293294
recent_requests_;
294295

295296
size_t entries_{0};

‎core/network/peer_manager.hpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
#include <libp2p/peer/peer_info.hpp>
1414

1515
#include "network/types/block_announce.hpp"
16+
#include "network/types/block_announce_handshake.hpp"
1617
#include "network/types/collator_messages.hpp"
1718
#include "network/types/grandpa_message.hpp"
18-
#include "network/types/status.hpp"
1919
#include "outcome/outcome.hpp"
2020
#include "primitives/common.hpp"
2121
#include "utils/non_copyable.hpp"
@@ -92,10 +92,10 @@ namespace kagome::network {
9292
virtual void startPingingPeer(const PeerId &peer_id) = 0;
9393

9494
/**
95-
* Updates known data about peer with {@param peer_id} by {@param status}
95+
* Updates known data about peer with {@param peer_id} by {@param handshake}
9696
*/
9797
virtual void updatePeerState(const PeerId &peer_id,
98-
const Status &status) = 0;
98+
const BlockAnnounceHandshake &handshake) = 0;
9999

100100
/**
101101
* Updates known data about peer with {@param peer_id} by {@param announce}

‎core/network/types/block_announce.hpp

+57-6
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,68 @@
77
#define KAGOME_BLOCK_ANNOUNCE_HPP
88

99
#include "primitives/block_header.hpp"
10-
#include "scale/tie.hpp"
10+
#include "scale/scale.hpp"
1111

1212
namespace kagome::network {
13-
/**
14-
* Announce a new complete block on the network
15-
*/
16-
struct BlockAnnounce {
17-
SCALE_TIE(1);
1813

14+
/// Block state in the chain.
15+
enum class BlockState : uint8_t {
16+
/// Block is not part of the best chain.
17+
Normal,
18+
/// Latest best block.
19+
Best,
20+
};
21+
22+
/// Announce a new complete relay chain block on the network.
23+
struct BlockAnnounce {
24+
/// New block header.
1925
primitives::BlockHeader header;
26+
27+
/// Block state.
28+
std::optional<BlockState> state = std::nullopt;
29+
30+
/// Data associated with this block announcement, e.g. a candidate message.
31+
std::optional<std::vector<uint8_t>> data = std::nullopt;
32+
33+
// operator== is needed only for tests
34+
inline bool operator==(const BlockAnnounce &other) const {
35+
return this->header == other.header and this->state == other.state
36+
and this->data == other.data;
37+
}
38+
39+
friend inline scale::ScaleEncoderStream &operator<<(
40+
scale::ScaleEncoderStream &s, const BlockAnnounce &v) {
41+
s << v.header;
42+
if (v.state.has_value()) {
43+
s << v.state.value();
44+
if (v.data.has_value()) {
45+
s << v.data.value();
46+
}
47+
}
48+
return s;
49+
}
50+
51+
friend inline scale::ScaleDecoderStream &operator>>(
52+
scale::ScaleDecoderStream &s, BlockAnnounce &v) {
53+
s >> v.header;
54+
if (s.hasMore(1)) {
55+
BlockState tmp;
56+
s >> tmp;
57+
v.state.emplace(tmp);
58+
} else {
59+
v.state.reset();
60+
}
61+
if (s.hasMore(1)) {
62+
std::vector<uint8_t> tmp;
63+
s >> tmp;
64+
v.data.emplace(std::move(tmp));
65+
} else {
66+
v.data.reset();
67+
}
68+
return s;
69+
}
2070
};
71+
2172
} // namespace kagome::network
2273

2374
#endif // KAGOME_BLOCK_ANNOUNCE_HPP
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef KAGOME_CORE_NETWORK_TYPES_STATUS_HPP
7+
#define KAGOME_CORE_NETWORK_TYPES_STATUS_HPP
8+
9+
#include <algorithm>
10+
#include <libp2p/peer/peer_info.hpp>
11+
#include <vector>
12+
13+
#include "network/types/roles.hpp"
14+
#include "primitives/common.hpp"
15+
#include "scale/scale.hpp"
16+
17+
namespace kagome::network {
18+
19+
using kagome::primitives::BlockHash;
20+
using kagome::primitives::BlockInfo;
21+
22+
/**
23+
* Handshake sent when we open a block announces substream.
24+
* Is the structure to send to a new connected peer. It contains common
25+
* information about current peer and used by the remote peer to detect the
26+
* posibility of the correct communication with it.
27+
*/
28+
struct BlockAnnounceHandshake {
29+
Roles roles; //!< Supported roles.
30+
31+
primitives::BlockInfo best_block; //!< Best block.
32+
33+
BlockHash genesis_hash; //!< Genesis block hash.
34+
35+
friend inline scale::ScaleEncoderStream &operator<<(
36+
scale::ScaleEncoderStream &s, const BlockAnnounceHandshake &v) {
37+
return s << v.roles << v.best_block.number << v.best_block.hash
38+
<< v.genesis_hash;
39+
}
40+
41+
friend inline scale::ScaleDecoderStream &operator>>(
42+
scale::ScaleDecoderStream &s, BlockAnnounceHandshake &v) {
43+
return s >> v.roles >> v.best_block.number >> v.best_block.hash
44+
>> v.genesis_hash;
45+
}
46+
};
47+
48+
} // namespace kagome::network
49+
50+
#endif // KAGOME_CORE_NETWORK_TYPES_STATUS_HPP

‎core/network/types/status.hpp

-73
This file was deleted.

‎examples/first_kagome_chain/localchain.json

+92-79
Large diffs are not rendered by default.

‎test/mock/core/consensus/babe/babe_mock.hpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ namespace kagome::consensus::babe {
2121
MOCK_METHOD(void, doOnSynchronized, (std::function<void()> handler));
2222

2323
MOCK_METHOD(void,
24-
onRemoteStatus,
24+
onBlockAnnounceHandshake,
2525
(const libp2p::peer::PeerId &peer_id,
26-
const network::Status &status),
26+
const network::BlockAnnounceHandshake &handshake),
2727
(override));
2828

2929
MOCK_METHOD(void,

‎test/mock/core/network/peer_manager_mock.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ namespace kagome::network {
3838

3939
MOCK_METHOD(void,
4040
updatePeerState,
41-
(const PeerId &, const Status &),
41+
(const PeerId &, const BlockAnnounceHandshake &),
4242
(override));
4343

4444
MOCK_METHOD(void,

0 commit comments

Comments
 (0)
Please sign in to comment.