Skip to main content

thruput_xdr/
retrocausal_queue.rs

1// -*-Rust-*-
2// Generated Code: DO NOT CHECK IN
3
4// Generated from xdrc commit: 6ab835b07c234abb4b0b50b61d687904727a4f32
5
6#![allow(non_camel_case_types)]
7#![allow(non_snake_case)]
8#![allow(non_upper_case_globals)]
9#![allow(unused_imports)]
10#![allow(dead_code)]
11#![allow(unused_variables)]
12#![allow(clippy::unnecessary_cast)]
13
14use crate::*;
15use core::option::Option;
16use core::ops::{Deref, DerefMut};
17
18#[cfg(feature = "std")]
19use std::io::{Read, Write};
20#[cfg(feature = "xdrs")]
21use xdrs::*;
22
23
24#[cfg(feature = "serde")]
25use ::serde::{{Serialize, Deserialize}};
26
27
28
29// clang-format on
30
31pub const kQueueEntryMaxLen : u32 = 256;
32
33// 
34#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
35#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
36#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
37#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
38#[repr(transparent)]
39#[cfg_attr(feature = "serde", serde(transparent))]
40pub struct QueueEntry {
41    inner: BytesM<kQueueEntryMaxLen>,
42}
43impl From<BytesM<kQueueEntryMaxLen>> for QueueEntry {
44    fn from(_inner: BytesM<kQueueEntryMaxLen>) -> Self {
45        Self { inner: _inner }
46    }
47}
48impl QueueEntry {
49    pub fn into_inner(self) -> BytesM<kQueueEntryMaxLen> {
50        self.inner
51    }
52    pub const fn new(_inner: BytesM<kQueueEntryMaxLen>) -> Self {
53        Self { inner: _inner }
54    }
55}
56
57impl Deref for QueueEntry {
58    type Target = BytesM<kQueueEntryMaxLen>;
59
60    fn deref(&self) -> &Self::Target {
61        &self.inner
62    }
63}
64impl DerefMut for QueueEntry {
65    fn deref_mut(&mut self) -> &mut Self::Target {
66        &mut self.inner
67    }
68}
69
70/// Per-transaction cap on the number of concurrent RetrocausalQueue entries a
71/// transaction may observe (peek/consume) and record in its
72/// NondeterministicProposalData. Each observation is proposer-controlled and
73/// must be buffered and validated against an insert, so an unbounded count is
74/// an unbounded memory/compute vector — this is a tx resource limit in the same
75/// family as gas, not an RPC artifact. Because it is a tx-observable count
76/// checked against this protocol constant, the limit is consensus-uniform
77/// (every node agrees on "<= cap reads") and independent of any RPC buffer size.
78pub const kMaxConcurrentRcqReadsPerTx : u32 = 16384;
79
80/// Maximum number of entries in a single RetrocausalQueue block.
81/// Each entry is at most 256 bytes. With XDR serialization overhead (4 bytes
82/// per entry length prefix, 12 bytes framing), storage key overhead (73 bytes),
83/// and item header (24 bytes), 250 entries of 256 bytes fits within the
84/// storage engine's 64 KiB item limit.
85pub const kRetrocausalQueueBlockEntriesMaxLen : u32 = 250;
86
87// A block in a retrocausal queue, containing a list of entries and a block
88// number The entries are stored in lexicographically sorted order within the
89// block Block numbers are monotonically increasing
90#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
91#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
92#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
93#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
94#[repr(C)]
95pub struct RetrocausalQueueBlock {
96    // Variable-length array of queue entries
97    pub entries: VecM<QueueEntry>,
98    // Unique identifier and ordering for this block
99    pub block_number: u64,
100}
101
102// This delta consumes all of the retrocausal queue entries
103// in blocks less than or equal to max_fully_consumed_block_number,
104// and removes the first partial_consumed_number entries from the
105// block number max_fully_consumed_block_number + 1.
106#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
107#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
108#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
109#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
110#[repr(C)]
111pub struct RetrocausalQueuePastBlockConsumeDelta {
112    pub max_fully_consumed_block_number: u64,
113    pub partial_consumed_number: u64,
114}
115
116// Root metadata for a Retrocausal Queue, stored at the item key.
117// Tracks both head (consume state) and tail (production state).
118#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
119#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
120#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
121#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
122#[repr(C)]
123pub struct RetrocausalQueueMetadata {
124    // Current consume state - where consumption left off.
125    pub consume_state: RetrocausalQueuePastBlockConsumeDelta,
126    // The highest block number currently live (written and not fully consumed).
127    // New blocks will be numbered max_live_block_num + 1.
128    // 0 if no blocks have been produced yet.
129    pub max_live_block_num: u64,
130    // Total number of entries currently live in the queue (for cost calculation).
131    pub live_entries: u64,
132}
133
134#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
135#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
136#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
137#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
138#[repr(C)]
139pub struct RetrocausalQueueConsumeDelta {
140    pub past_block_consume: RetrocausalQueuePastBlockConsumeDelta,
141    pub current_block_consumed: VecM<QueueEntry, kRetrocausalQueueBlockEntriesMaxLen>,
142}
143
144#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
145#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
146#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
147#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
148#[repr(C)]
149pub struct RetrocausalQueueInsertDelta {
150    pub added_entries: VecM<QueueEntry, kRetrocausalQueueBlockEntriesMaxLen>,
151}
152
153#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
154#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
155#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
156#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
157#[repr(C)]
158pub struct RetrocausalQueueDelta {
159    // set to null if no entries are consumed.
160    // This version of the retrocausal queue is single-consumer multi-producer.
161    pub consume: Option<RetrocausalQueueConsumeDelta>,
162    pub insert: RetrocausalQueueInsertDelta,
163    // Concurrent entries observed (e.g. via peek) but not consumed.
164    // The db validates that each entry was actually inserted by a concurrent
165    // transaction. Unlike current_block_consumed, these do not decrement the
166    // insert balance — they only require that a matching insert exists.
167    //
168    // This is bounded by the per-transaction observation cap
169    // (kMaxConcurrentRcqReadsPerTx), not the much smaller per-block entry cap
170    // (kRetrocausalQueueBlockEntriesMaxLen), for a non-obvious reason: when a
171    // validator replays a proposed block, the executor rebuilds this per-queue
172    // array from the proposer-supplied observation list, and a dishonest proposer
173    // can pack a whole transaction's observations into a single queue. The bogus
174    // entries are caught afterward (the db matches each observed entry to a real
175    // insert), but the array must be built before that check runs -- so it has to
176    // hold a full transaction's worth. Capping it at the per-block size would make
177    // that rebuild overflow and crash the validator instead of cleanly rejecting.
178    pub observed_concurrent_entries: VecM<QueueEntry, kMaxConcurrentRcqReadsPerTx>,
179}
180
181
182//
183// XDR internals below this point
184//
185
186