atomic

package
v1.23.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 7, 2026 License: GPL-3.0, LGPL-3.0, LGPL-3.0 Imports: 24 Imported by: 1

Documentation

Index

Constants

View Source
const (
	// LuxAtomicTxFee is the LUX amount burned per atomic tx.
	LuxAtomicTxFee = constants.MilliLux

	// AtomicTxBaseCost is the base intrinsic gas charged per atomic tx.
	AtomicTxBaseCost uint64 = 10_000

	// AtomicGasLimit caps the cumulative atomic gas consumed in a block.
	// A block may include any set of atomic txs whose total atomic gas is <=
	// this limit (analogous to the block gas limit for EVM txs).
	AtomicGasLimit uint64 = 100_000
)

Canonical atomic-tx accounting constants. Under activate-all-implicitly there ones (no per-upgrade variants).

View Source
const CodecVersion = uint16(0)

CodecVersion is the current wire version. Increment on any incompatible schema change. There is no "v0 read fallback" — hard cut, one shape.

View Source
const (
	X2CRateUint64 uint64 = 1_000_000_000
)

Variables

View Source
var (
	ErrUnknownVersion    = errors.New("unknown wire version")
	ErrCantUnpackVersion = errors.New("couldn't unpack version")
	ErrCantPackVersion   = errors.New("couldn't pack version")
	ErrUnsupportedType   = errors.New("unsupported atomic type")
	ErrUnknownTypeID     = errors.New("unknown atomic type id")
	ErrMaxSizeExceeded   = errors.New("max atomic message size exceeded")
	ErrExtraSpace        = errors.New("trailing buffer space in atomic blob")
	ErrMissingAtomicTxs  = errors.New("cannot build a block with non-empty extra data and zero atomic transactions")
)
View Source
var (
	ErrExportNonLUXInput  = errors.New("export input must be LUX")
	ErrExportNonLUXOutput = errors.New("export output must be LUX")
	ErrNoExportOutputs    = errors.New("tx has no export outputs")
)
View Source
var (
	ErrImportNonLUXInput      = errors.New("import input must be LUX")
	ErrImportNonLUXOutput     = errors.New("import output must be LUX")
	ErrNoImportInputs         = errors.New("tx has no imported inputs")
	ErrWrongChainID           = errors.New("tx has wrong chain ID")
	ErrNoEVMOutputs           = errors.New("tx has no EVM outputs")
	ErrInputsNotSortedUnique  = errors.New("inputs not sorted and unique")
	ErrOutputsNotSortedUnique = errors.New("outputs not sorted and unique")
	ErrOutputsNotSorted       = errors.New("tx outputs not sorted")
)
View Source
var (
	ErrWrongNetworkID = errors.New("tx was issued with a different network ID")
	ErrNilTx          = errors.New("tx is nil")

	ErrNoValueInput = errors.New("input has no value")
)
View Source
var (
	TxBytesGas   uint64 = 1
	EVMOutputGas uint64 = (common.AddressLength + wrappers.LongLen + hash.HashLen) * TxBytesGas
	EVMInputGas  uint64 = (common.AddressLength+wrappers.LongLen+hash.HashLen+wrappers.LongLen)*TxBytesGas + secp256k1fx.CostPerSignature
	// X2CRate is the conversion rate between the smallest denomination on the X-Chain
	// 1 nLUX and the smallest denomination on the C-Chain 1 wei. Where 1 nLUX = 1 gWei.
	// This is only required for LUX because the denomination of 1 LUX is 9 decimal
	// places on the X and P chains, but is 18 decimal places within the EVM.
	X2CRate = uint256.NewInt(X2CRateUint64)
)

Constants for calculating the gas consumed by atomic transactions

Functions

func CalculateDynamicFee

func CalculateDynamicFee(cost uint64, baseFee *big.Int) (uint64, error)

calculates the amount of LUX that must be burned by an atomic transaction that consumes [cost] at [baseFee].

func SortEVMInputsAndSigners

func SortEVMInputsAndSigners(inputs []EVMInput, signers [][]*secp256k1.PrivateKey)

SortEVMInputsAndSigners sorts the list of EVMInputs based on the addresses and assetIDs

Types

type AtomicBlockContext

type AtomicBlockContext interface {
	AtomicTxs() []*Tx
}

type EVMInput

