bridgevmroot

package
v1.30.43 Latest Latest
Warning

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

Go to latest
Published: Jun 23, 2026 License: BSD-3-Clause Imports: 3 Imported by: 0

Documentation

Overview

Package bridgevmroot computes the bridgevm_state_root in native Go, byte-identical to the lux-private GPU bridgevm_transition kernel (ops/bridgevm/cuda/bridgevm_transition.cu + bridgevm_kernels_common.cuh) and every backend's CPU oracle. It is the native-Go authority the licensed GPU accelerator mirrors: the same five family leaf preimages, the same per-family skip predicates, the same ascending-i compacted-occupied ordering, the same RFC-6962 tagged binary Merkle fold for the five variable-length sub-roots, and the same fixed-shape keccak256 composition for the final bridgevm_state_root.

It is the symmetric peer of vms/xvm/state/xvmroot (xvm execution_root): same crypto, same combiner, same value-struct decoupling. Where xvmroot has three families (utxo / asset / tx), bridgevm has five (signer_set / liquidity / inbox / outbox / daily_limit).

The root is a pure function of the canonical leaf FIELD VALUES, not of any in-memory struct. So this package consumes the accelerator's state-snapshot layout directly — SignerLeaf, LiquidityLeaf, MessageLeaf, DailyLeaf mirror the GPU structs' hashed fields exactly, in the exact preimage order. The leaves are the POST-transition values (the GPU's K1 mutates signer status / resets daily limits before hashing); callers supply the already-mutated field values, exactly as the GPU hashes them.

The leaf/node/empty Merkle combiner lives in github.com/luxfi/crypto/merkle (RFC-6962: leaf=keccak256(0x00‖d), node=keccak256(0x01‖L‖R), lone-right promotion, empty=keccak256("")). The un-tagged keccak256 (Ethereum Keccak-256, 0x01 pad — NOT FIPS-202 SHA3, i.e. sha3.NewLegacyKeccak256) used for both the leaf-digest preimage and the bridgevm_state_root compose lives in github.com/luxfi/crypto/hash. Integers are little-endian, matching the kernel's absorb_u32 / absorb_u64.

CRITICAL: the active-bond aggregate is a FULL 128-bit value (BondLo + BondHi with carry) — the GPU was fixed (MED-1 / "FIX 4") to accumulate both limbs and commit BondHi into both the signer leaf and the compose preimage. This package matches that: it accumulates the full 128-bit sum and binds both BondLo and BondHi into the composed root. Dropping BondHi would diverge from the GPU.

Normative spec: lux-private/gpu-kernels/backends/common/lux_merkle_fold.hpp, ops/bridgevm/cuda/bridgevm_transition.cu, and the CPU oracle in backends/vulkan/tests/test_bridgevm_transition_kat.cpp. KAT parity is proven in bridgevmroot_test.go against the values all GPU backends + the CPU oracle produce.

Index

Constants

View Source
const (
	SignerStatusActive      uint32 = 0x1
	SignerStatusJailed      uint32 = 0x2
	SignerStatusTombstoned  uint32 = 0x4
	SignerStatusPendingAdd  uint32 = 0x8
	SignerStatusPendingDrop uint32 = 0x10
	SignerStatusExiting     uint32 = 0x20
)

Signer status bits — match bridgevm_kernels_common.cuh kSignerStatus*. A signer is folded into signer_set_root iff Occupied != 0; the status bits below only affect the active-bond aggregate (active = Active set, Jailed clear, Tombstoned clear), never inclusion.

View Source
const Size = hash.KeccakSize

Size is the byte length of every root and element digest (a keccak256 output).

Variables

This section is empty.

Functions

func ActiveBond

func ActiveBond(signers []SignerLeaf) (bondLo, bondHi uint64, active uint32)

ActiveBond returns the FULL 128-bit aggregate Σ(BondLo : BondHi) over active signers (Active set, Jailed clear, Tombstoned clear), as a (lo, hi) pair with carry, alongside the active-signer count. This is the GPU's post-FIX-4 accumulation: BondHi is carried, never dropped. Used by Compose and surfaced for callers that need the epoch counters. Occupied == 0 slots do not contribute.

func Compose

func Compose(
	parentStateRoot, signerSetRoot, liquidityRoot, inboxRoot, outboxRoot, dailyLimitRoot [Size]byte,
	epoch, bondLo, bondHi uint64,
	active uint32,
) [Size]byte

Compose returns the bridgevm_state_root from the parent root, the five sub-roots, and the epoch counters, using the fixed-shape un-tagged keccak256 composition (this is NOT a Merkle node):

bridgevm_state_root = keccak256(
    parentStateRoot ‖ signerSetRoot ‖ liquidityRoot ‖ inboxRoot ‖
    outboxRoot ‖ dailyLimitRoot ‖ epoch_u64_le ‖ bondLo_u64_le ‖
    bondHi_u64_le ‖ active_u32_le )

epoch is the finalized current epoch (target epoch on a closing round, else the unchanged current epoch). bondLo/bondHi are the full 128-bit active-bond aggregate; active is the active-signer count.

func DailyLimitRoot

func DailyLimitRoot(entries []DailyLeaf) [Size]byte

DailyLimitRoot is the tagged binary Merkle root over the active daily-limit entries' leaf digests, in ascending slot index. An entry with Status == 0 is skipped.

func InboxRoot

func InboxRoot(inbox []MessageLeaf) [Size]byte

InboxRoot is the tagged binary Merkle root over the live inbox messages' leaf digests, in ascending slot index. A free slot (Status == 0 && MsgID all-zero) is skipped.

func LiquidityRoot

func LiquidityRoot(entries []LiquidityLeaf) [Size]byte

LiquidityRoot is the tagged binary Merkle root over the active liquidity entries' leaf digests, in ascending slot index. An entry with Status == 0 is skipped.

func OutboxRoot

func OutboxRoot(outbox []MessageLeaf) [Size]byte

OutboxRoot is the tagged binary Merkle root over the live outbox messages' leaf digests, in ascending slot index. A free slot (Status == 0 && MsgID all-zero) is skipped.

func SignerSetRoot

func SignerSetRoot(signers []SignerLeaf) [Size]byte

SignerSetRoot is the tagged binary Merkle root over the occupied signers' leaf digests, in ascending slot index. A signer with Occupied == 0 is skipped. An empty occupied set yields keccak256("") (merkle.EmptyRoot).

func StateRoot

func StateRoot(
	parentStateRoot [Size]byte,
	signers []SignerLeaf,
	liquidity []LiquidityLeaf,
	inbox []MessageLeaf,
	outbox []MessageLeaf,
	daily []DailyLeaf,
	epoch uint64,
) (stateRoot, signerSetRoot, liquidityRoot, inboxRoot, outboxRoot, dailyLimitRoot [Size]byte, bondLo, bondHi uint64, active uint32)

StateRoot computes the full bridgevm_state_root over the round's POST-transition state: the five sub-roots (signer_set, liquidity, inbox, outbox, daily_limit) folded as RFC-6962 tagged binary Merkle trees, the full 128-bit active-bond aggregate computed over the signer set, then composed with the parent state root and finalized epoch. It is byte-identical to lux_<backend>_bridgevm_transition.

epoch is the finalized current epoch the GPU writes into the compose preimage (target_epoch = desc.epoch + closing_flag, used as current_epoch on a closing round; otherwise the carried current_epoch). The caller resolves it from the round descriptor exactly as the kernel does.

Types

type DailyLeaf

type DailyLeaf struct {
	AssetID     uint32
	Status      uint32
	DailyCapLo  uint64
	DailyCapHi  uint64
	UsedTodayLo uint64
	UsedTodayHi uint64
}

DailyLeaf is one bridgevm daily-limit entry in the accelerator's state-snapshot layout, holding the POST-reset field values. Its fields are hashed, in this exact order, into the leaf preimage:

AssetID ‖ Status ‖ DailyCapLo ‖ DailyCapHi ‖ UsedTodayLo ‖ UsedTodayHi ‖
index   (integers little-endian)

An entry with Status == 0 is skipped, matching the kernel's status-occupied check.

type LiquidityLeaf

type LiquidityLeaf struct {
	ProviderAddr [20]byte
	AssetID      uint32
	Status       uint32
	AmountLo     uint64
	AmountHi     uint64
	FeeAccrualLo uint64
	FeeAccrualHi uint64
}

LiquidityLeaf is one bridgevm liquidity entry in the accelerator's state-snapshot layout. Its fields are hashed, in this exact order, into the leaf preimage:

ProviderAddr[20] ‖ 0u32 ‖ AssetID ‖ Status ‖ AmountLo ‖ AmountHi ‖
FeeAccrualLo ‖ FeeAccrualHi ‖ index   (integers little-endian)

An entry with Status == 0 is skipped, matching the kernel's status-occupied check. The 0u32 after ProviderAddr is the GPU struct's _pad_addr.

type MessageLeaf

type MessageLeaf struct {
	MsgID       [32]byte
	PayloadRoot [32]byte
	Nonce       uint64
	SrcChain    uint32
	DstChain    uint32
	Kind        uint32
	Status      uint32
	AmountLo    uint64
	AmountHi    uint64
}

MessageLeaf is one bridgevm message (inbox or outbox) in the accelerator's state-snapshot layout. Its fields are hashed, in this exact order, into the leaf preimage:

MsgID[32] ‖ PayloadRoot[32] ‖ Nonce ‖ SrcChain ‖ DstChain ‖ Kind ‖
Status ‖ AmountLo ‖ AmountHi ‖ index   (integers little-endian)

A message that is FREE — Status == 0 AND MsgID is all-zero — is skipped, matching the kernel's free-slot predicate. (A nonzero MsgID OR a nonzero Status makes the slot live and folded.) The agg_signature, signers_bitmap, asset_id, signer_count and arrival_height fields of the GPU Message struct are NOT part of the leaf preimage and so are absent here.

type SignerLeaf

type SignerLeaf struct {
	SignerID       uint64
	LuxAddress     [20]byte
	BondLo         uint64
	BondHi         uint64
	OptInHeight    uint64
	ExitEpoch      uint64
	SignCount      uint64
	BLSPubkey      [48]byte
	CoronaPubkey   [32]byte
	MLDSAPubkey    [32]byte
	Status         uint32
	JailUntilEpoch uint32
	SlashCount     uint32
	Occupied       uint32
}

SignerLeaf is one bridgevm signer in the accelerator's state-snapshot layout, holding the POST-transition field values. Its fields are hashed, in this exact order, into the leaf preimage:

SignerID ‖ LuxAddress[20] ‖ 0u32 ‖ BondLo ‖ BondHi ‖ OptInHeight ‖
ExitEpoch ‖ SignCount ‖ BLSPubkey[48] ‖ CoronaPubkey[32] ‖ MLDSAPubkey[32] ‖
Status ‖ JailUntilEpoch ‖ SlashCount ‖ index   (integers little-endian)

A signer with Occupied == 0 is skipped (not folded), exactly as the kernel skips unoccupied slots. The 0u32 after LuxAddress is the GPU struct's _pad_addr, committed as four zero bytes.

Jump to

Keyboard shortcuts

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