sui_types/
executable_transaction.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::crypto::AccountKeyPair;
5use crate::messages_checkpoint::CheckpointSequenceNumber;
6use crate::utils::to_sender_signed_transaction;
7use crate::{committee::EpochId, crypto::AuthorityStrongQuorumSignInfo};
8
9use crate::message_envelope::{Envelope, TrustedEnvelope, VerifiedEnvelope};
10use crate::transaction::{
11    SenderSignedData, TransactionData, TransactionDataAPI, VerifiedTransaction,
12};
13use serde::{Deserialize, Serialize};
14
15/// CertificateProof is a proof that a transaction certs existed at a given epoch and hence can be executed.
16/// There are two types of proofs: one that is proven by inclusion in a checkpoint and one that is proven by quorum signature.
17#[derive(Clone, Debug, Serialize, Deserialize)]
18pub enum CertificateProof {
19    /// Validity was proven by inclusion in the given checkpoint
20    Checkpoint(EpochId, CheckpointSequenceNumber),
21    /// Validity was proven by transaction certificate signature
22    Certified(AuthorityStrongQuorumSignInfo),
23    /// At least f+1 validators have executed this transaction.
24    /// In practice, we will always get 2f+1 (effects cert), but theoretically f+1 is enough to prove
25    /// that the transaction is valid.
26    QuorumExecuted(EpochId),
27    /// Transaction generated by the system, for example Clock update transaction
28    SystemTransaction(EpochId),
29    /// Validity was proven through voting in consensus.
30    Consensus(EpochId),
31}
32
33impl CertificateProof {
34    pub fn new_from_cert_sig(sig: AuthorityStrongQuorumSignInfo) -> Self {
35        Self::Certified(sig)
36    }
37
38    pub fn new_from_checkpoint(epoch: EpochId, checkpoint: CheckpointSequenceNumber) -> Self {
39        Self::Checkpoint(epoch, checkpoint)
40    }
41
42    pub fn new_system(epoch: EpochId) -> Self {
43        Self::SystemTransaction(epoch)
44    }
45
46    pub fn new_from_consensus(epoch: EpochId) -> Self {
47        Self::Consensus(epoch)
48    }
49
50    pub fn epoch(&self) -> EpochId {
51        match self {
52            Self::Checkpoint(epoch, _)
53            | Self::QuorumExecuted(epoch)
54            | Self::SystemTransaction(epoch)
55            | Self::Consensus(epoch) => *epoch,
56            Self::Certified(sig) => sig.epoch,
57        }
58    }
59}
60
61/// An ExecutableTransaction is a wrapper of a transaction with a CertificateProof that indicates
62/// there existed a valid certificate for this transaction, and hence it can be executed locally.
63/// This is an abstraction data structure to cover both the case where the transaction is
64/// certified or checkpointed when we schedule it for execution.
65pub type ExecutableTransaction = Envelope<SenderSignedData, CertificateProof>;
66pub type VerifiedExecutableTransaction = VerifiedEnvelope<SenderSignedData, CertificateProof>;
67pub type TrustedExecutableTransaction = TrustedEnvelope<SenderSignedData, CertificateProof>;
68
69impl VerifiedExecutableTransaction {
70    pub fn gas_budget(&self) -> u64 {
71        self.data().transaction_data().gas_budget()
72    }
73
74    pub fn new_for_testing(tx_data: TransactionData, keypair: &AccountKeyPair) -> Self {
75        let tx = to_sender_signed_transaction(tx_data, keypair);
76        Self::new_from_quorum_execution(VerifiedTransaction::new_unchecked(tx), 0)
77    }
78}