mirror of
https://github.com/luxfi/node.git
synced 2026-07-27 03:39:39 +00:00
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>
186 lines
3.9 KiB
Go
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,
|
|
)
|
|
}
|
|
|