use crate::Digest;
use super::Address;
use super::CheckpointTimestamp;
use super::EpochId;
use super::GenesisObject;
use super::Identifier;
use super::Jwk;
use super::JwkId;
use super::ObjectReference;
use super::ProtocolVersion;
use super::TypeTag;
use super::UserSignature;
use super::Version;
#[cfg(feature = "serde")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
mod serialization;
#[cfg(feature = "serde")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "serde")))]
pub(crate) use serialization::SignedTransactionWithIntentMessage;
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct Transaction {
pub kind: TransactionKind,
pub sender: Address,
pub gas_payment: GasPayment,
pub expiration: TransactionExpiration,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct SignedTransaction {
pub transaction: Transaction,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
pub signatures: Vec<UserSignature>,
}
#[derive(Clone, Copy, Default, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
#[non_exhaustive]
pub enum TransactionExpiration {
#[default]
None,
Epoch(EpochId),
ValidDuring {
min_epoch: Option<EpochId>,
max_epoch: Option<EpochId>,
min_timestamp: Option<u64>,
max_timestamp: Option<u64>,
chain: Digest,
nonce: u32,
},
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct GasPayment {
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub objects: Vec<ObjectReference>,
pub owner: Address,
pub price: u64,
pub budget: u64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct RandomnessStateUpdate {
pub epoch: u64,
pub randomness_round: u64,
#[cfg_attr(
feature = "serde",
serde(with = "crate::_serde::ReadableBase64Encoded")
)]
pub random_bytes: Vec<u8>,
pub randomness_obj_initial_shared_version: u64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
#[non_exhaustive]
pub enum TransactionKind {
ProgrammableTransaction(ProgrammableTransaction),
ChangeEpoch(ChangeEpoch),
Genesis(GenesisTransaction),
ConsensusCommitPrologue(ConsensusCommitPrologue),
AuthenticatorStateUpdate(AuthenticatorStateUpdate),
EndOfEpoch(
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
Vec<EndOfEpochTransactionKind>,
),
RandomnessStateUpdate(RandomnessStateUpdate),
ConsensusCommitPrologueV2(ConsensusCommitPrologueV2),
ConsensusCommitPrologueV3(ConsensusCommitPrologueV3),
ConsensusCommitPrologueV4(ConsensusCommitPrologueV4),
ProgrammableSystemTransaction(ProgrammableTransaction),
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
#[non_exhaustive]
pub enum EndOfEpochTransactionKind {
ChangeEpoch(ChangeEpoch),
AuthenticatorStateCreate,
AuthenticatorStateExpire(AuthenticatorStateExpire),
RandomnessStateCreate,
DenyListStateCreate,
BridgeStateCreate { chain_id: Digest },
BridgeCommitteeInit { bridge_object_version: u64 },
StoreExecutionTimeObservations(ExecutionTimeObservations),
AccumulatorRootCreate,
CoinRegistryCreate,
DisplayRegistryCreate,
AddressAliasStateCreate,
WriteAccumulatorStorageCost { storage_cost: u64 },
}
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[non_exhaustive]
pub enum ExecutionTimeObservations {
V1(
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
Vec<(
ExecutionTimeObservationKey,
Vec<ValidatorExecutionTimeObservation>,
)>,
),
}
#[derive(Debug, Hash, PartialEq, Eq, Clone)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
pub struct ValidatorExecutionTimeObservation {
pub validator: crate::Bls12381PublicKey,
#[cfg_attr(feature = "proptest", strategy(proptest::strategy::Strategy::prop_map(proptest::arbitrary::any::<u32>(), |x| std::time::Duration::from_millis(x.into()))))]
pub duration: std::time::Duration,
}
#[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[non_exhaustive]
pub enum ExecutionTimeObservationKey {
MoveEntryPoint {
package: Address,
module: String,
function: String,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
type_arguments: Vec<TypeTag>,
},
TransferObjects,
SplitCoins,
MergeCoins,
Publish, MakeMoveVec,
Upgrade,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct AuthenticatorStateExpire {
pub min_epoch: u64,
pub authenticator_object_initial_shared_version: u64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct AuthenticatorStateUpdate {
pub epoch: u64,
pub round: u64,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
pub new_active_jwks: Vec<ActiveJwk>,
pub authenticator_obj_initial_shared_version: u64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct ActiveJwk {
pub jwk_id: JwkId,
pub jwk: Jwk,
pub epoch: u64,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct ConsensusCommitPrologue {
pub epoch: u64,
pub round: u64,
pub commit_timestamp_ms: CheckpointTimestamp,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct ConsensusCommitPrologueV2 {
pub epoch: u64,
pub round: u64,
pub commit_timestamp_ms: CheckpointTimestamp,
pub consensus_commit_digest: Digest,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
#[non_exhaustive]
pub enum ConsensusDeterminedVersionAssignments {
CanceledTransactions {
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
canceled_transactions: Vec<CanceledTransaction>,
},
CanceledTransactionsV2 {
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
canceled_transactions: Vec<CanceledTransactionV2>,
},
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct CanceledTransaction {
pub digest: Digest,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub version_assignments: Vec<VersionAssignment>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct VersionAssignment {
pub object_id: Address,
pub version: Version,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct CanceledTransactionV2 {
pub digest: Digest,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub version_assignments: Vec<VersionAssignmentV2>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct VersionAssignmentV2 {
pub object_id: Address,
pub start_version: Version,
pub version: Version,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct ConsensusCommitPrologueV3 {
pub epoch: u64,
pub round: u64,
pub sub_dag_index: Option<u64>,
pub commit_timestamp_ms: CheckpointTimestamp,
pub consensus_commit_digest: Digest,
pub consensus_determined_version_assignments: ConsensusDeterminedVersionAssignments,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct ConsensusCommitPrologueV4 {
pub epoch: u64,
pub round: u64,
pub sub_dag_index: Option<u64>,
pub commit_timestamp_ms: CheckpointTimestamp,
pub consensus_commit_digest: Digest,
pub consensus_determined_version_assignments: ConsensusDeterminedVersionAssignments,
pub additional_state_digest: Digest,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct ChangeEpoch {
pub epoch: EpochId,
pub protocol_version: ProtocolVersion,
pub storage_charge: u64,
pub computation_charge: u64,
pub storage_rebate: u64,
pub non_refundable_storage_fee: u64,
pub epoch_start_timestamp_ms: u64,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
pub system_packages: Vec<SystemPackage>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct SystemPackage {
pub version: Version,
#[cfg_attr(
feature = "serde",
serde(
with = "::serde_with::As::<Vec<::serde_with::IfIsHumanReadable<crate::_serde::Base64Encoded, ::serde_with::Bytes>>>"
)
)]
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
pub modules: Vec<Vec<u8>>,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
pub dependencies: Vec<Address>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct GenesisTransaction {
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
pub objects: Vec<GenesisObject>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct ProgrammableTransaction {
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=10).lift()))]
pub inputs: Vec<Input>,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub commands: Vec<Command>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
#[non_exhaustive]
pub enum Input {
Pure(Vec<u8>),
ImmutableOrOwned(ObjectReference),
Shared(SharedInput),
Receiving(ObjectReference),
FundsWithdrawal(FundsWithdrawal),
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct SharedInput {
object_id: Address,
version: u64,
mutability: Mutability,
}
impl SharedInput {
pub fn new<M: Into<Mutability>>(object_id: Address, version: u64, mutable: M) -> Self {
Self {
object_id,
version,
mutability: mutable.into(),
}
}
pub fn object_id(&self) -> Address {
self.object_id
}
pub fn version(&self) -> u64 {
self.version
}
pub fn mutability(&self) -> Mutability {
self.mutability
}
}
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub enum Mutability {
Immutable,
Mutable,
NonExclusiveWrite,
}
impl From<bool> for Mutability {
fn from(mutable: bool) -> Self {
if mutable {
Self::Mutable
} else {
Self::Immutable
}
}
}
impl Mutability {
pub fn is_mutable(self) -> bool {
match self {
Mutability::Immutable => false,
Mutability::Mutable => true,
Mutability::NonExclusiveWrite => false,
}
}
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
#[non_exhaustive]
enum Reservation {
Amount(u64),
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
#[non_exhaustive]
enum WithdrawalType {
Balance(TypeTag),
}
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct FundsWithdrawal {
reservation: Reservation,
type_: WithdrawalType,
source: WithdrawFrom,
}
impl FundsWithdrawal {
pub fn new(amount: u64, coin_type: TypeTag, source: WithdrawFrom) -> Self {
Self {
reservation: Reservation::Amount(amount),
type_: WithdrawalType::Balance(coin_type),
source,
}
}
pub fn amount(&self) -> Option<u64> {
match self.reservation {
Reservation::Amount(amount) => Some(amount),
}
}
pub fn coin_type(&self) -> &TypeTag {
match &self.type_ {
WithdrawalType::Balance(coin_type) => coin_type,
}
}
pub fn source(&self) -> WithdrawFrom {
self.source
}
}
#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
#[non_exhaustive]
pub enum WithdrawFrom {
Sender,
Sponsor,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
#[non_exhaustive]
pub enum Command {
MoveCall(MoveCall),
TransferObjects(TransferObjects),
SplitCoins(SplitCoins),
MergeCoins(MergeCoins),
Publish(Publish),
MakeMoveVector(MakeMoveVector),
Upgrade(Upgrade),
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct TransferObjects {
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub objects: Vec<Argument>,
pub address: Argument,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct SplitCoins {
pub coin: Argument,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub amounts: Vec<Argument>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct MergeCoins {
pub coin: Argument,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub coins_to_merge: Vec<Argument>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct Publish {
#[cfg_attr(
feature = "serde",
serde(
with = "::serde_with::As::<Vec<::serde_with::IfIsHumanReadable<crate::_serde::Base64Encoded, ::serde_with::Bytes>>>"
)
)]
pub modules: Vec<Vec<u8>>,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub dependencies: Vec<Address>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct MakeMoveVector {
#[cfg_attr(feature = "serde", serde(rename = "type"))]
pub type_: Option<TypeTag>,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub elements: Vec<Argument>,
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct Upgrade {
#[cfg_attr(
feature = "serde",
serde(
with = "::serde_with::As::<Vec<::serde_with::IfIsHumanReadable<crate::_serde::Base64Encoded, ::serde_with::Bytes>>>"
)
)]
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=1).lift()))]
pub modules: Vec<Vec<u8>>,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub dependencies: Vec<Address>,
pub package: Address,
pub ticket: Argument,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub enum Argument {
Gas,
Input(u16),
Result(u16),
NestedResult(u16, u16),
}
impl Argument {
pub fn nested(&self, ix: u16) -> Option<Argument> {
match self {
Argument::Result(i) => Some(Argument::NestedResult(*i, ix)),
_ => None,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "serde",
derive(serde_derive::Serialize, serde_derive::Deserialize)
)]
#[cfg_attr(feature = "proptest", derive(test_strategy::Arbitrary))]
pub struct MoveCall {
pub package: Address,
pub module: Identifier,
pub function: Identifier,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub type_arguments: Vec<TypeTag>,
#[cfg_attr(feature = "proptest", any(proptest::collection::size_range(0..=2).lift()))]
pub arguments: Vec<Argument>,
}