1use crate::{
6 message::{Message, MsgId, RequestId},
7 sync::message::Throttled,
8 NodeType,
9};
10use cfx_internal_common::ChainIdParamsOneChainInner;
11use cfx_types::{H160, H256};
12use network::{node_table::NodeId, NetworkContext, UpdateNodeOperation};
13use parking_lot::Mutex;
14use primitives::{account::AccountError, filter::FilterError, StateRoot};
15use rlp::DecoderError;
16use std::sync::Arc;
17use thiserror::Error;
18
19#[derive(Debug, Error)]
20pub enum Error {
21 #[error(transparent)]
22 Network(#[from] network::Error),
23 #[error(transparent)]
24 StateDb(#[from] cfx_statedb::Error),
25 #[error(transparent)]
26 Storage(#[from] cfx_storage::Error),
27 #[error(transparent)]
28 Decoder(#[from] DecoderError),
29 #[error(transparent)]
30 Filter(#[from] FilterError),
31 #[error(transparent)]
32 AccountError(#[from] AccountError),
33 #[error("packet already throttled: {0:?}")]
34 AlreadyThrottled(&'static str),
35 #[error("ChainId mismatch, ours={ours:?}, theirs={theirs:?}.")]
36 ChainIdMismatch {
37 ours: ChainIdParamsOneChainInner,
38 theirs: ChainIdParamsOneChainInner,
39 },
40 #[error("{:?}", .0.display_error())]
41 ClonableErrorWrapper(ClonableError),
42 #[error("Genesis mismatch, ours={ours:?}, theirs={theirs:?}.")]
43 GenesisMismatch { ours: H256, theirs: H256 },
44 #[error("Internal error: {0:?}")]
45 InternalError(String),
46 #[error("Logs bloom hash validation for epoch {epoch} failed, expected={expected:?}, received={received:?}")]
47 InvalidBloom {
48 epoch: u64,
49 expected: H256,
50 received: H256,
51 },
52 #[error("Header verification failed")]
53 InvalidHeader,
54 #[error("Invalid ledger proof size for header {hash:?}: expected={expected}, received={received}")]
55 InvalidLedgerProofSize {
56 hash: H256,
57 expected: u64,
58 received: u64,
59 },
60 #[error("Invalid message format")]
61 InvalidMessageFormat,
62 #[error("Invalid previous state root for epoch {current_epoch} with snapshot epoch count {snapshot_epoch_count}: {root:?}")]
63 InvalidPreviousStateRoot {
64 current_epoch: u64,
65 snapshot_epoch_count: u64,
66 root: Option<StateRoot>,
67 },
68 #[error("Receipts root validation for epoch {epoch} failed, expected={expected:?}, received={received:?}")]
69 InvalidReceipts {
70 epoch: u64,
71 expected: H256,
72 received: H256,
73 },
74 #[error(
75 "Invalid state proof for key {value:?} and value {key:?} in epoch {epoch}: {reason:?}"
76 )]
77 InvalidStateProof {
78 epoch: u64,
79 key: Vec<u8>,
80 value: Option<Vec<u8>>,
81 reason: &'static str,
82 #[source]
83 source: Option<Box<Error>>,
84 },
85 #[error("State root validation for epoch {epoch} failed, expected={expected:?}, received={received:?}")]
86 InvalidStateRoot {
87 epoch: u64,
88 expected: H256,
89 received: H256,
90 },
91 #[error("Invalid storage root proof for address {address:?} in epoch {epoch}: {reason}")]
92 InvalidStorageRootProof {
93 epoch: u64,
94 address: H160,
95 reason: &'static str,
96 #[source]
97 source: Option<Box<Error>>,
98 },
99 #[error("Invalid tx info: {reason:?}")]
100 InvalidTxInfo { reason: String },
101 #[error("Transaction root validation for block {hash:?} failed, expected={expected:?}, received={received:?}")]
102 InvalidTxRoot {
103 hash: H256,
104 expected: H256,
105 received: H256,
106 },
107 #[error("Invalid signature for transaction {hash:?}")]
108 InvalidTxSignature { hash: H256 },
109 #[error("Witness root validation for header {hash:?} failed, expected={expected:?}, received={received:?}")]
110 InvalidWitnessRoot {
111 hash: H256,
112 expected: H256,
113 received: H256,
114 },
115 #[error("Failed to send status to peer {peer:?}")]
116 SendStatusFailed {
117 peer: NodeId,
118 #[source]
119 source: Option<Box<Error>>,
120 },
121 #[error("Operation timeout: {0:?}")]
122 Timeout(String),
123 #[error("packet {0:?} throttled: {1:?}")]
124 Throttled(&'static str, Throttled),
125 #[error("Unable to produce tx info: {reason:?}")]
126 UnableToProduceTxInfo { reason: String },
127 #[error(
128 "Unexpected message id={received:?}, expected one of {expected:?}"
129 )]
130 UnexpectedMessage {
131 expected: Vec<MsgId>,
132 received: MsgId,
133 },
134 #[error("Unexpected peer type: {node_type:?}")]
135 UnexpectedPeerType { node_type: NodeType },
136 #[error("Unexpected response id; expected = {expected:?}, received = {received:?}")]
137 UnexpectedResponse {
138 expected: Option<RequestId>,
139 received: RequestId,
140 },
141 #[error("Unknown message: {id:?}")]
142 UnknownMessage { id: MsgId },
143 #[error("Witness for epoch {epoch} is not available")]
144 WitnessUnavailable { epoch: u64 },
145 #[error("{0}")]
146 Msg(String),
147}
148
149pub type Result<T> = std::result::Result<T, Error>;
150
151pub fn handle(
152 io: &dyn NetworkContext, peer: &NodeId, msg_id: MsgId, e: &Error,
153) {
154 if !matches!(e, Error::ClonableErrorWrapper(_)) {
156 warn!(
157 "Error while handling message, peer={}, msg_id={:?}, error={}",
158 peer, msg_id, e,
159 );
160 }
161
162 let mut disconnect = true;
163 let reason = format!("{}", e);
164 let mut op = None;
165
166 match &e {
169 Error::ClonableErrorWrapper(e) => {
171 handle(io, peer, msg_id, &*e.0.lock());
172
173 disconnect = false
175 }
176
177 Error::Filter(_)
178 | Error::InternalError(_)
179
180 | Error::Msg(_)
183
184 | Error::SendStatusFailed{..}
187
188 | Error::Timeout(_)
189
190 | Error::UnableToProduceTxInfo{..}
193
194 | Error::WitnessUnavailable{..}
197
198 | Error::UnknownMessage{..} => disconnect = false,
201
202
203 Error::GenesisMismatch{..}
204 | Error::InvalidHeader
205 | Error::ChainIdMismatch{..}
206 | Error::UnexpectedMessage{..}
207 | Error::UnexpectedPeerType{..} => op = Some(UpdateNodeOperation::Failure),
208
209 Error::UnexpectedResponse{..} => {
210 op = Some(UpdateNodeOperation::Demotion)
211 }
212
213 Error::InvalidBloom{..}
214 | Error::InvalidLedgerProofSize{..}
215 | Error::InvalidMessageFormat
216 | Error::InvalidPreviousStateRoot{..}
217 | Error::InvalidReceipts{..}
218 | Error::InvalidStateProof{..}
219 | Error::InvalidStateRoot{..}
220 | Error::InvalidStorageRootProof{..}
221 | Error::InvalidTxInfo{..}
222 | Error::InvalidTxRoot{..}
223 | Error::InvalidTxSignature{..}
224 | Error::InvalidWitnessRoot{..}
225 | Error::AlreadyThrottled(_)
226 | Error::Decoder(_)
227 | Error::AccountError(_) => op = Some(UpdateNodeOperation::Remove),
228
229 Error::Throttled(_, resp) => {
230 disconnect = false;
231
232 if let Err(e) = resp.send(io, peer) {
233 error!("failed to send throttled packet: {:?}", e);
234 disconnect = true;
235 }
236 }
237
238 Error::Network(kind) => match kind {
240 network::Error::SendUnsupportedMessage{..} => {
241 unreachable!("This is a bug in protocol version maintenance. {:?}", kind);
242 }
243
244 network::Error::MessageDeprecated{..} => {
245 op = Some(UpdateNodeOperation::Failure);
246 error!(
247 "Peer sent us a deprecated message {:?}. Either it's a bug \
248 in protocol version maintenance or the peer is malicious.",
249 kind,
250 );
251 }
252
253 network::Error::AddressParse
254 | network::Error::AddressResolve(_)
255 | network::Error::Auth
256 | network::Error::BadAddr
257 | network::Error::Disconnect(_)
258 | network::Error::Expired
259 | network::Error::InvalidNodeId
260 | network::Error::Io(_)
261 | network::Error::OversizedPacket
262 | network::Error::Throttling(_) => disconnect = false,
263
264 network::Error::BadProtocol | network::Error::Decoder(_) => {
265 op = Some(UpdateNodeOperation::Remove)
266 }
267
268 network::Error::SocketIo(_) | network::Error::Msg(_) => {
269 op = Some(UpdateNodeOperation::Failure)
270 }
271 },
272
273 Error::StateDb(_)| Error::Storage(_) => disconnect = false,
274
275 };
279
280 if disconnect {
281 io.disconnect_peer(peer, op, reason.as_str());
282 }
283}
284
285#[derive(Clone, Debug)]
286pub struct ClonableError(Arc<Mutex<Error>>);
287
288impl Into<Error> for ClonableError {
289 fn into(self) -> Error { Error::ClonableErrorWrapper(self).into() }
290}
291
292impl From<Error> for ClonableError {
293 fn from(e: Error) -> ClonableError {
294 ClonableError(Arc::new(Mutex::new(e)))
295 }
296}
297
298impl ClonableError {
299 fn display_error(&self) -> String { self.0.lock().to_string() }
300}
301
302impl From<&str> for Error {
303 fn from(e: &str) -> Self { Error::Msg(e.into()) }
304}
305impl From<String> for Error {
306 fn from(e: String) -> Self { Error::Msg(e) }
307}