thruput-xdr 0.63.0

Bindings for Thruput protocol structures
Documentation
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
// -*-Rust-*-
// Generated Code: DO NOT CHECK IN

// Generated from xdrc commit: 6ab835b07c234abb4b0b50b61d687904727a4f32

#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
#![allow(unused_imports)]
#![allow(dead_code)]
#![allow(unused_variables)]
#![allow(clippy::unnecessary_cast)]

use crate::*;
use core::option::Option;
use core::ops::{Deref, DerefMut};

#[cfg(feature = "std")]
use std::io::{Read, Write};
#[cfg(feature = "xdrs")]
use xdrs::*;


#[cfg(feature = "serde")]
use ::serde::{{Serialize, Deserialize}};



// clang-format on

//==============================================================================
// Transactions and Invocations
//
// This module defines the transaction model for Thruput. Transactions are
// the fundamental unit of state modification in the system.
//
// Key concepts:
// - Each transaction invokes a contract method with specified parameters
// - Transactions include authorization claims and signatures
// - Transactions can deploy new contracts
// - Thruput executes transactions in parallel, using two-phase commit for conflict resolution
// - Proposers attach nondeterministic data to ensure deterministic re-execution
//
// Transaction lifecycle:
// 1. User constructs a Transaction with invocation details, auth claims, etc.
// 2. Signatures are added to create a SignedTransaction
// 3. Transaction is submitted to the network
// 4. A proposer executes the transaction and captures nondeterministic data
// 5. Proposer creates a ProposedTransaction and includes it in a block proposal
// 6. Validators re-execute using the nondeterministic data to verify correctness
//==============================================================================

//------------------------------------------------------------------------------
// Call Data and Return Values
//------------------------------------------------------------------------------

/// Opaque encoded call arguments passed to a contract invocation.
///
/// Contracts can encode calldata arbitrarily, but the SDKs encode a tuple or
/// struct of the method's parameters in CXS (compact XDR serialization), a
/// variant of RFC 4506 XDR without 4-byte padding and with variable-length
/// integers, lengths and discriminants.
pub type Calldata = BytesM;

/// Opaque encoded return value from a contract invocation.
///
/// Like Calldata, contracts can encode return values arbitrarily, but the
/// SDKs use CXS.
///
/// Unbounded here, as `Calldata` is: what a chain permits is stated by
/// `kConfigParamMaxReturnBufferLen` and enforced where the Return syscall
/// writes one, rather than where one is decoded. Nothing decodes a buffer
/// the local executor did not just build, so a bound here would constrain
/// what a configuration may state without guarding anything.
pub type ReturnBuffer = BytesM;

//------------------------------------------------------------------------------
// Invocations
//------------------------------------------------------------------------------

/// Specifies a contract method invocation with its parameters.
///
/// This struct is used both for the root transaction invocation and for
/// subinvocations made via the Invoke syscall.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(C)]
pub struct Invocation {
    /// Address of the contract to invoke.
    pub invoked_address: ContractAddress,
    /// 8-byte identifier of the contract method to call.
    ///
    /// See [`ContractEntrypointID`] in contract.x for how these are derived.
    pub entrypoint: ContractEntrypointID,
    /// Maximum gas units available for this invocation.
    ///
    /// For the root transaction invocation, this is the total gas budget.
    /// For subinvocations via the Invoke syscall, this is capped at the
    /// remaining gas in the caller's frame. The SDK default is UINT64_MAX,
    /// meaning "use all remaining gas".
    pub gas_limit: GasAmount,
    /// Encoded arguments to pass to the contract method.
    pub calldata: Calldata,
}

#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[derive(Copy)]
#[repr(transparent)]
pub struct InvocationFrameStatusCode(pub i32);

impl InvocationFrameStatusCode {
    pub const Return: Self = Self(0);
    pub const Fault: Self = Self(1);
    pub const Abort: Self = Self(2);
}
impl From<i32> for InvocationFrameStatusCode {
    fn from(v: i32) -> Self {
        Self(v)
    }
}
#[cfg(feature = "std")]
impl core::fmt::Display for InvocationFrameStatusCode {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self.0 {
            x if x == Self::Return.0 => {
                write!(f, "InvocationFrameStatusCode::Return")
            },
            x if x == Self::Fault.0 => {
                write!(f, "InvocationFrameStatusCode::Fault")
            },
            x if x == Self::Abort.0 => {
                write!(f, "InvocationFrameStatusCode::Abort")
            },
            _ => {
                write!(f, "InvocationFrameStatusCode({})", self.0)
            }
        }
    }
}


