cfxcore/sync/message/
snapshot_chunk_response.rs

1// Copyright 2019 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4
5use crate::{
6    message::{GetMaybeRequestId, Message, MessageProtocolVersionBound, MsgId},
7    sync::{
8        message::{msgid, Context, Handleable, SnapshotChunkRequest},
9        state::storage::Chunk,
10        Error, SYNC_PROTO_V1, SYNC_PROTO_V3,
11    },
12};
13use network::service::ProtocolVersion;
14use rlp::Encodable;
15use rlp_derive::{RlpDecodable, RlpEncodable};
16
17#[derive(RlpDecodable, RlpEncodable)]
18pub struct SnapshotChunkResponse {
19    pub request_id: u64,
20    pub chunk: Chunk,
21}
22
23build_msg_impl! {
24    SnapshotChunkResponse, msgid::GET_SNAPSHOT_CHUNK_RESPONSE,
25    "SnapshotChunkResponse", SYNC_PROTO_V1, SYNC_PROTO_V3
26}
27
28impl Handleable for SnapshotChunkResponse {
29    fn handle(self, ctx: &Context) -> Result<(), Error> {
30        let message = ctx.match_request(self.request_id)?;
31
32        let request = message.downcast_ref::<SnapshotChunkRequest>(
33            ctx.io,
34            &ctx.manager.request_manager,
35        )?;
36
37        debug!(
38            "handle_snapshot_chunk_response key={:?} chunk_len={}",
39            request.chunk_key,
40            self.chunk.keys.len()
41        );
42
43        if let Err(e) = self.chunk.validate(&request.chunk_key) {
44            debug!("failed to validate the snapshot chunk, error = {}", e);
45            // TODO: is the "other" peer guaranteed to have the chunk?
46            // How did we pass the peer list?
47            ctx.manager
48                .request_manager
49                .resend_request_to_another_peer(ctx.io, &message);
50            return Err(e);
51        }
52
53        ctx.manager.state_sync.handle_snapshot_chunk_response(
54            ctx,
55            request.chunk_key.clone(),
56            self.chunk,
57        )?;
58
59        Ok(())
60    }
61}