jam_std_common/safrole/
ticket.rs

1//! Types related to tickets.
2
3use crate::{bandersnatch::ring_vrf, Entropy, EpochPeriod, TicketAttempt};
4use bounded_collections::BoundedVec;
5use jam_types::opaque;
6use scale::{Decode, Encode, MaxEncodedLen};
7
8// Ticket identifier.
9//
10// Output of a VRF whose inputs cannot be controlled by the
11// ticket's creator (refer to [`super::vrf::ticket_id_input`] parameters).
12//
13// The value is used as the ticket score to decide if the ticket is worth being considered.
14opaque! { pub struct TicketId(pub [u8; 32]); }
15
16impl TicketId {
17	pub fn from(entropy: Entropy) -> TicketId {
18		TicketId(*entropy)
19	}
20}
21
22/// Ticket data on-chain.
23#[derive(Debug, Copy, Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen)]
24pub struct TicketBody {
25	/// Ticket identifier
26	pub id: TicketId,
27	/// Attempt index.
28	pub attempt: TicketAttempt,
29}
30
31impl Ord for TicketBody {
32	fn cmp(&self, other: &Self) -> core::cmp::Ordering {
33		self.id.cmp(&other.id)
34	}
35}
36
37impl PartialOrd for TicketBody {
38	fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
39		Some(self.cmp(other))
40	}
41}
42
43/// Ticket ring vrf signature.
44pub type TicketSignature = ring_vrf::Signature;
45
46/// Ticket envelope used during submission.
47#[derive(Debug, Clone, PartialEq, Eq, Encode, Decode, MaxEncodedLen)]
48pub struct TicketEnvelope {
49	/// Ticket attempt.
50	pub attempt: TicketAttempt,
51	/// Ring signature of the ticket `body`.
52	pub signature: TicketSignature,
53}
54
55impl Ord for TicketEnvelope {
56	fn cmp(&self, other: &Self) -> core::cmp::Ordering {
57		self.id().cmp(&other.id())
58	}
59}
60
61impl PartialOrd for TicketEnvelope {
62	fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
63		Some(self.cmp(other))
64	}
65}
66
67impl TicketEnvelope {
68	/// Construct [`TicketId`] from [`TicketEnvelope`] signature.
69	pub fn id(&self) -> TicketId {
70		TicketId::from(self.signature.vrf_output())
71	}
72
73	/// Construct [`TicketBody`] from [`TicketEnvelope`] signature.
74	pub fn body(&self) -> TicketBody {
75		TicketBody { id: self.id(), attempt: self.attempt }
76	}
77}
78
79/// A collection of ticket bodies.
80pub type TicketBodies = BoundedVec<TicketBody, EpochPeriod>;