#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[repr(i32)]
#[non_exhaustive]
pub enum InvocationFrameOutput {
    // case Return:
    //   ReturnBuffer return_buffer;
    Return { return_buffer: ReturnBuffer } = InvocationFrameStatusCode::Return.0 as i32,
    // case Abort:
    //   ReturnBuffer abort_buffer;
    Abort { abort_buffer: ReturnBuffer } = InvocationFrameStatusCode::Abort.0 as i32,
    // case Fault:
    //   void;
    Fault = InvocationFrameStatusCode::Fault.0 as i32,
    
}

//------------------------------------------------------------------------------
// Transaction Uniqueness and Replay Protection
//------------------------------------------------------------------------------

/// Ensures transaction uniqueness and prevents replay attacks.
///
/// Each transaction must include a uniquifier with two components:
/// 1. An expiry height - the transaction becomes invalid after this block
/// 2. A nonce - ensures uniqueness even if the same operation is repeated
///
/// The uniquifier is stored in the replay cache (see [`StorageKeyType::ReplayCache`]
/// in types.x) at the invoked contract's address to prevent replays.
///
/// Important: The replay cache considers the (nonce, block_expiry_height) pair as the
/// unique identifier. Two transactions with the same nonce but different expiry heights
/// do NOT conflict with each other. For example, (nonce=1, expiry=100) and (nonce=1, expiry=200)
/// can both be valid transactions.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(C)]
pub struct Uniquifier {
    /// The block height after which this transaction becomes invalid.
    ///
    /// Transactions submitted after this height will be rejected. This prevents
    /// old transactions from being replayed indefinitely.
    ///
    /// Note: This is part of the uniqueness check - the pair (nonce, block_expiry_height)
    /// must be unique, not just the nonce alone.
    pub block_expiry_height: BlockHeight,
    /// A 64-bit value chosen by the transaction creator.
    ///
    /// Combined with block_expiry_height and the invoked address, this ensures each
    /// transaction is globally unique. The nonce can be chosen arbitrarily (random,
    /// sequential, timestamp-based, etc.) as long as the (nonce, block_expiry_height)
    /// pair hasn't been used before for this address.
    pub nonce: u64,
}

//------------------------------------------------------------------------------
// Transactions
//------------------------------------------------------------------------------

/// A complete transaction that can be executed on the Thruput blockchain.
///
/// Transactions are the fundamental unit of state modification. Each transaction:
/// - Invokes a single contract method (which may make subinvocations)
/// - Includes claims about attached signatures, which must be verified before execution
///   can begin.  A transaction is invalid if any attached signatures are invalid
///   or if the attached signatures do not match the auth claims.
/// - Can deploy new contracts that will be available during execution
/// - Must have a [`Uniquifier`] that has never before been used for this address
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(C)]
pub struct Transaction {
    /// The root contract invocation for this transaction.
    pub invocation: Invocation,
    /// Uniqueness and replay protection data.
    pub uniquifier: Uniquifier,
    /// Contracts made available for deployment during this transaction.
    ///
    /// Attaching a contract does not deploy it: nothing reaches the chain
    /// unless a frame deploys it with the DeployContract syscall, which can then
    /// be invoked for the rest of the transaction. Contracts whose code is
    /// already on-chain do not need to be included here.
    pub contracts_to_deploy: VecM<Contract>,
    /// Authorization claim specifying required signatures.
    ///
    /// See [`AuthClaim`] in auth_claim.x for details.
    pub auth_claim: AuthClaim,
}

//------------------------------------------------------------------------------
// Signatures and Signed Transactions
//------------------------------------------------------------------------------

/// A cryptographic signature paired with its key identifier.
///
/// The public_key_id indicates which key from an address's key set produced
/// this signature, allowing the signature to be matched against the transaction's
/// auth claims.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(C)]
pub struct DecoratedSignature {
    /// The KeyID of the public key that created this signature.
    ///
    /// This is matched against the auth claims to determine if the signature
    /// satisfies the transaction's authorization requirements. Keys are
    /// registered and weighted in [`AddressAuthData`] (address_auth.x); see
    /// [`AuthClaim`] in auth_claim.x for how a claim selects them.
    // uint32_t
    pub public_key_id: u32,
    /// The cryptographic signature itself.
    ///
    /// See [`Signature`] in types.x for the union that supports different schemes.
    pub signature: Signature,
}

