Skip to content

Commit f986642

Browse files
committed
A0-3575: Update block sync message versions (#1696)
# Description We no longer need the id-only requests, nor support for v2 messages. Complete removal of id-only request logic will happen in a follow-up PR. ## Type of change - Breaking change (fix or feature that would cause existing functionality to not work as expected) # Checklist: - I have made corresponding changes to the existing documentation - I have created new documentation
1 parent 71b7207 commit f986642

File tree

4 files changed

+99
-190
lines changed

4 files changed

+99
-190
lines changed

finality-aleph/src/sync/data.rs

Lines changed: 76 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -6,49 +6,19 @@ use static_assertions::const_assert;
66

77
use crate::{
88
aleph_primitives::MAX_BLOCK_SIZE,
9-
block::{
10-
Block, Header, Justification, UnverifiedHeader, UnverifiedHeaderFor,
11-
UnverifiedJustification,
12-
},
9+
block::{Block, Header, Justification, UnverifiedHeader, UnverifiedHeaderFor},
1310
network::GossipNetwork,
1411
sync::{PeerId, LOG_TARGET},
1512
BlockId, Version,
1613
};
1714

18-
/// The representation of the database state to be sent to other nodes.
19-
/// In the first version this only contains the top justification.
20-
#[derive(Clone, Debug, Encode, Decode)]
21-
pub struct StateV1<J: Justification> {
22-
top_justification: J::Unverified,
23-
}
24-
2515
/// The representation of the database state to be sent to other nodes.
2616
#[derive(Clone, Debug, Encode, Decode)]
2717
pub struct State<J: Justification> {
2818
top_justification: J::Unverified,
2919
favourite_block: UnverifiedHeaderFor<J>,
3020
}
3121

32-
impl<J: Justification> From<StateV1<J>> for State<J> {
33-
fn from(other: StateV1<J>) -> Self {
34-
let StateV1 { top_justification } = other;
35-
let favourite_block = top_justification.header().clone();
36-
State {
37-
top_justification,
38-
favourite_block,
39-
}
40-
}
41-
}
42-
43-
impl<J: Justification> From<State<J>> for StateV1<J> {
44-
fn from(other: State<J>) -> Self {
45-
let State {
46-
top_justification, ..
47-
} = other;
48-
StateV1 { top_justification }
49-
}
50-
}
51-
5222
impl<J: Justification> State<J> {
5323
pub fn new(top_justification: J::Unverified, favourite_block: UnverifiedHeaderFor<J>) -> Self {
5424
State {
@@ -95,94 +65,72 @@ pub enum BranchKnowledge {
9565
TopImported(BlockId),
9666
}
9767

98-
/// Request content, first version.
99-
#[derive(Clone, Debug, Encode, Decode)]
100-
pub struct RequestV1<J: Justification> {
101-
target_id: BlockId,
102-
branch_knowledge: BranchKnowledge,
103-
state: StateV1<J>,
104-
}
105-
106-
impl<J: Justification> RequestV1<J> {
107-
/// A silly fallback to have old nodes respond with at least justifications
108-
/// when we request a chain extension.
109-
pub fn from_state_only(state: StateV1<J>) -> Self {
110-
let target_id = state.top_justification.header().id();
111-
let branch_knowledge = BranchKnowledge::TopImported(target_id.clone());
112-
Self {
113-
target_id,
114-
branch_knowledge,
115-
state,
116-
}
117-
}
118-
}
119-
12068
// TODO(A0-3494): Only needed because old requests did not have headers, afterwards we will have headers always.
12169
#[derive(Clone, Debug, Encode, Decode)]
12270
pub enum MaybeHeader<UH: UnverifiedHeader> {
12371
Header(UH),
12472
Id(BlockId),
12573
}
12674

127-
impl<UH: UnverifiedHeader> MaybeHeader<UH> {
128-
pub fn id(&self) -> BlockId {
129-
use MaybeHeader::*;
130-
match self {
131-
Header(header) => header.id(),
132-
Id(id) => id.clone(),
133-
}
134-
}
75+
/// Request content, version 2.
76+
#[derive(Clone, Debug, Encode, Decode)]
77+
pub struct RequestV2<J: Justification> {
78+
target: MaybeHeader<UnverifiedHeaderFor<J>>,
79+
branch_knowledge: BranchKnowledge,
80+
state: State<J>,
13581
}
13682

13783
/// Request content, current version.
13884
#[derive(Clone, Debug, Encode, Decode)]
13985
pub struct Request<J: Justification> {
140-
target: MaybeHeader<UnverifiedHeaderFor<J>>,
86+
target: UnverifiedHeaderFor<J>,
14187
branch_knowledge: BranchKnowledge,
14288
state: State<J>,
14389
}
14490

145-
impl<J: Justification> From<RequestV1<J>> for Request<J> {
146-
fn from(other: RequestV1<J>) -> Self {
147-
let RequestV1 {
148-
target_id,
91+
impl<J: Justification> TryFrom<RequestV2<J>> for Request<J> {
92+
type Error = ();
93+
94+
fn try_from(other: RequestV2<J>) -> Result<Self, Self::Error> {
95+
let RequestV2 {
96+
target,
14997
branch_knowledge,
15098
state,
15199
} = other;
152-
Request {
153-
target: MaybeHeader::Id(target_id),
100+
let target = match target {
101+
MaybeHeader::Header(header) => header,
102+
MaybeHeader::Id(_) => return Err(()),
103+
};
104+
Ok(Request {
105+
target,
154106
branch_knowledge,
155-
state: state.into(),
156-
}
107+
state,
108+
})
157109
}
158110
}
159111

160-
impl<J: Justification> From<Request<J>> for RequestV1<J> {
112+
impl<J: Justification> From<Request<J>> for RequestV2<J> {
161113
fn from(other: Request<J>) -> Self {
162114
let Request {
163115
target,
164116
branch_knowledge,
165117
state,
166118
} = other;
167-
let target_id = match target {
168-
MaybeHeader::Header(header) => header.id(),
169-
MaybeHeader::Id(id) => id,
170-
};
171-
RequestV1 {
172-
target_id,
119+
RequestV2 {
120+
target: MaybeHeader::Header(target),
173121
branch_knowledge,
174-
state: state.into(),
122+
state,
175123
}
176124
}
177125
}
178126

179127
impl<J: Justification> Request<J> {
180128
pub fn new(
181-
target: MaybeHeader<UnverifiedHeaderFor<J>>,
129+
target: UnverifiedHeaderFor<J>,
182130
branch_knowledge: BranchKnowledge,
183131
state: State<J>,
184132
) -> Self {
185-
Self {
133+
Request {
186134
target,
187135
branch_knowledge,
188136
state,
@@ -194,7 +142,7 @@ impl<J: Justification> Request<J> {
194142
pub fn state(&self) -> &State<J> {
195143
&self.state
196144
}
197-
pub fn target(&self) -> &MaybeHeader<UnverifiedHeaderFor<J>> {
145+
pub fn target(&self) -> &UnverifiedHeaderFor<J> {
198146
&self.target
199147
}
200148
pub fn branch_knowledge(&self) -> &BranchKnowledge {
@@ -204,27 +152,15 @@ impl<J: Justification> Request<J> {
204152

205153
/// Data that can be used to generate a request given our state.
206154
pub struct PreRequest<UH: UnverifiedHeader, I: PeerId> {
207-
header: MaybeHeader<UH>,
155+
header: UH,
208156
branch_knowledge: BranchKnowledge,
209157
know_most: HashSet<I>,
210158
}
211159

212160
impl<UH: UnverifiedHeader, I: PeerId> PreRequest<UH, I> {
213-
pub fn new_headerless(
214-
id: BlockId,
215-
branch_knowledge: BranchKnowledge,
216-
know_most: HashSet<I>,
217-
) -> Self {
218-
PreRequest {
219-
header: MaybeHeader::Id(id),
220-
branch_knowledge,
221-
know_most,
222-
}
223-
}
224-
225161
pub fn new(header: UH, branch_knowledge: BranchKnowledge, know_most: HashSet<I>) -> Self {
226162
PreRequest {
227-
header: MaybeHeader::Header(header),
163+
header,
228164
branch_knowledge,
229165
know_most,
230166
}
@@ -245,24 +181,26 @@ impl<UH: UnverifiedHeader, I: PeerId> PreRequest<UH, I> {
245181
}
246182
}
247183

248-
/// Data to be sent over the network version 2.
184+
/// Data to be sent over the network, version 3.
249185
#[derive(Clone, Debug, Encode, Decode)]
250-
pub enum NetworkDataV2<B: Block, J: Justification>
186+
pub enum NetworkDataV3<B: Block, J: Justification>
251187
where
252188
J: Justification,
253189
B: Block<UnverifiedHeader = UnverifiedHeaderFor<J>>,
254190
{
255191
/// A periodic state broadcast, so that neighbouring nodes can request what they are missing,
256192
/// send what we are missing, and sometimes just use the justifications to update their own
257193
/// state.
258-
StateBroadcast(StateV1<J>),
194+
StateBroadcast(State<J>),
259195
/// Response to a state broadcast. Contains at most two justifications that the peer will
260196
/// understand.
261197
StateBroadcastResponse(J::Unverified, Option<J::Unverified>),
262198
/// An explicit request for data, potentially a lot of it.
263-
Request(RequestV1<J>),
199+
Request(RequestV2<J>),
264200
/// Response to the request for data.
265201
RequestResponse(ResponseItems<B, J>),
202+
/// A request for a chain extension.
203+
ChainExtensionRequest(State<J>),
266204
}
267205

268206
/// Data to be sent over the network, current version.
@@ -287,42 +225,47 @@ where
287225
ChainExtensionRequest(State<J>),
288226
}
289227

290-
impl<B: Block, J: Justification> From<NetworkDataV2<B, J>> for NetworkData<B, J>
228+
impl<B: Block, J: Justification> TryFrom<NetworkDataV3<B, J>> for NetworkData<B, J>
291229
where
292230
J: Justification,
293231
B: Block<UnverifiedHeader = UnverifiedHeaderFor<J>>,
294232
{
295-
fn from(data: NetworkDataV2<B, J>) -> Self {
296-
match data {
297-
NetworkDataV2::StateBroadcast(state) => NetworkData::StateBroadcast(state.into()),
298-
NetworkDataV2::StateBroadcastResponse(justification, maybe_justification) => {
233+
type Error = ();
234+
235+
fn try_from(data: NetworkDataV3<B, J>) -> Result<Self, Self::Error> {
236+
Ok(match data {
237+
NetworkDataV3::StateBroadcast(state) => NetworkData::StateBroadcast(state),
238+
NetworkDataV3::StateBroadcastResponse(justification, maybe_justification) => {
299239
NetworkData::StateBroadcastResponse(justification, maybe_justification)
300240
}
301-
NetworkDataV2::Request(request) => NetworkData::Request(request.into()),
302-
NetworkDataV2::RequestResponse(response_items) => {
241+
NetworkDataV3::Request(request) => NetworkData::Request(request.try_into()?),
242+
NetworkDataV3::RequestResponse(response_items) => {
303243
NetworkData::RequestResponse(response_items)
304244
}
305-
}
245+
NetworkDataV3::ChainExtensionRequest(state) => {
246+
NetworkData::ChainExtensionRequest(state)
247+
}
248+
})
306249
}
307250
}
308251

309-
impl<B: Block, J: Justification> From<NetworkData<B, J>> for NetworkDataV2<B, J>
252+
impl<B: Block, J: Justification> From<NetworkData<B, J>> for NetworkDataV3<B, J>
310253
where
311254
J: Justification,
312255
B: Block<UnverifiedHeader = UnverifiedHeaderFor<J>>,
313256
{
314257
fn from(data: NetworkData<B, J>) -> Self {
315258
match data {
316-
NetworkData::StateBroadcast(state) => NetworkDataV2::StateBroadcast(state.into()),
259+
NetworkData::StateBroadcast(state) => NetworkDataV3::StateBroadcast(state),
317260
NetworkData::StateBroadcastResponse(justification, maybe_justification) => {
318-
NetworkDataV2::StateBroadcastResponse(justification, maybe_justification)
261+
NetworkDataV3::StateBroadcastResponse(justification, maybe_justification)
319262
}
320-
NetworkData::Request(request) => NetworkDataV2::Request(request.into()),
263+
NetworkData::Request(request) => NetworkDataV3::Request(request.into()),
321264
NetworkData::RequestResponse(response_items) => {
322-
NetworkDataV2::RequestResponse(response_items)
265+
NetworkDataV3::RequestResponse(response_items)
323266
}
324267
NetworkData::ChainExtensionRequest(state) => {
325-
NetworkDataV2::Request(RequestV1::from_state_only(state.into()))
268+
NetworkDataV3::ChainExtensionRequest(state)
326269
}
327270
}
328271
}
@@ -337,8 +280,8 @@ where
337280
{
338281
// Most likely from the future.
339282
Other(Version, Vec<u8>),
340-
V2(NetworkDataV2<B, J>),
341-
V3(NetworkData<B, J>),
283+
V3(NetworkDataV3<B, J>),
284+
V4(NetworkData<B, J>),
342285
}
343286

344287
// We need 32 bits, since blocks can be quite sizeable.
@@ -388,17 +331,17 @@ where
388331
+ byte_count_size
389332
+ match self {
390333
Other(_, payload) => payload.len(),
391-
V2(data) => data.size_hint(),
392334
V3(data) => data.size_hint(),
335+
V4(data) => data.size_hint(),
393336
}
394337
}
395338

396339
fn encode(&self) -> Vec<u8> {
397340
use VersionedNetworkData::*;
398341
match self {
399342
Other(version, payload) => encode_with_version(*version, payload),
400-
V2(data) => encode_with_version(Version(2), &data.encode()),
401343
V3(data) => encode_with_version(Version(3), &data.encode()),
344+
V4(data) => encode_with_version(Version(4), &data.encode()),
402345
}
403346
}
404347
}
@@ -413,8 +356,8 @@ where
413356
let version = Version::decode(input)?;
414357
let num_bytes = ByteCount::decode(input)?;
415358
match version {
416-
Version(2) => Ok(V2(NetworkDataV2::decode(input)?)),
417-
Version(3) => Ok(V3(NetworkData::decode(input)?)),
359+
Version(3) => Ok(V3(NetworkDataV3::decode(input)?)),
360+
Version(4) => Ok(V4(NetworkData::decode(input)?)),
418361
_ => {
419362
if num_bytes > MAX_SYNC_MESSAGE_SIZE {
420363
Err("Sync message has unknown version and is encoded as more than the maximum size.")?;
@@ -469,10 +412,10 @@ where
469412
peer_id: Self::PeerId,
470413
) -> Result<(), Self::Error> {
471414
self.inner.send_to(
472-
VersionedNetworkData::V2(data.clone().into()),
415+
VersionedNetworkData::V3(data.clone().into()),
473416
peer_id.clone(),
474417
)?;
475-
self.inner.send_to(VersionedNetworkData::V3(data), peer_id)
418+
self.inner.send_to(VersionedNetworkData::V4(data), peer_id)
476419
}
477420

478421
fn send_to_random(
@@ -481,17 +424,17 @@ where
481424
peer_ids: HashSet<Self::PeerId>,
482425
) -> Result<(), Self::Error> {
483426
self.inner.send_to_random(
484-
VersionedNetworkData::V2(data.clone().into()),
427+
VersionedNetworkData::V3(data.clone().into()),
485428
peer_ids.clone(),
486429
)?;
487430
self.inner
488-
.send_to_random(VersionedNetworkData::V3(data), peer_ids)
431+
.send_to_random(VersionedNetworkData::V4(data), peer_ids)
489432
}
490433

491434
fn broadcast(&mut self, data: NetworkData<B, J>) -> Result<(), Self::Error> {
492435
self.inner
493-
.broadcast(VersionedNetworkData::V2(data.clone().into()))?;
494-
self.inner.broadcast(VersionedNetworkData::V3(data))
436+
.broadcast(VersionedNetworkData::V3(data.clone().into()))?;
437+
self.inner.broadcast(VersionedNetworkData::V4(data))
495438
}
496439

497440
/// Retrieves next message from the network.
@@ -508,8 +451,14 @@ where
508451
"Received sync data of unsupported version {:?}.", version
509452
)
510453
}
511-
(VersionedNetworkData::V2(data), peer_id) => return Ok((data.into(), peer_id)),
512-
(VersionedNetworkData::V3(data), peer_id) => return Ok((data, peer_id)),
454+
(VersionedNetworkData::V3(data), peer_id) => match data.try_into() {
455+
Ok(data) => return Ok((data, peer_id)),
456+
Err(()) => warn!(
457+
target: LOG_TARGET,
458+
"Received request with no header in target, this should never happen.",
459+
),
460+
},
461+
(VersionedNetworkData::V4(data), peer_id) => return Ok((data, peer_id)),
513462
}
514463
}
515464
}

0 commit comments

Comments
 (0)