mirror of
https://github.com/luxfi/proto.git
synced 2026-10-30 15:21:09 +00:00
proto required luxfi/node and luxfi/node required proto, with no replace directive on either side. The cycle was not load-bearing: most of it was proto reaching into the node for packages proto already owns — p/warp, p/txs, p/signer, p/stakeable, p/security, x/txs — which now name themselves. Two were real. The UTXO components moved here, where the chains that use them already live, and the node is the only other caller, so that dependency now runs one way. And p/config held the node's chain manager to queue a chain the P-Chain had accepted a CreateChainTx for; it calls one method, so it declares one method. A P-Chain that imports the node to describe QueueChainCreation is what made two modules require each other. Dropping the requirement dropped a registration with it: lux.ParseUTXO is a registry filled by an init, which the node used to link in on proto's behalf. The packages that call it now say so themselves. Co-authored-by: Hanzo Dev <[email protected]>
84 lines
2.3 KiB
Go
84 lines
2.3 KiB
Go
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package lux
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/luxfi/runtime"
|
|
|
|
"github.com/luxfi/ids"
|
|
"github.com/luxfi/vm/types"
|
|
)
|
|
|
|
// MaxMemoSize is the maximum number of bytes in the memo field
|
|
const MaxMemoSize = 256
|
|
|
|
var (
|
|
ErrNilTx = errors.New("nil tx is not valid")
|
|
ErrWrongNetworkID = errors.New("tx has wrong network ID")
|
|
ErrWrongChainID = errors.New("tx has wrong chain ID")
|
|
ErrMemoTooLarge = errors.New("memo exceeds maximum length")
|
|
)
|
|
|
|
// BaseTx is the basis of all standard transactions.
|
|
type BaseTx struct {
|
|
NetworkID uint32 `serialize:"true" json:"networkID"` // ID of the network this chain lives on
|
|
BlockchainID ids.ID `serialize:"true" json:"blockchainID"` // ID of the chain on which this transaction exists (prevents replay attacks)
|
|
Outs []*TransferableOutput `serialize:"true" json:"outputs"` // The outputs of this transaction
|
|
Ins []*TransferableInput `serialize:"true" json:"inputs"` // The inputs to this transaction
|
|
Memo types.JSONByteSlice `serialize:"true" json:"memo"` // Memo field contains arbitrary bytes, up to maxMemoSize
|
|
}
|
|
|
|
// InputUTXOs track which UTXOs this transaction is consuming.
|
|
func (t *BaseTx) InputUTXOs() []*UTXOID {
|
|
utxos := make([]*UTXOID, len(t.Ins))
|
|
for i, in := range t.Ins {
|
|
utxos[i] = &in.UTXOID
|
|
}
|
|
return utxos
|
|
}
|
|
|
|
// NumCredentials returns the number of expected credentials
|
|
func (t *BaseTx) NumCredentials() int {
|
|
return len(t.Ins)
|
|
}
|
|
|
|
// Verify ensures that transaction metadata is valid
|
|
func (t *BaseTx) Verify(rt *runtime.Runtime) error {
|
|
switch {
|
|
case t == nil:
|
|
return ErrNilTx
|
|
case t.NetworkID != rt.NetworkID:
|
|
return ErrWrongNetworkID
|
|
case t.BlockchainID != rt.ChainID:
|
|
return ErrWrongChainID
|
|
case len(t.Memo) > MaxMemoSize:
|
|
return fmt.Errorf(
|
|
"%w: %d > %d",
|
|
ErrMemoTooLarge,
|
|
len(t.Memo),
|
|
MaxMemoSize,
|
|
)
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// VerifyMemoFieldLength enforces the Lux memo-field length rule: under
|
|
// activate-all-implicitly the memo field must be empty on every tx.
|
|
func VerifyMemoFieldLength(memo types.JSONByteSlice, _ bool) error {
|
|
if len(memo) != 0 {
|
|
return fmt.Errorf(
|
|
"%w: %d > %d",
|
|
ErrMemoTooLarge,
|
|
len(memo),
|
|
0,
|
|
)
|
|
}
|
|
|
|
return nil
|
|
}
|