type EVMInput struct {
	Address common.Address `serialize:"true" json:"address"`
	Amount  uint64         `serialize:"true" json:"amount"`
	AssetID ids.ID         `serialize:"true" json:"assetID"`
	Nonce   uint64         `serialize:"true" json:"nonce"`
}

EVMInput defines an input created from the EVM state to fund export transactions

func (EVMInput) Compare

func (i EVMInput) Compare(other EVMInput) int

func (*EVMInput) Verify

func (i *EVMInput) Verify() error

Verify ...

type EVMOutput

type EVMOutput struct {
	Address common.Address `serialize:"true" json:"address"`
	Amount  uint64         `serialize:"true" json:"amount"`
	AssetID ids.ID         `serialize:"true" json:"assetID"`
}

EVMOutput defines an output that is added to the EVM state created by import transactions

func (EVMOutput) Compare

func (o EVMOutput) Compare(other EVMOutput) int

func (*EVMOutput) Verify

func (o *EVMOutput) Verify() error

Verify ...

type Manager added in v1.23.2

type Manager interface {
	Marshal(version uint16, source interface{}) ([]byte, error)
	Unmarshal(bytes []byte, dest interface{}) (uint16, error)
}

Manager is the surface every wire-touching peer of this package needs. It is the smallest method set that lets a caller serialize or parse an atomic-tx blob — no reflection registry, no codec.Codec sub-interface.

The package singleton Codec implements Manager. Downstream packages (atomic/state, atomic/vm, plugin/evm/atomic/atomictest) accept Manager in their constructors rather than coupling to a specific concrete type.

var Codec Manager = &manager{maxSize: maxAtomicMessageSize}

Codec is the singleton atomic-tx codec. Callers use Codec.Marshal / Codec.Unmarshal.

type Metadata

type Metadata struct {
	// contains filtered or unexported fields
}

func (*Metadata) Bytes

func (md *Metadata) Bytes() []byte

UnsignedBytes returns the unsigned binary representation of this data

func (*Metadata) ID

func (md *Metadata) ID() ids.ID

ID returns the unique ID of this data

func (*Metadata) Initialize

func (md *Metadata) Initialize(unsignedBytes, bytes []byte)

Initialize set the bytes and ID

func (*Metadata) SignedBytes

func (md *Metadata) SignedBytes() []byte

Bytes returns the binary representation of this data

type StateDB

type StateDB interface {
	AddBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) uint256.Int
	AddBalanceMultiCoin(common.Address, common.Hash, *big.Int)

	SubBalance(common.Address, *uint256.Int, tracing.BalanceChangeReason) uint256.Int
	SubBalanceMultiCoin(common.Address, common.Hash, *big.Int)

	GetBalance(common.Address) *uint256.Int
	GetBalanceMultiCoin(common.Address, common.Hash) *big.Int

	GetNonce(common.Address) uint64
	SetNonce(common.Address, uint64, tracing.NonceChangeReason)
}

type Status

type Status uint32

Status ...

const (
	Unknown Status = iota
	Dropped
	Processing
	Accepted
)

List of possible status values Unknown Zero value, means the status is not known Dropped means the transaction was in the mempool, but was dropped because it failed verification Processing means the transaction is in the mempool Accepted means the transaction was accepted

func (Status) MarshalJSON

func (s Status) MarshalJSON() ([]byte, error)

MarshalJSON ...

func (Status) String

func (s Status) String() string

func (*Status) UnmarshalJSON

func (s *Status) UnmarshalJSON(b []byte) error

UnmarshalJSON ...

func (Status) Valid

func (s Status) Valid() error

Valid returns nil if the status is a valid status.

type Tx

type Tx struct {
	// The body of this transaction
	UnsignedAtomicTx `serialize:"true" json:"unsignedTx"`

	// The credentials of this transaction
	Creds []verify.Verifiable `serialize:"true" json:"credentials"`
}

Tx is a signed transaction

func ExtractAtomicTx

func ExtractAtomicTx(atomicTxBytes []byte, c Manager) (*Tx, error)

ExtractAtomicTx extracts a singular atomic transaction from [atomicTxBytes]. Note: this function assumes [atomicTxBytes] is non-empty.