/// Hash of a transaction body, the identifier users, events and indexers
/// know a transaction by.
///
/// This is the SHA-256 hash of the XDR-encoded [`Transaction`] -- the same
/// encoding the signatures cover (see [`SignedTransaction`]). It deliberately covers neither the
/// signatures wrapped around it by [`SignedTransaction`] nor the
/// nondeterministic data attached to it by [`ProposedTransaction`]:
///
///  - Excluding the signatures keeps the identifier fixed however the body
///    is signed, so a submitter can look up its transaction without knowing
///    which signing a block carried.
///  - Excluding the proposal data keeps the identifier computable by the
///    submitter at signing time. Nondeterministic proposal data does not
///    exist until a proposer has executed the transaction, so an identifier
///    covering it could not be used to look up one's own transaction.
///
/// Proposals do not name transactions by this hash: they commit to each
/// transaction's exact signed encoding by [`SignedTransactionHash`].
///
/// Uniqueness across blocks rests on replay protection -- the
/// [`Uniquifier`] every [`Transaction`] carries -- rather than on anything
/// in the preimage: two distinct commits can never share a hash, because
/// the same [`Transaction`] cannot commit twice.
pub type TransactionHash = SHA256Hash;

/// Hash of one exact signed encoding of a transaction.
///
/// This is the SHA-256 hash of the canonical XDR of a [`SignedTransaction`]:
/// the [`Transaction`], its signatures and its `pubkey_claim_key`. Two
/// signings of one body share a [`TransactionHash`] but not a
/// [`SignedTransactionHash`].
///
/// Proposals name their transactions by this hash, so every validator
/// executes the encoding the proposer chose rather than whichever signing of
/// the body it happens to hold. A validator that holds a different signing
/// treats the transaction as missing and fetches the proposer's. It is not a
/// lookup key for users: re-signing a body changes it.
pub type SignedTransactionHash = SHA256Hash;

/// A transaction with cryptographic signatures.
///
/// This is the form in which transactions are transmitted and stored.
/// Before execution, the signatures are verified against the auth claim.
///
/// Each signature is over
/// `cxs(DomainSeparator("Transaction")) || network_hash || xdr(tx)`: the
/// domain separator keeps it from being reinterpreted as a signature over
/// another object, and the network hash binds it to one network.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(C)]
pub struct SignedTransaction {
    /// The transaction to execute.
    pub tx: Transaction,
    /// Signatures that authorize this transaction.
    ///
    /// These signatures must satisfy the auth_claim in the transaction.
    /// See [`SignedTransaction`] for the message they sign.
    pub signatures: VecM<DecoratedSignature>,
    /// The public key a `kPubkeySignature` auth claim names by hash.
    ///
    /// Present exactly when the auth claim is `kPubkeySignature`, and then its
    /// [`PublicKeyHash`] must equal the claim's `pubkey_preimage.pubkey_hash`.
    /// It sits outside the signed [`Transaction`] because the claim already
    /// commits to it by hash; keeping it out of the claim keeps the claim that
    /// contracts read the same size for every scheme.
    pub pubkey_claim_key: Option<PublicKey>,
}

//------------------------------------------------------------------------------
// Batch Types
//------------------------------------------------------------------------------

/// A batch of transactions (without signatures).
pub type TransactionBatch = VecM::<Transaction>;

/// A batch of signed transactions.
pub type SignedTransactionBatch = VecM::<SignedTransaction>;

/// An optional signed transaction (pointer may be null).
pub type OptSignedTransaction = Option::<SignedTransaction>;

/// A batch of optional signed transactions.
pub type OptSignedTransactionBatch = VecM::<OptSignedTransaction>;

/// A batch of transaction hashes.
pub type TransactionHashBatch = VecM::<TransactionHash>;

/// A batch of signed transaction hashes.
pub type SignedTransactionHashBatch = VecM::<SignedTransactionHash>;

//------------------------------------------------------------------------------
// Proposed Transactions and Nondeterministic Data
//------------------------------------------------------------------------------

