Files
zeekayandHanzo Dev 938b06d485 Stop requiring the node this module is imported by
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]>
2026-09-06 12:49:55 -07:00

49 lines
1.8 KiB
Go

package conformance
import (
"testing"
"github.com/luxfi/ids"
nodestakeable "github.com/luxfi/proto/p/stakeable"
protostakeable "github.com/luxfi/proto/p/stakeable"
"github.com/luxfi/utxo/secp256k1fx"
)
// A stakeable-locked output is serialized by proto when the wallet BUILDS a tx
// and by the node when it PARSES one. The canonical output sort compares
// exactly those bytes, so a second encoding is not a cosmetic difference: the
// two sides order the outputs differently and the chain rejects the tx with
// "outputs not sorted". That is what happened to the first real
// AddPermissionlessDelegatorTx issued against mainnet — proto emitted an ad-hoc
// 0xFF||locktime||inner marker while the chain emits the shared
// wire.LockedOutput envelope.
//
// TestWire's fixtures are all unlocked outputs, so nothing covered this.
func TestLockOutWireMatchesChain(t *testing.T) {
inner := &secp256k1fx.TransferOutput{
Amt: 4998000000000000,
OutputOwners: secp256k1fx.OutputOwners{
Threshold: 1,
Addrs: []ids.ShortID{{1, 2, 3}},
},
}
const locktime = uint64(0x90cc4f80)
proto := (&protostakeable.LockOut{Locktime: locktime, TransferableOut: inner}).Bytes()
node := (&nodestakeable.LockOut{Locktime: locktime, TransferableOut: inner}).Bytes()
t.Logf("proto len=%d %x", len(proto), proto)
t.Logf("node len=%d %x", len(node), node)
if string(proto) != string(node) {
t.Fatalf("LockOut wire fork: proto %d bytes, node %d bytes", len(proto), len(node))
}
// Positive control: the comparison can fail. A different locktime must
// produce different bytes, otherwise the check above proves nothing.
other := (&nodestakeable.LockOut{Locktime: locktime + 1, TransferableOut: inner}).Bytes()
if string(node) == string(other) {
t.Fatal("control failed: locktime is not reflected in the wire bytes")
}
}