Decode refuse reason in handshake
This commit is contained in:
parent
65144ce14b
commit
9d534a6cbb
3 changed files with 79 additions and 79 deletions
|
|
@ -1,5 +1,5 @@
|
|||
use itertools::Itertools;
|
||||
use pallas_machines::{DecodePayload, EncodePayload, PayloadEncoder};
|
||||
use pallas_machines::{DecodePayload, EncodePayload, MachineError, PayloadEncoder};
|
||||
use std::{collections::HashMap, fmt::Debug};
|
||||
|
||||
pub const TESTNET_MAGIC: u64 = 1097911063;
|
||||
|
|
@ -17,10 +17,7 @@ impl<T> EncodePayload for VersionTable<T>
|
|||
where
|
||||
T: Debug + Clone + EncodePayload + DecodePayload,
|
||||
{
|
||||
fn encode_payload(
|
||||
&self,
|
||||
e: &mut PayloadEncoder,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box<dyn std::error::Error>> {
|
||||
e.map(self.values.len() as u64)?;
|
||||
|
||||
for key in self.values.keys().sorted() {
|
||||
|
|
@ -44,10 +41,7 @@ pub enum RefuseReason {
|
|||
}
|
||||
|
||||
impl EncodePayload for RefuseReason {
|
||||
fn encode_payload(
|
||||
&self,
|
||||
e: &mut PayloadEncoder,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box<dyn std::error::Error>> {
|
||||
match self {
|
||||
RefuseReason::VersionMismatch(versions) => {
|
||||
e.array(2)?;
|
||||
|
|
@ -69,7 +63,7 @@ impl EncodePayload for RefuseReason {
|
|||
}
|
||||
RefuseReason::Refused(version, msg) => {
|
||||
e.array(3)?;
|
||||
e.u16(1)?;
|
||||
e.u16(2)?;
|
||||
e.u64(*version)?;
|
||||
e.str(msg)?;
|
||||
|
||||
|
|
@ -78,3 +72,32 @@ impl EncodePayload for RefuseReason {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl DecodePayload for RefuseReason {
|
||||
fn decode_payload(
|
||||
d: &mut pallas_machines::PayloadDecoder,
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
d.array()?;
|
||||
|
||||
match d.u16()? {
|
||||
0 => {
|
||||
let versions = d.array_iter::<u64>()?;
|
||||
let versions = versions.try_collect()?;
|
||||
Ok(RefuseReason::VersionMismatch(versions))
|
||||
}
|
||||
1 => {
|
||||
let version = d.u64()?;
|
||||
let msg = d.str()?;
|
||||
|
||||
Ok(RefuseReason::HandshakeDecodeError(version, msg.to_string()))
|
||||
}
|
||||
2 => {
|
||||
let version = d.u64()?;
|
||||
let msg = d.str()?;
|
||||
|
||||
Ok(RefuseReason::Refused(version, msg.to_string()))
|
||||
}
|
||||
x => Err(Box::new(MachineError::BadLabel(x))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
use core::panic;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use itertools::Merge;
|
||||
use pallas_machines::{
|
||||
Agent, DecodePayload, EncodePayload, MachineError, MachineOutput,
|
||||
PayloadDecoder, PayloadEncoder,
|
||||
Agent, DecodePayload, EncodePayload, MachineError, MachineOutput, PayloadDecoder,
|
||||
PayloadEncoder,
|
||||
};
|
||||
|
||||
use crate::common::{NetworkMagic, RefuseReason, VersionNumber};
|
||||
|
|
@ -42,13 +43,10 @@ impl VersionTable {
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VersionData (NetworkMagic,);
|
||||
pub struct VersionData(NetworkMagic);
|
||||
|
||||
impl EncodePayload for VersionData {
|
||||
fn encode_payload(
|
||||
&self,
|
||||
e: &mut PayloadEncoder,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box<dyn std::error::Error>> {
|
||||
e.u64(self.0)?;
|
||||
|
||||
Ok(())
|
||||
|
|
@ -56,9 +54,7 @@ impl EncodePayload for VersionData {
|
|||
}
|
||||
|
||||
impl DecodePayload for VersionData {
|
||||
fn decode_payload(
|
||||
d: &mut PayloadDecoder,
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
fn decode_payload(d: &mut PayloadDecoder) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
let network_magic = d.u64()?;
|
||||
|
||||
Ok(Self(network_magic))
|
||||
|
|
@ -73,10 +69,7 @@ pub enum Message {
|
|||
}
|
||||
|
||||
impl EncodePayload for Message {
|
||||
fn encode_payload(
|
||||
&self,
|
||||
e: &mut PayloadEncoder,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box<dyn std::error::Error>> {
|
||||
match self {
|
||||
Message::Propose(version_table) => {
|
||||
e.array(2)?.u16(0)?;
|
||||
|
|
@ -98,24 +91,22 @@ impl EncodePayload for Message {
|
|||
}
|
||||
|
||||
impl DecodePayload for Message {
|
||||
fn decode_payload(
|
||||
d: &mut PayloadDecoder,
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
fn decode_payload(d: &mut PayloadDecoder) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
d.array()?;
|
||||
|
||||
let msg = match d.u16()? {
|
||||
match d.u16()? {
|
||||
0 => todo!(),
|
||||
1 => {
|
||||
let version_number = d.u64()?;
|
||||
let version_data = VersionData::decode_payload(d)?;
|
||||
|
||||
Message::Accept(version_number, version_data)
|
||||
Ok(Message::Accept(version_number, version_data))
|
||||
}
|
||||
2 => todo!(),
|
||||
x => return Err(Box::new(MachineError::BadLabel(x))),
|
||||
};
|
||||
|
||||
Ok(msg)
|
||||
2 => {
|
||||
let reason = RefuseReason::decode_payload(d)?;
|
||||
Ok(Message::Refuse(reason))
|
||||
}
|
||||
x => Err(Box::new(MachineError::BadLabel(x))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -165,10 +156,7 @@ impl Agent for Client {
|
|||
}
|
||||
}
|
||||
|
||||
fn send_next(
|
||||
self,
|
||||
tx: &impl MachineOutput,
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
fn send_next(self, tx: &impl MachineOutput) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
match self.state {
|
||||
State::Propose => {
|
||||
tx.send_msg(&Message::Propose(self.version_table.clone()))?;
|
||||
|
|
@ -182,10 +170,7 @@ impl Agent for Client {
|
|||
}
|
||||
}
|
||||
|
||||
fn receive_next(
|
||||
self,
|
||||
msg: Self::Message,
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
fn receive_next(self, msg: Self::Message) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
match (self.state, msg) {
|
||||
(State::Confirm, Message::Accept(version, data)) => Ok(Self {
|
||||
state: State::Done,
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ use core::panic;
|
|||
use std::collections::HashMap;
|
||||
|
||||
use pallas_machines::{
|
||||
Agent, DecodePayload, EncodePayload, MachineError, MachineOutput,
|
||||
PayloadDecoder, PayloadEncoder,
|
||||
Agent, DecodePayload, EncodePayload, MachineError, MachineOutput, PayloadDecoder,
|
||||
PayloadEncoder,
|
||||
};
|
||||
|
||||
use crate::common::{RefuseReason, VersionNumber};
|
||||
|
|
@ -28,6 +28,17 @@ impl VersionTable {
|
|||
|
||||
VersionTable { values }
|
||||
}
|
||||
|
||||
pub fn v6_and_above(network_magic: u64) -> VersionTable {
|
||||
let values = vec![
|
||||
(PROTOCOL_V6, VersionData::new(network_magic, false)),
|
||||
(PROTOCOL_V7, VersionData::new(network_magic, false)),
|
||||
]
|
||||
.into_iter()
|
||||
.collect::<HashMap<u64, VersionData>>();
|
||||
|
||||
VersionTable { values }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -37,10 +48,7 @@ pub struct VersionData {
|
|||
}
|
||||
|
||||
impl VersionData {
|
||||
pub fn new(
|
||||
network_magic: u64,
|
||||
initiator_and_responder_diffusion_mode: bool,
|
||||
) -> Self {
|
||||
pub fn new(network_magic: u64, initiator_and_responder_diffusion_mode: bool) -> Self {
|
||||
VersionData {
|
||||
network_magic,
|
||||
initiator_and_responder_diffusion_mode,
|
||||
|
|
@ -49,10 +57,7 @@ impl VersionData {
|
|||
}
|
||||
|
||||
impl EncodePayload for VersionData {
|
||||
fn encode_payload(
|
||||
&self,
|
||||
e: &mut PayloadEncoder,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box<dyn std::error::Error>> {
|
||||
e.array(2)?
|
||||
.u64(self.network_magic)?
|
||||
.bool(self.initiator_and_responder_diffusion_mode)?;
|
||||
|
|
@ -62,9 +67,7 @@ impl EncodePayload for VersionData {
|
|||
}
|
||||
|
||||
impl DecodePayload for VersionData {
|
||||
fn decode_payload(
|
||||
d: &mut PayloadDecoder,
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
fn decode_payload(d: &mut PayloadDecoder) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
d.array()?;
|
||||
let network_magic = d.u64()?;
|
||||
let initiator_and_responder_diffusion_mode = d.bool()?;
|
||||
|
|
@ -84,10 +87,7 @@ pub enum Message {
|
|||
}
|
||||
|
||||
impl EncodePayload for Message {
|
||||
fn encode_payload(
|
||||
&self,
|
||||
e: &mut PayloadEncoder,
|
||||
) -> Result<(), Box<dyn std::error::Error>> {
|
||||
fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box<dyn std::error::Error>> {
|
||||
match self {
|
||||
Message::Propose(version_table) => {
|
||||
e.array(2)?.u16(0)?;
|
||||
|
|
@ -109,24 +109,22 @@ impl EncodePayload for Message {
|
|||
}
|
||||
|
||||
impl DecodePayload for Message {
|
||||
fn decode_payload(
|
||||
d: &mut PayloadDecoder,
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
fn decode_payload(d: &mut PayloadDecoder) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
d.array()?;
|
||||
|
||||
let msg = match d.u16()? {
|
||||
match d.u16()? {
|
||||
0 => todo!(),
|
||||
1 => {
|
||||
let version_number = d.u64()?;
|
||||
let version_data = VersionData::decode_payload(d)?;
|
||||
|
||||
Message::Accept(version_number, version_data)
|
||||
Ok(Message::Accept(version_number, version_data))
|
||||
}
|
||||
2 => todo!(),
|
||||
x => return Err(Box::new(MachineError::BadLabel(x))),
|
||||
};
|
||||
|
||||
Ok(msg)
|
||||
2 => {
|
||||
let reason = RefuseReason::decode_payload(d)?;
|
||||
Ok(Message::Refuse(reason))
|
||||
}
|
||||
x => Err(Box::new(MachineError::BadLabel(x))),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -176,10 +174,7 @@ impl Agent for Client {
|
|||
}
|
||||
}
|
||||
|
||||
fn send_next(
|
||||
self,
|
||||
tx: &impl MachineOutput,
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
fn send_next(self, tx: &impl MachineOutput) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
match self.state {
|
||||
State::Propose => {
|
||||
tx.send_msg(&Message::Propose(self.version_table.clone()))?;
|
||||
|
|
@ -193,10 +188,7 @@ impl Agent for Client {
|
|||
}
|
||||
}
|
||||
|
||||
fn receive_next(
|
||||
self,
|
||||
msg: Self::Message,
|
||||
) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
fn receive_next(self, msg: Self::Message) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
match (self.state, msg) {
|
||||
(State::Confirm, Message::Accept(version, data)) => Ok(Self {
|
||||
state: State::Done,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue