amaru_protocols/handshake/
mod.rs1mod initiator;
16mod messages;
17mod responder;
18#[cfg(test)]
19mod tests;
20
21use amaru_kernel::NetworkMagic;
22pub use messages::Message;
23
24use crate::{
25 protocol::{ProtoSpec, ProtocolState, Role, RoleT},
26 protocol_messages::{
27 handshake::{HandshakeResult, RefuseReason},
28 version_data::{PEER_SHARING_DISABLED, VersionData},
29 version_number::VersionNumber,
30 version_table::VersionTable,
31 },
32};
33
34pub fn register_deserializers() -> pure_stage::DeserializerGuards {
35 vec![initiator::register_deserializers(), responder::register_deserializers()].into_iter().flatten().collect()
36}
37
38#[derive(Debug, PartialEq, Eq, Clone, Copy, PartialOrd, Ord, serde::Serialize, serde::Deserialize)]
39pub enum State {
40 Propose,
41 Confirm,
42 Done,
43}
44
45pub use initiator::{HandshakeInitiator, initiator};
47pub use responder::{HandshakeResponder, responder};
48
49pub fn compute_negotiation_result(
51 _role: Role,
52 ours: VersionTable<VersionData>,
53 theirs: VersionTable<VersionData>,
54) -> HandshakeResult {
55 use crate::protocol_messages::handshake::RefuseReason;
56 let mut their_versions = theirs.values.keys().collect::<Vec<_>>();
57 their_versions.sort();
58 their_versions.reverse();
59 for their_version in their_versions {
60 if let Some(our_version) = ours.values.get(their_version) {
61 return HandshakeResult::Accepted(*their_version, our_version.clone());
62 }
63 }
64 HandshakeResult::Refused(RefuseReason::VersionMismatch(ours.values.keys().copied().collect()))
65}
66
67pub fn spec<R: RoleT>() -> ProtoSpec<State, Message<VersionData>, R>
68where
69 State: ProtocolState<R, WireMsg = Message<VersionData>>,
70{
71 use State::*;
72
73 let mut spec = ProtoSpec::default();
74
75 let propose = || Message::Propose(VersionTable::empty());
76 let accept = || {
77 Message::Accept(
78 VersionNumber::V14,
79 VersionData::new(NetworkMagic::MAINNET, false, PEER_SHARING_DISABLED, false),
80 )
81 };
82 let refuse = || Message::Refuse(RefuseReason::VersionMismatch(vec![VersionNumber::V14]));
83 let query_reply = || Message::QueryReply(VersionTable::empty());
84
85 spec.init(Propose, propose(), Confirm);
86 spec.sim_open(Confirm, propose(), Done);
87 spec.resp(Confirm, accept(), Done);
88 spec.resp(Confirm, refuse(), Done);
89 spec.resp(Confirm, query_reply(), Done);
90 spec
91}