Files
node/vms/example/xsvm/execute/tx.go
T
zeekayandHanzo Dev 2d227dd3aa Full-codec-kill wave 2: proposervm + xsvm + components + evm + platformvm-residual → native ZAP
Kills pcodecs from 3 complete subsystems (verified go test ./... = 155 ok / 0 FAIL):
- proposervm: block/state/summary struct-is-wire (blockwire.go + statewire.go;
  deleted block/state/summary codec.go). blockKind bytes: reserved=0 signed=1
  option=2. Epoch inlined in unsigned object. proposer/windower chainSource seed
  = binary.LittleEndian (byte-identical to old wrappers.Packer.UnpackLong).
- example/xsvm: tx/block/genesis native Marshal (deleted 3 codec.go); create-chain
  example uses genesis.Marshal().
- components: message.Tx native (deleted codec.go); keystore codec shell removed;
  index pcodecs.LongLen → local const.
- evm/{predicate,lp176}: off pcodecs.
- platformvm residual: state metadata + genesis + metrics + signer + stakeable
  native, vestigial serialize tags removed.

REMAINING (careful solo, agents weekly-capped): warp (reverted — agent left an
ID≠Marshal consensus inconsistency in ChainToL1Conversion; needs proper review,
not a golden-regen) + xvm (reverted — barely started). pcodecs package stays
until those 2 land. /ext/→/v1/ endpoint change also pending.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
2026-07-11 17:19:20 -07:00

186 lines
3.9 KiB
Go

// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
// See the file LICENSE for licensing terms.
package execute
import (
"context"
"errors"
hash "github.com/luxfi/crypto/hash"
"github.com/luxfi/database"
"github.com/luxfi/ids"
"github.com/luxfi/node/vms/example/xsvm/state"
"github.com/luxfi/node/vms/example/xsvm/tx"
"github.com/luxfi/node/vms/platformvm/warp"
"github.com/luxfi/runtime"
"github.com/luxfi/utils/wrappers"
validators "github.com/luxfi/validators"
)
const (
QuorumNumerator = 2
QuorumDenominator = 3
)
var (
_ tx.Visitor = (*Tx)(nil)
errFeeTooHigh = errors.New("fee too high")
errWrongChainID = errors.New("wrong chainID")
errMissingBlockContext = errors.New("missing block context")
errDuplicateImport = errors.New("duplicate import")
)
type Tx struct {
Context context.Context
Runtime *runtime.Runtime
Database database.KeyValueReaderWriterDeleter
SkipVerify bool
BlockContext *runtime.Runtime
TxID ids.ID
Sender ids.ShortID
TransferFee uint64
ExportFee uint64
ImportFee uint64
}
func (t *Tx) Transfer(tf *tx.Transfer) error {
if tf.MaxFee < t.TransferFee {
return errFeeTooHigh
}
if tf.ChainID != t.Runtime.ChainID {
return errWrongChainID
}
return errors.Join(
state.IncrementNonce(t.Database, t.Sender, tf.Nonce),
state.DecreaseBalance(t.Database, t.Sender, tf.ChainID, t.TransferFee),
state.DecreaseBalance(t.Database, t.Sender, tf.AssetID, tf.Amount),
state.IncreaseBalance(t.Database, tf.To, tf.AssetID, tf.Amount),
)
}
func (t *Tx) Export(e *tx.Export) error {
if e.MaxFee < t.ExportFee {
return errFeeTooHigh
}
if e.ChainID != t.Runtime.ChainID {
return errWrongChainID
}
payload, err := tx.NewPayload(
t.Sender,
e.Nonce,
e.IsReturn,
e.Amount,
e.To,
)
if err != nil {
return err
}
message, err := warp.NewUnsignedMessage(
t.Runtime.NetworkID,
e.ChainID,
payload.Bytes(),
)
if err != nil {
return err
}
var errs wrappers.Errs
errs.Add(
state.IncrementNonce(t.Database, t.Sender, e.Nonce),
state.DecreaseBalance(t.Database, t.Sender, e.ChainID, t.ExportFee),
)
if e.IsReturn {
errs.Add(
state.DecreaseBalance(t.Database, t.Sender, e.PeerChainID, e.Amount),
)
} else {
errs.Add(
state.DecreaseBalance(t.Database, t.Sender, e.ChainID, e.Amount),
state.IncreaseLoan(t.Database, e.PeerChainID, e.Amount),
)
}
errs.Add(
state.SetMessage(t.Database, t.TxID, message),
)
return errs.Err
}
func (t *Tx) Import(i *tx.Import) error {
if i.MaxFee < t.ImportFee {
return errFeeTooHigh
}
if t.BlockContext == nil {
return errMissingBlockContext
}
message, err := warp.ParseMessage(i.Message)
if err != nil {
return err
}
var errs wrappers.Errs
errs.Add(
state.IncrementNonce(t.Database, t.Sender, i.Nonce),
state.DecreaseBalance(t.Database, t.Sender, t.Runtime.ChainID, t.ImportFee),
)
payload, err := tx.ParsePayload(message.Payload)
if err != nil {
return err
}
if payload.IsReturn {
errs.Add(
state.IncreaseBalance(t.Database, payload.To, t.Runtime.ChainID, payload.Amount),
state.DecreaseLoan(t.Database, message.SourceChainID, payload.Amount),
)
} else {
errs.Add(
state.IncreaseBalance(t.Database, payload.To, message.SourceChainID, payload.Amount),
)
}
var loanID ids.ID = hash.ComputeHash256Array(message.UnsignedMessage.Bytes())
hasLoanID, err := state.HasLoanID(t.Database, message.SourceChainID, loanID)
if hasLoanID {
return errDuplicateImport
}
errs.Add(
err,
state.AddLoanID(t.Database, message.SourceChainID, loanID),
)
if t.SkipVerify || errs.Errored() {
return errs.Err
}
validatorSet, err := warp.GetCanonicalValidatorSetFromChainID(
t.Context,
t.Runtime.ValidatorState.(validators.State),
t.BlockContext.PChainHeight,
message.SourceChainID,
)
if err != nil {
return err
}
return message.Signature.Verify(
&message.UnsignedMessage,
t.Runtime.NetworkID,
validatorSet,
QuorumNumerator,
QuorumDenominator,
)
}