The post-unmarshal step re-marshals via [c] to materialize the unsigned and signed byte forms on the Tx — these are stashed in Metadata and later consumed by ID(), Bytes(), SignedBytes(). We deliberately do not call Tx.Sign here because Sign is bound to the production Codec and would refuse non-production tx types (e.g. the atomictest harness type).

func ExtractAtomicTxs

func ExtractAtomicTxs(atomicTxBytes []byte, batch bool, c Manager) ([]*Tx, error)

ExtractAtomicTxs returns the atomic transactions in [atomicTxBytes] if they exist. If [batch] is true, [atomicTxBytes] is decoded as a batch; otherwise as a single atomic tx.

func ExtractAtomicTxsBatch

func ExtractAtomicTxsBatch(atomicTxBytes []byte, c Manager) ([]*Tx, error)

ExtractAtomicTxsBatch extracts a slice of atomic transactions from [atomicTxBytes]. Note: this function assumes [atomicTxBytes] is non-empty.

func NewExportTx

func NewExportTx(
	ctx *consensusctx.Context,
	rules extras.Rules,
	state StateDB,
	assetID ids.ID,
	amount uint64,
	chainID ids.ID,
	to ids.ShortID,
	baseFee *big.Int,
	keys []*secp256k1.PrivateKey,
) (*Tx, error)

NewExportTx returns a new ExportTx

func NewImportTx

func NewImportTx(
	ctx *consensusctx.Context,
	rules extras.Rules,
	time uint64,
	chainID ids.ID,
	to common.Address,
	baseFee *big.Int,
	kc *secp256k1fx.Keychain,
	atomicUTXOs []*lux.UTXO,
) (*Tx, error)

NewImportTx returns a new ImportTx. Under activate-all-implicitly the

func (*Tx) BlockFeeContribution

func (tx *Tx) BlockFeeContribution(fixedFee bool, luxAssetID ids.ID, baseFee *big.Int) (*big.Int, *big.Int, error)

BlockFeeContribution calculates how much LUX towards the block fee contribution was paid for via this transaction denominated in [luxAssetID] with [baseFee] used to calculate the cost of this transaction. This function also returns the [gasUsed] by the transaction for inclusion in the [baseFee] algorithm.

func (*Tx) Compare

func (tx *Tx) Compare(other *Tx) int

func (*Tx) GossipID

func (tx *Tx) GossipID() luxfiids.ID

func (*Tx) Sign

func (tx *Tx) Sign(signers [][]*secp256k1.PrivateKey) error

Sign this transaction with the provided signers. The atomic-tx package owns its own wire format via Codec; callers no longer pass a codec manager in. Pass nil signers to compute and stash the unsigned/signed byte forms without adding any new credentials.

type TxMarshaller

type TxMarshaller struct{}

func (*TxMarshaller) MarshalGossip

func (g *TxMarshaller) MarshalGossip(tx *Tx) ([]byte, error)

func (*TxMarshaller) UnmarshalGossip

func (*TxMarshaller) UnmarshalGossip(bytes []byte) (*Tx, error)

type UnsignedAtomicTx

type UnsignedAtomicTx interface {
	UnsignedTx

	// InputUTXOs returns the UTXOs this tx consumes
	InputUTXOs() set.Set[ids.ID]
	// Verify attempts to verify that the transaction is well formed
	Verify(ctx *consensusctx.Context, rules extras.Rules) error
	// Visit calls the corresponding method for the underlying transaction type
	// implementing [Visitor].
	// This is used in semantic verification of the tx.
	Visit(v Visitor) error
	// AtomicOps returns the blockchainID and set of atomic requests that
	// must be applied to shared memory for this transaction to be accepted.
	// The set of atomic requests must be returned in a consistent order.
	AtomicOps() (ids.ID, *atomic.Requests, error)

	EVMStateTransfer(ctx *consensusctx.Context, state StateDB) error
}

UnsignedAtomicTx is an unsigned operation that can be atomically accepted

type UnsignedExportTx

type UnsignedExportTx struct {
	Metadata
	// ID of the network on which this tx was issued
	NetworkID uint32 `serialize:"true" json:"networkID"`
	// ID of this blockchain.
	BlockchainID ids.ID `serialize:"true" json:"blockchainID"`
	// Which chain to send the funds to
	DestinationChain ids.ID `serialize:"true" json:"destinationChain"`
	// Inputs
	Ins []EVMInput `serialize:"true" json:"inputs"`
	// Outputs that are exported to the chain
	ExportedOutputs []*lux.TransferableOutput `serialize:"true" json:"exportedOutputs"`
}

