mirror of
https://github.com/luxfi/node.git
synced 2026-07-27 03:39:39 +00:00
txs+wallet: deprecate AddChainValidatorTx under LP-018 sovereign-L1
Validators validate networks; chains live on networks. AddValidatorTx
is the universal add-validator-to-a-network tx whether the target
network is Lux primary (1/2/3/1337) or any downstream sovereign L1's
own primary at its chosen networkID. AddChainValidatorTx is legacy
and kept for one release cycle of wire/codec compat with pre-LP-018
binaries.
- vms/platformvm/txs/add_chain_validator_tx.go: file-header + struct
Deprecated: notice pointing to AddValidatorTx.
- vms/platformvm/txs/chain_validator.go: ChainValidator descriptor
marked Deprecated.
- vms/platformvm/txs/add_validator_test.go: new
TestAddValidatorTxSyntacticVerify_ArbitraryPrimaryNetworkIDs covers
Lux primaries (1/2/3/1337) plus four synthetic IDs across the uint32
range, asserting the tx body has no per-chain field and accepts any
valid primary networkID.
- wallet/chain/p/wallet/wallet.go + with_options.go: Deprecated on
IssueAddChainValidatorTx; IssueRemoveChainValidatorTx doc reworded
to network-centric language.
- wallet/chain/p/builder.go + builder/builder.go: Deprecated on
NewAddChainValidatorTx interfaces.
- wallet/network/primary/examples/{add-permissioned-chain-validator,
bootstrap-hanzo, deploy-chains}/main.go: file-header notes that
these examples exercise the legacy path; new code uses AddValidatorTx.
- node/validator_manager.go: 4 log strings + 1 comment block rewritten
to talk about network validator (not chain validator).
- vms/platformvm/health.go: error string 'current chain validator of'
→ 'current network validator on'.
This commit is contained in:
@@ -109,20 +109,23 @@ func (v *ValidatorManager) Connected(nodeID ids.NodeID, nodeVersion *version.App
|
||||
)
|
||||
}
|
||||
|
||||
// Also add to ALL tracked chain validator sets so chain consensus
|
||||
// engines can find validators for their chains. Without this, non-primary
|
||||
// chains can't gossip blocks because the validator set is empty.
|
||||
// Also add to ALL tracked network validator sets so each
|
||||
// network's consensus engine can find validators for the chains
|
||||
// it hosts. Without this, non-primary networks can't gossip
|
||||
// blocks because the validator set is empty. Under the
|
||||
// canonical model, validators validate networks; chains live on
|
||||
// networks.
|
||||
for _, networkID := range v.trackedNetworks {
|
||||
networkTxID := ids.Empty
|
||||
copy(networkTxID[:], nodeID.Bytes())
|
||||
if err := v.vdrs.AddStaker(networkID, nodeID, nil, networkTxID, v.weight); err != nil {
|
||||
v.log.Debug("failed to add chain validator on connect",
|
||||
v.log.Debug("failed to add network validator on connect",
|
||||
log.Stringer("nodeID", nodeID),
|
||||
log.Stringer("networkID", networkID),
|
||||
log.Reflect("error", err),
|
||||
)
|
||||
} else {
|
||||
v.log.Info("added chain validator on connect (sybil protection disabled)",
|
||||
v.log.Info("added network validator on connect (sybil protection disabled)",
|
||||
log.Stringer("nodeID", nodeID),
|
||||
log.Stringer("networkID", networkID),
|
||||
)
|
||||
@@ -173,10 +176,10 @@ func (v *ValidatorManager) Disconnected(nodeID ids.NodeID) {
|
||||
)
|
||||
}
|
||||
|
||||
// Also remove from all tracked chain validator sets
|
||||
// Also remove from all tracked network validator sets.
|
||||
for _, networkID := range v.trackedNetworks {
|
||||
if err := v.vdrs.RemoveWeight(networkID, nodeID, v.weight); err != nil {
|
||||
v.log.Debug("failed to remove chain validator on disconnect",
|
||||
v.log.Debug("failed to remove network validator on disconnect",
|
||||
log.Stringer("nodeID", nodeID),
|
||||
log.Stringer("networkID", networkID),
|
||||
)
|
||||
|
||||
@@ -38,7 +38,7 @@ func (vm *VM) HealthCheck(context.Context) (chain.HealthResult, error) {
|
||||
case database.ErrNotFound:
|
||||
vm.metrics.SetTimeUntilNetUnstake(chainID, 0)
|
||||
default:
|
||||
return chain.HealthResult{}, fmt.Errorf("couldn't get current chain validator of %q: %w", chainID, err)
|
||||
return chain.HealthResult{}, fmt.Errorf("couldn't get current network validator on %q: %w", chainID, err)
|
||||
}
|
||||
}
|
||||
return chain.HealthResult{Healthy: true, Details: nil}, nil
|
||||
|
||||
@@ -1,5 +1,19 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
//
|
||||
// File deprecation notice: this file defines AddChainValidatorTx, the
|
||||
// legacy per-chain validator registration tx. Under LP-018
|
||||
// (sovereign-L1), validators join a network — never a chain — via
|
||||
// AddValidatorTx. Chains live on networks (created via CreateChainTx);
|
||||
// the canonical model has validators validate networks, not chains. A
|
||||
// sovereign L1 IS a primary network at its own networkID; the Lux
|
||||
// primary networks live at 1/2/3/1337, and any downstream consumer
|
||||
// running its own primary picks any other uint32. AddValidatorTx is
|
||||
// the universal add-validator-to-a-network entry point for all of
|
||||
// them. New code must use AddValidatorTx. The wire codec entries,
|
||||
// Visitor method, and wallet IssueAddChainValidatorTx helper are kept
|
||||
// for one release cycle so existing pre-LP-018 P-chain history
|
||||
// continues to decode and replay.
|
||||
|
||||
package txs
|
||||
|
||||
@@ -21,7 +35,16 @@ var (
|
||||
errAddPrimaryNetworkValidator = errors.New("can't add primary network validator with AddChainValidatorTx")
|
||||
)
|
||||
|
||||
// AddChainValidatorTx is an unsigned addChainValidatorTx
|
||||
// AddChainValidatorTx is the legacy per-chain (legacy: per-subnet)
|
||||
// validator registration tx.
|
||||
//
|
||||
// Deprecated: Use AddValidatorTx. Under LP-018 sovereign-L1, validators
|
||||
// join a network (Lux primary 1/2/3/1337 or any sovereign L1's own
|
||||
// primary at its EVM chainID). Chains live on networks; validators no
|
||||
// longer register per-chain. This type is retained for one release
|
||||
// cycle for wire/codec compat with pre-LP-018 binaries. The Visitor
|
||||
// method, codec slots, and wallet IssueAddChainValidatorTx helper are
|
||||
// preserved so older P-chain history still decodes and replays.
|
||||
type AddChainValidatorTx struct {
|
||||
// Metadata, inputs and outputs
|
||||
BaseTx `serialize:"true"`
|
||||
|
||||
@@ -252,3 +252,124 @@ func TestAddValidatorTxNotDelegatorTx(t *testing.T) {
|
||||
_, ok := txIntf.(DelegatorTx)
|
||||
require.False(t, ok)
|
||||
}
|
||||
|
||||
// TestAddValidatorTxSyntacticVerify_ArbitraryPrimaryNetworkIDs asserts
|
||||
// that AddValidatorTx — the canonical post-LP-018 add-validator-to-a-
|
||||
// network tx — accepts arbitrary primary networkIDs, not just the Lux
|
||||
// primary values (1/2/3/1337). A sovereign L1 IS a primary network at
|
||||
// its own networkID; downstream consumers may operate primary networks
|
||||
// at any uint32 they choose. This test pins that contract: the tx body
|
||||
// has no per-chain "Chain" field, so SyntacticVerify must succeed
|
||||
// against any valid primary networkID.
|
||||
func TestAddValidatorTxSyntacticVerify_ArbitraryPrimaryNetworkIDs(t *testing.T) {
|
||||
// Lux primaries (1/2/3/1337) plus four arbitrary synthetic IDs
|
||||
// covering low / mid / high uint32 ranges, to demonstrate the tx
|
||||
// is networkID-agnostic without baking any downstream value into
|
||||
// this upstream test.
|
||||
primaryNetworkIDs := []uint32{
|
||||
1, // Lux mainnet
|
||||
2, // Lux testnet
|
||||
3, // Lux local
|
||||
1337, // Lux dev/localnet
|
||||
9001,
|
||||
123456,
|
||||
7_777_777,
|
||||
4_000_000_000,
|
||||
}
|
||||
|
||||
for _, networkID := range primaryNetworkIDs {
|
||||
networkID := networkID
|
||||
t.Run(formatPrimaryNetworkID(networkID), func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
clk := mockable.Clock{}
|
||||
utxoAssetID := ids.GenerateTestID()
|
||||
nodeID := ids.GenerateTestNodeID()
|
||||
testChainID := ids.GenerateTestID()
|
||||
rt := &runtime.Runtime{
|
||||
NetworkID: networkID,
|
||||
ChainID: testChainID,
|
||||
UTXOAssetID: utxoAssetID,
|
||||
NodeID: nodeID,
|
||||
}
|
||||
signers := [][]*secp256k1.PrivateKey{preFundedKeys}
|
||||
|
||||
validatorWeight := uint64(2026)
|
||||
rewardAddress := preFundedKeys[0].Address()
|
||||
inputs := []*lux.TransferableInput{{
|
||||
UTXOID: lux.UTXOID{
|
||||
TxID: ids.ID{'l', 'p', '0', '1', '8'},
|
||||
OutputIndex: 0,
|
||||
},
|
||||
Asset: lux.Asset{ID: utxoAssetID},
|
||||
In: &secp256k1fx.TransferInput{
|
||||
Amt: uint64(5678),
|
||||
Input: secp256k1fx.Input{SigIndices: []uint32{0}},
|
||||
},
|
||||
}}
|
||||
outputs := []*lux.TransferableOutput{{
|
||||
Asset: lux.Asset{ID: utxoAssetID},
|
||||
Out: &secp256k1fx.TransferOutput{
|
||||
Amt: uint64(1234),
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{preFundedKeys[0].Address()},
|
||||
},
|
||||
},
|
||||
}}
|
||||
stakes := []*lux.TransferableOutput{{
|
||||
Asset: lux.Asset{ID: utxoAssetID},
|
||||
Out: &stakeable.LockOut{
|
||||
Locktime: uint64(clk.Time().Add(time.Second).Unix()),
|
||||
TransferableOut: &secp256k1fx.TransferOutput{
|
||||
Amt: validatorWeight,
|
||||
OutputOwners: secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{preFundedKeys[0].Address()},
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
addValidatorTx := &AddValidatorTx{
|
||||
BaseTx: BaseTx{BaseTx: lux.BaseTx{
|
||||
NetworkID: rt.NetworkID,
|
||||
BlockchainID: rt.ChainID,
|
||||
Ins: inputs,
|
||||
Outs: outputs,
|
||||
}},
|
||||
Validator: Validator{
|
||||
NodeID: rt.NodeID,
|
||||
Start: uint64(clk.Time().Unix()),
|
||||
End: uint64(clk.Time().Add(time.Hour).Unix()),
|
||||
Wght: validatorWeight,
|
||||
},
|
||||
StakeOuts: stakes,
|
||||
RewardsOwner: &secp256k1fx.OutputOwners{
|
||||
Locktime: 0,
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{rewardAddress},
|
||||
},
|
||||
DelegationShares: reward.PercentDenominator,
|
||||
}
|
||||
|
||||
stx, err := NewSigned(addValidatorTx, Codec, signers)
|
||||
require.NoError(err)
|
||||
require.NoError(stx.SyntacticVerify(rt))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func formatPrimaryNetworkID(id uint32) string {
|
||||
switch id {
|
||||
case 1:
|
||||
return "lux-mainnet-1"
|
||||
case 2:
|
||||
return "lux-testnet-2"
|
||||
case 3:
|
||||
return "lux-local-3"
|
||||
case 1337:
|
||||
return "lux-dev-1337"
|
||||
default:
|
||||
return fmt.Sprintf("primary-networkID-%d", id)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,15 @@ import (
|
||||
"github.com/luxfi/ids"
|
||||
)
|
||||
|
||||
// ChainValidator validates a chain on the Lux network.
|
||||
// ChainValidator is the legacy per-chain validator descriptor used by
|
||||
// AddChainValidatorTx. The Chain field is the network ID this validator
|
||||
// registers under (legacy: subnet ID).
|
||||
//
|
||||
// Deprecated: Use Validator with AddValidatorTx. Under LP-018
|
||||
// sovereign-L1, validators validate networks — not chains. Chains live
|
||||
// on networks (created via CreateChainTx); validators no longer
|
||||
// register per-chain. Retained for one release cycle for wire/codec
|
||||
// compat with pre-LP-018 binaries.
|
||||
type ChainValidator struct {
|
||||
Validator `serialize:"true"`
|
||||
|
||||
|
||||
@@ -77,10 +77,16 @@ type Builder interface {
|
||||
options ...common.Option,
|
||||
) (*txs.AddValidatorTx, error)
|
||||
|
||||
// NewAddChainValidatorTx creates a new validator of a chain.
|
||||
// NewAddChainValidatorTx builds an unsigned legacy per-chain
|
||||
// validator registration tx.
|
||||
//
|
||||
// - [vdr] specifies all the details of the validation period such as the
|
||||
// startTime, endTime, sampling weight, nodeID, and netID.
|
||||
//
|
||||
// Deprecated: Use NewAddValidatorTx. Under LP-018 sovereign-L1,
|
||||
// validators join a network — never a chain. A sovereign L1 IS a
|
||||
// primary network at its own networkID. Retained for one release
|
||||
// cycle for wire/codec compat with pre-LP-018 binaries.
|
||||
NewAddChainValidatorTx(
|
||||
vdr *txs.ChainValidator,
|
||||
options ...common.Option,
|
||||
|
||||
@@ -84,10 +84,16 @@ type Builder interface {
|
||||
options ...common.Option,
|
||||
) (*txs.AddValidatorTx, error)
|
||||
|
||||
// NewAddChainValidatorTx creates a new validator of a chain.
|
||||
// NewAddChainValidatorTx builds an unsigned legacy per-chain
|
||||
// validator registration tx.
|
||||
//
|
||||
// - [vdr] specifies all the details of the validation period such as the
|
||||
// startTime, endTime, sampling weight, nodeID, and netID.
|
||||
//
|
||||
// Deprecated: Use NewAddValidatorTx. Under LP-018 sovereign-L1,
|
||||
// validators join a network — never a chain. A sovereign L1 IS a
|
||||
// primary network at its own networkID. Retained for one release
|
||||
// cycle for wire/codec compat with pre-LP-018 binaries.
|
||||
NewAddChainValidatorTx(
|
||||
vdr *txs.ChainValidator,
|
||||
options ...common.Option,
|
||||
|
||||
@@ -63,20 +63,31 @@ type Wallet interface {
|
||||
options ...common.Option,
|
||||
) (*txs.Tx, error)
|
||||
|
||||
// IssueAddChainValidatorTx creates, signs, and issues a new validator of a
|
||||
// chain.
|
||||
// IssueAddChainValidatorTx creates, signs, and issues a legacy
|
||||
// per-chain validator registration tx.
|
||||
//
|
||||
// - [vdr] specifies all the details of the validation period such as the
|
||||
// startTime, endTime, sampling weight, nodeID, and chainID.
|
||||
//
|
||||
// Deprecated: Use IssueAddValidatorTx. Under LP-018 sovereign-L1,
|
||||
// validators join a network — never a chain — via AddValidatorTx.
|
||||
// Chains live on networks (created via CreateChainTx); the
|
||||
// canonical model has validators validate networks, not chains. A
|
||||
// sovereign L1 IS a primary network at its own networkID (Lux
|
||||
// primaries at 1/2/3/1337; any downstream consumer's primary at
|
||||
// whatever uint32 it picks). Retained for one release cycle for
|
||||
// wire/codec compat with pre-LP-018 binaries.
|
||||
IssueAddChainValidatorTx(
|
||||
vdr *txs.ChainValidator,
|
||||
options ...common.Option,
|
||||
) (*txs.Tx, error)
|
||||
|
||||
// IssueRemoveChainValidatorTx creates, signs, and issues a transaction
|
||||
// that removes a validator of a chain.
|
||||
// IssueRemoveChainValidatorTx creates, signs, and issues a
|
||||
// transaction that removes a validator from a network (legacy:
|
||||
// from a chain's permissioned validator set).
|
||||
//
|
||||
// - [nodeID] is the validator being removed from [chainID].
|
||||
// - [nodeID] is the validator being removed from the network
|
||||
// referenced by [chainID].
|
||||
IssueRemoveChainValidatorTx(
|
||||
nodeID ids.NodeID,
|
||||
chainID ids.ID,
|
||||
@@ -365,6 +376,8 @@ func (w *wallet) IssueAddValidatorTx(
|
||||
return w.IssueUnsignedTx(utx, options...)
|
||||
}
|
||||
|
||||
// Deprecated: Use IssueAddValidatorTx. See the interface declaration
|
||||
// for the LP-018 migration note.
|
||||
func (w *wallet) IssueAddChainValidatorTx(
|
||||
vdr *txs.ChainValidator,
|
||||
options ...common.Option,
|
||||
|
||||
@@ -70,7 +70,9 @@ func (w *withOptions) IssueAddValidatorTx(
|
||||
)
|
||||
}
|
||||
|
||||
// Removed in regenesis
|
||||
// Deprecated: Use IssueAddValidatorTx. Under LP-018 sovereign-L1,
|
||||
// validators join a network — never a chain. See the wallet interface
|
||||
// declaration for the full migration note.
|
||||
func (w *withOptions) IssueAddChainValidatorTx(
|
||||
vdr *txs.ChainValidator,
|
||||
options ...common.Option,
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
// Copyright (C) 2019-2025, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
//
|
||||
// Deprecated example: this binary exercises the legacy
|
||||
// AddChainValidatorTx flow (validator scoped to a non-primary network
|
||||
// id). Under LP-018 sovereign-L1, validators join a network — never a
|
||||
// chain — via AddValidatorTx. A sovereign L1 IS a primary network at
|
||||
// its own networkID; new code should issue AddValidatorTx against that
|
||||
// primary network. This example is kept to exercise the deprecated tx
|
||||
// path for one release cycle.
|
||||
|
||||
package main
|
||||
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
// MNEMONIC="..." go run . --uri=http://localhost:19640 --network=testnet \
|
||||
// --genesis=/Users/z/work/lux/genesis/configs/hanzo-testnet/genesis.json \
|
||||
// --hrp=test --bip44-idx=5
|
||||
//
|
||||
// Deprecated post-chain-create flow: after CreateChainTx, this binary
|
||||
// adds validators to the created network via the legacy
|
||||
// IssueAddChainValidatorTx. Under LP-018 sovereign-L1, validators join
|
||||
// a network via AddValidatorTx — chains live on networks, validators
|
||||
// do not register per-chain. The legacy call is preserved for one
|
||||
// release cycle for wire/codec compat with pre-LP-018 binaries.
|
||||
package main
|
||||
|
||||
import (
|
||||
|
||||
@@ -5,6 +5,13 @@
|
||||
// MNEMONIC="word1 word2 ..." go run . --network=mainnet
|
||||
// go run . --network=mainnet mainnet-key-01
|
||||
// MNEMONIC="word1 word2 ..." go run . --network=mainnet --chain=zoo
|
||||
//
|
||||
// Deprecated post-chain-create flow: after CreateChainTx, this binary
|
||||
// adds validators to the created network via the legacy
|
||||
// IssueAddChainValidatorTx. Under LP-018 sovereign-L1, validators join
|
||||
// a network via AddValidatorTx — chains live on networks, validators
|
||||
// do not register per-chain. The legacy call is preserved for one
|
||||
// release cycle for wire/codec compat with pre-LP-018 binaries.
|
||||
package main
|
||||
|
||||
import (
|
||||
|
||||
Reference in New Issue
Block a user