/// Nondeterministic data captured during transaction execution by the proposer.
///
/// Thruput executes transactions in parallel, which introduces nondeterminism
/// (e.g., from two-phase commit conflict resolution). To ensure validators can deterministically
/// re-execute transactions, the proposer captures all nondeterministic decisions
/// and includes them in the block proposal.
///
/// This allows validators to replay the exact same execution path as the proposer,
/// ensuring consensus on the transaction result.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(C)]
pub struct NondeterministicProposalData {
    /// A bitstring of nondeterministic decisions made during execution.
    ///
    /// This includes:
    /// - Two-phase commit conflict resolution results from try_invoke frames (one boolean
    ///   per try_invoke frame that succeeds and attempts lock acquisition)
    /// - Other nondeterministic outcomes that must be consistent across validators
    ///
    /// Each bit represents a binary decision point encountered during execution.
    /// The bits are consumed sequentially as the transaction re-executes.
    pub nondeterministic_bits: BytesM,
    /// The length of nondeterministic_bits in bits (not bytes).
    ///
    /// Since nondeterministic_bits.size() returns the rounded-up length in bytes,
    /// this field tracks the exact bit count to avoid trailing garbage bits.
    pub nondeterministic_bit_count: u32,
    /// Retrocausal queue entries inserted by concurrent transactions in the same
    /// block that this transaction observed, so validators replay the same reads.
    ///
    /// An entry is recorded when a peek or consume reads a concurrent entry.
    /// Reads of entries from past blocks or inserted by this transaction itself
    /// record nothing. Entries appear in the order they were first observed
    /// during execution, interleaved across queues; within one queue they are
    /// that queue's concurrent entries in index order, starting at 0. Each
    /// (queue, index) is recorded once however many times it is read, so
    /// repeated peeks, or a peek followed by a consume, add a single entry.
    /// Whether each concurrent read found an entry is recorded separately, one
    /// bit per read, in nondeterministic_bits.
    pub observed_queue_entry_sequence: VecM<QueueEntry, kMaxConcurrentRcqReadsPerTx>,
}

/// A signed transaction with nondeterministic execution data attached.
///
/// This is the form in which transactions are included in block proposals.
/// The proposer:
/// 1. Executes the signed transaction
/// 2. Captures all nondeterministic decisions (two-phase commit results, queue entries, etc.)
/// 3. Packages both into a ProposedTransaction
/// 4. Includes it in the proposed block
///
/// Validators then re-execute using the nondeterministic data to verify
/// the proposer's execution was correct.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(C)]
pub struct ProposedTransaction {
    /// The signed transaction to execute.
    pub signed_tx: SignedTransaction,
    /// Nondeterministic data captured during the proposer's execution.
    ///
    /// Validators use this to deterministically replay the same execution path.
    pub nondeterministic_proposal_data: NondeterministicProposalData,
}

pub type ProposedTransactionBatch = VecM::<ProposedTransaction>;

//------------------------------------------------------------------------------
// Transaction Statistics
//------------------------------------------------------------------------------

/// Transaction execution statistics available via the GetTransactionStatistics syscall.
///
/// These statistics provide runtime information about transaction execution,
/// primarily for debugging and monitoring. Some statistics may be disabled
/// in production builds.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[cfg_attr(feature = "serde", serde(transparent))]
#[cfg_attr(feature = "xdrs", derive(ReadXDR, WriteXDR, ConstXDRSize))]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[derive(Copy)]
#[repr(transparent)]
pub struct TransactionStatistic(pub i32);

impl TransactionStatistic {
    /// The amount of gas remaining in the current call frame.
    ///
    /// This can be queried to monitor gas consumption during execution.
    /// Note that this statistic may be disabled or return nondeterministic
    /// values in test configurations (see syscalls.yaml for details).
    pub const GasRemaining: Self = Self(0);
}
impl From<i32> for TransactionStatistic {
    fn from(v: i32) -> Self {
        Self(v)
    }
}
#[cfg(feature = "std")]
impl core::fmt::Display for TransactionStatistic {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        match self.0 {
            x if x == Self::GasRemaining.0 => {
                write!(f, "TransactionStatistic::GasRemaining")
            },
            _ => {
                write!(f, "TransactionStatistic({})", self.0)
            }
        }
    }
}



//
// XDR internals below this point
//

impl InvocationFrameOutput {
    #[allow(clippy::match_single_binding)]
    pub fn status_code(&self) -> InvocationFrameStatusCode {
        match self {
            
            _ => (unsafe { *(self as *const Self as *const i32) }).into(),
        }
    }
}