1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use itertools::Itertools;
use pallas_machines::{CodecError, DecodePayload, EncodePayload, PayloadEncoder};
use std::{collections::HashMap, fmt::Debug};
pub const TESTNET_MAGIC: u64 = 1097911063;
pub const MAINNET_MAGIC: u64 = 764824073;
#[derive(Debug, Clone)]
pub struct VersionTable<T>
where
T: Debug + Clone + EncodePayload + DecodePayload,
{
pub values: HashMap<u64, T>,
}
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>> {
e.map(self.values.len() as u64)?;
for key in self.values.keys().sorted() {
e.u64(*key)?;
self.values[key].encode_payload(e)?;
}
Ok(())
}
}
pub type NetworkMagic = u64;
pub type VersionNumber = u64;
#[derive(Debug)]
pub enum RefuseReason {
VersionMismatch(Vec<VersionNumber>),
HandshakeDecodeError(VersionNumber, String),
Refused(VersionNumber, String),
}
impl EncodePayload for RefuseReason {
fn encode_payload(&self, e: &mut PayloadEncoder) -> Result<(), Box<dyn std::error::Error>> {
match self {
RefuseReason::VersionMismatch(versions) => {
e.array(2)?;
e.u16(0)?;
e.array(versions.len() as u64)?;
for v in versions.iter() {
e.u64(*v)?;
}
Ok(())
}
RefuseReason::HandshakeDecodeError(version, msg) => {
e.array(3)?;
e.u16(1)?;
e.u64(*version)?;
e.str(msg)?;
Ok(())
}
RefuseReason::Refused(version, msg) => {
e.array(3)?;
e.u16(2)?;
e.u64(*version)?;
e.str(msg)?;
Ok(())
}
}
}
}
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(CodecError::BadLabel(x))),
}
}
}