jam_std_common/safrole/
ticket.rs1use crate::{bandersnatch::ring_vrf, Entropy};
4use bounded_collections::BoundedVec;
5use codec::{Decode, Encode, MaxEncodedLen};
6use jam_types::{opaque, EpochPeriod, TicketAttempt};
7
8opaque! { pub struct TicketId(pub [u8; 32]); }
15
16impl TicketId {
17 pub fn from(entropy: Entropy) -> TicketId {
18 TicketId(*entropy)
19 }
20}
21
22#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen)]
24pub struct TicketBody {
25 pub id: TicketId,
27 #[codec(compact)]
29 pub attempt: TicketAttempt,
30}
31
32impl Ord for TicketBody {
33 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
34 self.id.cmp(&other.id)
35 }
36}
37
38impl PartialOrd for TicketBody {
39 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
40 Some(self.cmp(other))
41 }
42}
43
44pub type TicketSignature = ring_vrf::Signature;
46
47#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen)]
49pub struct TicketEnvelope {
50 #[codec(compact)]
52 pub attempt: TicketAttempt,
53 pub signature: TicketSignature,
55}
56
57impl Ord for TicketEnvelope {
58 fn cmp(&self, other: &Self) -> core::cmp::Ordering {
59 self.id().cmp(&other.id())
60 }
61}
62
63impl PartialOrd for TicketEnvelope {
64 fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
65 Some(self.cmp(other))
66 }
67}
68
69impl TicketEnvelope {
70 pub fn id(&self) -> TicketId {
72 TicketId::from(self.signature.vrf_output())
73 }
74
75 pub fn body(&self) -> TicketBody {
77 TicketBody { id: self.id(), attempt: self.attempt }
78 }
79}
80
81pub type TicketBodies = BoundedVec<TicketBody, EpochPeriod>;