UnsignedExportTx is an unsigned ExportTx

func (*UnsignedExportTx) AtomicOps

func (utx *UnsignedExportTx) AtomicOps() (ids.ID, *atomic.Requests, error)

AtomicOps returns the atomic operations for this transaction.

func (*UnsignedExportTx) Burned

func (utx *UnsignedExportTx) Burned(assetID ids.ID) (uint64, error)

Amount of [assetID] burned by this transaction

func (*UnsignedExportTx) EVMStateTransfer

func (utx *UnsignedExportTx) EVMStateTransfer(ctx *consensusctx.Context, state StateDB) error

EVMStateTransfer executes the state update from the atomic export transaction

func (*UnsignedExportTx) GasUsed

func (utx *UnsignedExportTx) GasUsed(fixedFee bool) (uint64, error)

func (*UnsignedExportTx) InputUTXOs

func (utx *UnsignedExportTx) InputUTXOs() set.Set[ids.ID]

InputUTXOs returns a set of all the hash(address:nonce) exporting funds.

func (*UnsignedExportTx) Verify

func (utx *UnsignedExportTx) Verify(
	ctx *consensusctx.Context,
	rules extras.Rules,
) error

Verify this transaction is well-formed

func (*UnsignedExportTx) Visit

func (utx *UnsignedExportTx) Visit(v Visitor) error

type UnsignedImportTx

type UnsignedImportTx struct {
	Metadata
	// ID of the network on which this tx was issued
	NetworkID uint32 `serialize:"true" json:"networkID"`
	// ID of this blockchain.
	BlockchainID ids.ID `serialize:"true" json:"blockchainID"`
	// Which chain to consume the funds from
	SourceChain ids.ID `serialize:"true" json:"sourceChain"`
	// Inputs that consume UTXOs produced on the chain
	ImportedInputs []*lux.TransferableInput `serialize:"true" json:"importedInputs"`
	// Outputs
	Outs []EVMOutput `serialize:"true" json:"outputs"`
}

UnsignedImportTx is an unsigned ImportTx

func (*UnsignedImportTx) AtomicOps

func (utx *UnsignedImportTx) AtomicOps() (ids.ID, *atomic.Requests, error)

AtomicOps returns imported inputs spent on this transaction We spend imported UTXOs here rather than in verification because we don't want to remove an imported UTXO in verification only to have the transaction not be Accepted. This would be inconsistent. Recall that imported UTXOs are not kept in a versionDB.

func (*UnsignedImportTx) Burned

func (utx *UnsignedImportTx) Burned(assetID ids.ID) (uint64, error)

Amount of [assetID] burned by this transaction

func (*UnsignedImportTx) EVMStateTransfer

func (utx *UnsignedImportTx) EVMStateTransfer(ctx *consensusctx.Context, state StateDB) error

EVMStateTransfer performs the state transfer to increase the balances of accounts accordingly with the imported EVMOutputs

func (*UnsignedImportTx) GasUsed

func (utx *UnsignedImportTx) GasUsed(fixedFee bool) (uint64, error)

func (*UnsignedImportTx) InputUTXOs

func (utx *UnsignedImportTx) InputUTXOs() set.Set[ids.ID]

InputUTXOs returns the UTXOIDs of the imported funds

func (*UnsignedImportTx) Verify

func (utx *UnsignedImportTx) Verify(
	ctx *consensusctx.Context,
	_ extras.Rules,
) error

Verify this transaction is well-formed. Under activate-all-implicitly every collapse to the strict path.

func (*UnsignedImportTx) Visit

func (utx *UnsignedImportTx) Visit(v Visitor) error

type UnsignedTx

type UnsignedTx interface {
	Initialize(unsignedBytes, signedBytes []byte)
	ID() ids.ID
	GasUsed(fixedFee bool) (uint64, error)
	Burned(assetID ids.ID) (uint64, error)
	Bytes() []byte
	SignedBytes() []byte
}

UnsignedTx is an unsigned transaction

type Visitor

type Visitor interface {
	ImportTx(*UnsignedImportTx) error
	ExportTx(*UnsignedExportTx) error
}

Visitor allows executing custom logic against the underlying transaction types.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL