mirror of
https://github.com/luxfi/netrunner.git
synced 2026-07-27 00:04:23 +00:00
feat: Improve genesis config and graceful shutdown handling
- Add treasury and ewoq allocations to mainnet genesis - Use proper treasury address for reward and stake allocations - Add ewoq allocation with immediately available P-chain funds - Improve graceful shutdown exit code handling (accept 0, -1, 2, 130, 143) - Update dependencies: node v1.21.5, genesis v1.2.5, evm v0.8.1 - Remove local replace directive for genesis
This commit is contained in:
@@ -9,14 +9,14 @@ require (
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1
|
||||
github.com/luxfi/consensus v1.22.2
|
||||
github.com/luxfi/crypto v1.17.7
|
||||
github.com/luxfi/evm v1.16.20
|
||||
github.com/luxfi/genesis v1.2.4
|
||||
github.com/luxfi/evm v0.8.1
|
||||
github.com/luxfi/genesis v1.2.5
|
||||
github.com/luxfi/geth v1.16.40
|
||||
github.com/luxfi/ids v1.1.2
|
||||
github.com/luxfi/log v1.1.24
|
||||
github.com/luxfi/math v0.1.5
|
||||
github.com/luxfi/metric v1.4.5
|
||||
github.com/luxfi/node v1.21.3
|
||||
github.com/luxfi/node v1.21.5
|
||||
github.com/onsi/ginkgo/v2 v2.25.1
|
||||
github.com/onsi/gomega v1.38.0
|
||||
github.com/otiai10/copy v1.14.1
|
||||
@@ -96,7 +96,7 @@ require (
|
||||
github.com/luxfi/ledger-lux-go v1.0.0 // indirect
|
||||
github.com/luxfi/mock v0.1.0 // indirect
|
||||
github.com/luxfi/trace v0.1.2 // indirect
|
||||
github.com/luxfi/warp v1.16.19 // indirect
|
||||
github.com/luxfi/warp v1.16.26 // indirect
|
||||
github.com/mr-tron/base58 v1.2.0 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/otiai10/mint v1.6.3 // indirect
|
||||
|
||||
@@ -283,10 +283,10 @@ github.com/luxfi/crypto v1.17.7 h1:zo0M6/exQiNn825cUmDL4SgmY2ZjZkIyMb2wc5WCHyg=
|
||||
github.com/luxfi/crypto v1.17.7/go.mod h1:5Lg/6cio6nAwo0iEwnzMtDcacRuOWuuR/QEg3b4AEHw=
|
||||
github.com/luxfi/database v1.2.7 h1:FpPfvl6C4/DqeP9OrV5LbeUAFxmDyBgHP8CcvSO2D1c=
|
||||
github.com/luxfi/database v1.2.7/go.mod h1:yZGYMY97Ca0pboIyOQ5JTD/ErvpW4bGot7rUvfMn5ko=
|
||||
github.com/luxfi/evm v1.16.20 h1:w1xyLgCvKSrwjko79K76xnPQQVwMeSs2j4wa6vvf8XY=
|
||||
github.com/luxfi/evm v1.16.20/go.mod h1:/440wuInsyyuZWMAN8Cr4AcvYpCCf/miGoOzDCHyR00=
|
||||
github.com/luxfi/genesis v1.2.4 h1:7cy2nKKnpnI03fVvXAClsNMwgI5+EaUF94chZ8c8+wQ=
|
||||
github.com/luxfi/genesis v1.2.4/go.mod h1:wMBXXh4V3JntkWfQhOI/Rrv4mzGIuC+VN1aDgb6I2iM=
|
||||
github.com/luxfi/evm v0.8.1 h1:DmQC5UETgunf4e0HGHkeDJCFwU2dOflcHLDICvszN7g=
|
||||
github.com/luxfi/evm v0.8.1/go.mod h1:ufY7D5sJ9mPUsj1ijuTXUU/ymiMoPoEI1mkjde3H1aA=
|
||||
github.com/luxfi/genesis v1.2.5 h1:FQLpYZ4Mi3vYZOgLPeJZZMkexIdp+feTrTtSGRUv7Oc=
|
||||
github.com/luxfi/genesis v1.2.5/go.mod h1:wMBXXh4V3JntkWfQhOI/Rrv4mzGIuC+VN1aDgb6I2iM=
|
||||
github.com/luxfi/geth v1.16.40 h1:26dLZh0huxAm2/iiMac2pzwh7mlMXyJafW2Tj22qqjc=
|
||||
github.com/luxfi/geth v1.16.40/go.mod h1:sfmc/YJ0EaaNP5PJmD31yTaSP6VLSvwvOUCViTSZa0I=
|
||||
github.com/luxfi/ids v1.1.2 h1:+qCUzE9Ga4slSHbnYl7T3I6c8y+n4/kKk4rzSEkLv/k=
|
||||
@@ -301,12 +301,12 @@ github.com/luxfi/metric v1.4.5 h1:fD6gtpzB5ebGB06/m4K7e5+tOV5RiVHSZCV+Zb8ZDxk=
|
||||
github.com/luxfi/metric v1.4.5/go.mod h1:AUQ7NSNz9WndAcr/SKnOkP7XSFFnBXOa+ihtJYfDaQY=
|
||||
github.com/luxfi/mock v0.1.0 h1:IwElfNu+T9sXvzFX6tudPDx1vqPuACRSRdxpD5lxW+o=
|
||||
github.com/luxfi/mock v0.1.0/go.mod h1:izF+9K0gGzFC9zERn6Po37v46eLdPB+EIsDjL3GLk+U=
|
||||
github.com/luxfi/node v1.21.3 h1:yzI+lrBBK44SY2J7eUNoOdIfTKMseVTWXmiuPj+5tpA=
|
||||
github.com/luxfi/node v1.21.3/go.mod h1:aI8Oh/B/U1o79Kl09yYmSkJwsFbXC0YLQ4dMvu9d/YY=
|
||||
github.com/luxfi/node v1.21.5 h1:k9ov99r/kMhWg/ADgM5xv/OxrMK59iw9YtENCi+vTNg=
|
||||
github.com/luxfi/node v1.21.5/go.mod h1:P8oadRkpiRU0Ezuj48KTUhZRGoJEdB8EbPEeMbXWnR4=
|
||||
github.com/luxfi/trace v0.1.2 h1:KhRZbk2lQQmmYZjdTWcZKCYkLfu7/VUiLFIsWFKhkwg=
|
||||
github.com/luxfi/trace v0.1.2/go.mod h1:4SleFc5NVbQYEfn6rYafdfxvHJ+QSdkGAIfKiICYvQE=
|
||||
github.com/luxfi/warp v1.16.19 h1:zzaYbJN1H8b/3hjsybvxVaECuCFLCtRNxwFBBTsP0t8=
|
||||
github.com/luxfi/warp v1.16.19/go.mod h1:xXgLbBlGLE1Q64yGsPUvjSYu+Go192BECGjgm2xq1hM=
|
||||
github.com/luxfi/warp v1.16.26 h1:XawtVax9UXd9NbIuQt4aY74ypfAvzkypW4LqdIuBnHM=
|
||||
github.com/luxfi/warp v1.16.26/go.mod h1:Ny3H4lBhhJNblQbIsWjvi2Ewg6VRUBvkKsQ+WzAqrck=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
|
||||
+93
-28
@@ -212,6 +212,12 @@ func (ln *localNetwork) installCustomChains(
|
||||
fmt.Println()
|
||||
ln.log.Info(luxlog.Blue.Wrap(luxlog.Bold.Wrap("create and install custom chains")))
|
||||
|
||||
// Ensure nodes are healthy before proceeding (nodes may have been restarted by a prior
|
||||
// CreateSubnets call which restarts nodes to track subnets)
|
||||
if err := ln.healthy(ctx); err != nil {
|
||||
return nil, fmt.Errorf("network not healthy at start of installCustomChains: %w", err)
|
||||
}
|
||||
|
||||
clientURI, err := ln.getClientURI()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -443,6 +449,12 @@ func (ln *localNetwork) installSubnets(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Wait for nodes to be healthy after restart before querying P-Chain
|
||||
ln.log.Info("waiting for nodes to be healthy after restart...")
|
||||
if err := ln.healthy(ctx); err != nil {
|
||||
return nil, fmt.Errorf("nodes not healthy after restart: %w", err)
|
||||
}
|
||||
|
||||
if err = ln.waitSubnetValidators(ctx, platformCli, subnetIDs, subnetSpecs); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -636,7 +648,13 @@ func (ln *localNetwork) restartNodes(
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err := ln.healthy(ctx); err != nil {
|
||||
// Use a fresh context for health check during planned restarts to avoid
|
||||
// context cancellation from onStopCh which is triggered during node restarts.
|
||||
// The parent context (ctx) can be canceled by the stop channel during restartNode,
|
||||
// but we still need to wait for nodes to become healthy after restart.
|
||||
healthCtx, healthCancel := context.WithTimeout(context.Background(), defaultTimeout)
|
||||
defer healthCancel()
|
||||
if err := ln.healthy(healthCtx); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@@ -659,16 +677,22 @@ func newWallet(
|
||||
preloadTXs []ids.ID,
|
||||
) (*wallet, error) {
|
||||
kc := secp256k1fx.NewKeychain(genesis.EWOQKey)
|
||||
luxState, err := primary.FetchState(ctx, uri, kc.Addrs)
|
||||
// Use dedicated timeout context for FetchState to avoid parent context cancellation propagation
|
||||
fetchCtx, fetchCancel := createDefaultCtx(ctx)
|
||||
luxState, err := primary.FetchState(fetchCtx, uri, kc.Addrs)
|
||||
fetchCancel()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("failed to fetch state from %s: %w", uri, err)
|
||||
}
|
||||
pClient := platformvm.NewClient(uri)
|
||||
pTXs := make(map[ids.ID]*txs.Tx)
|
||||
for _, id := range preloadTXs {
|
||||
txBytes, err := pClient.GetTx(ctx, id)
|
||||
// Use dedicated timeout context for GetTx to avoid parent context cancellation propagation
|
||||
getTxCtx, getTxCancel := createDefaultCtx(ctx)
|
||||
txBytes, err := pClient.GetTx(getTxCtx, id)
|
||||
getTxCancel()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, fmt.Errorf("failed to get tx %s: %w", id, err)
|
||||
}
|
||||
tx, err := txs.Parse(txs.Codec, txBytes)
|
||||
if err != nil {
|
||||
@@ -772,6 +796,7 @@ func (ln *localNetwork) addPrimaryValidators(
|
||||
},
|
||||
10*10000, // 10% fee percent, times 10000 to make it as shares
|
||||
common.WithContext(ctx),
|
||||
defaultPoll,
|
||||
)
|
||||
cancel()
|
||||
if err != nil {
|
||||
@@ -804,6 +829,7 @@ func getXChainAssetID(ctx context.Context, w *wallet, tokenName string, tokenSym
|
||||
},
|
||||
},
|
||||
common.WithContext(ctx),
|
||||
defaultPoll,
|
||||
)
|
||||
if err != nil {
|
||||
return ids.Empty, err
|
||||
@@ -827,6 +853,7 @@ func exportXChainToPChain(ctx context.Context, w *wallet, owner *secp256k1fx.Out
|
||||
},
|
||||
},
|
||||
},
|
||||
common.WithContext(ctx),
|
||||
defaultPoll,
|
||||
)
|
||||
return err
|
||||
@@ -839,6 +866,7 @@ func importPChainFromXChain(ctx context.Context, w *wallet, owner *secp256k1fx.O
|
||||
_, err := pWallet.IssueImportTx(
|
||||
xChainID,
|
||||
owner,
|
||||
common.WithContext(ctx),
|
||||
defaultPoll,
|
||||
)
|
||||
return err
|
||||
@@ -894,11 +922,12 @@ func (ln *localNetwork) removeSubnetValidators(
|
||||
if isValidator := subnetValidators.Contains(nodeID); !isValidator {
|
||||
return fmt.Errorf("node %s is currently not a subnet validator of subnet %s", nodeName, subnetID.String())
|
||||
}
|
||||
_, cancel := createDefaultCtx(ctx)
|
||||
ctx, cancel := createDefaultCtx(ctx)
|
||||
tx, err := w.pWallet.IssueRemoveNetValidatorTx(
|
||||
nodeID,
|
||||
subnetID,
|
||||
defaultPoll,
|
||||
common.WithContext(ctx),
|
||||
defaultPoll,
|
||||
)
|
||||
cancel()
|
||||
if err != nil {
|
||||
@@ -982,7 +1011,7 @@ func (ln *localNetwork) addPermissionlessValidators(
|
||||
|
||||
for _, validatorSpec := range validatorSpecs {
|
||||
ln.log.Info(luxlog.Green.Wrap("adding permissionless validator"), "node ", validatorSpec.NodeName)
|
||||
_, cancel := createDefaultCtx(ctx)
|
||||
ctx, cancel := createDefaultCtx(ctx)
|
||||
validatorNodeID := ln.nodes[validatorSpec.NodeName].nodeID
|
||||
subnetID, err := ids.FromString(validatorSpec.SubnetID)
|
||||
if err != nil {
|
||||
@@ -1020,7 +1049,8 @@ func (ln *localNetwork) addPermissionlessValidators(
|
||||
owner,
|
||||
&secp256k1fx.OutputOwners{},
|
||||
reward.PercentDenominator,
|
||||
defaultPoll,
|
||||
common.WithContext(ctx),
|
||||
defaultPoll,
|
||||
)
|
||||
cancel()
|
||||
if err != nil {
|
||||
@@ -1089,13 +1119,14 @@ func (ln *localNetwork) transformToElasticSubnets(
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
_, cancel := createDefaultCtx(ctx)
|
||||
ctx, cancel := createDefaultCtx(ctx)
|
||||
transformSubnetTx, err := w.pWallet.IssueTransformNetTx(subnetID, subnetAssetID,
|
||||
elasticSubnetSpec.InitialSupply, elasticSubnetSpec.MaxSupply, elasticSubnetSpec.MinConsumptionRate,
|
||||
elasticSubnetSpec.MaxConsumptionRate, elasticSubnetSpec.MinValidatorStake, elasticSubnetSpec.MaxValidatorStake,
|
||||
elasticSubnetSpec.MinStakeDuration, elasticSubnetSpec.MaxStakeDuration, elasticSubnetSpec.MinDelegationFee,
|
||||
elasticSubnetSpec.MinDelegatorStake, elasticSubnetSpec.MaxValidatorWeightFactor, elasticSubnetSpec.UptimeRequirement,
|
||||
defaultPoll,
|
||||
common.WithContext(ctx),
|
||||
defaultPoll,
|
||||
)
|
||||
cancel()
|
||||
if err != nil {
|
||||
@@ -1127,13 +1158,14 @@ func createSubnets(
|
||||
subnetIDs := make([]ids.ID, numSubnets)
|
||||
for i := uint32(0); i < numSubnets; i++ {
|
||||
log.Info("creating subnet tx")
|
||||
_, cancel := createDefaultCtx(ctx)
|
||||
ctx, cancel := createDefaultCtx(ctx)
|
||||
tx, err := w.pWallet.IssueCreateNetTx(
|
||||
&secp256k1fx.OutputOwners{
|
||||
Threshold: 1,
|
||||
Addrs: []ids.ShortID{w.addr},
|
||||
},
|
||||
defaultPoll,
|
||||
common.WithContext(ctx),
|
||||
defaultPoll,
|
||||
)
|
||||
cancel()
|
||||
if err != nil {
|
||||
@@ -1159,22 +1191,28 @@ func (ln *localNetwork) addSubnetValidators(
|
||||
) error {
|
||||
ln.log.Info(luxlog.Green.Wrap("adding the nodes as subnet validators"))
|
||||
for i, subnetID := range subnetIDs {
|
||||
ln.log.Info("getting primary validators for subnet", "index", i, "subnet-ID", subnetID.String())
|
||||
ctx, cancel := createDefaultCtx(ctx)
|
||||
vs, err := platformCli.GetCurrentValidators(ctx, constants.PrimaryNetworkID, nil)
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
ln.log.Error("failed to get primary validators", "error", err.Error())
|
||||
return fmt.Errorf("failed to get primary validators: %w", err)
|
||||
}
|
||||
ln.log.Info("got primary validators", "count", len(vs))
|
||||
primaryValidatorsEndtime := make(map[ids.NodeID]time.Time)
|
||||
for _, v := range vs {
|
||||
primaryValidatorsEndtime[v.NodeID] = time.Unix(int64(v.EndTime), 0)
|
||||
}
|
||||
ln.log.Info("getting current validators for subnet", "subnet-ID", subnetID.String())
|
||||
ctx, cancel = createDefaultCtx(ctx)
|
||||
vs, err = platformCli.GetCurrentValidators(ctx, subnetID, nil)
|
||||
cancel()
|
||||
if err != nil {
|
||||
return err
|
||||
ln.log.Error("failed to get current validators for subnet", "subnet-ID", subnetID.String(), "error", err.Error())
|
||||
return fmt.Errorf("failed to get current validators for subnet %s: %w", subnetID.String(), err)
|
||||
}
|
||||
ln.log.Info("got current validators for subnet", "subnet-ID", subnetID.String(), "count", len(vs))
|
||||
subnetValidators := set.Set[ids.NodeID]{}
|
||||
for _, v := range vs {
|
||||
subnetValidators.Add(v.NodeID)
|
||||
@@ -1189,7 +1227,7 @@ func (ln *localNetwork) addSubnetValidators(
|
||||
if isValidator := subnetValidators.Contains(nodeID); isValidator {
|
||||
continue
|
||||
}
|
||||
_, cancel := createDefaultCtx(ctx)
|
||||
ctx, cancel := createDefaultCtx(ctx)
|
||||
tx, err := w.pWallet.IssueAddNetValidatorTx(
|
||||
&txs.NetValidator{
|
||||
Validator: txs.Validator{
|
||||
@@ -1201,7 +1239,8 @@ func (ln *localNetwork) addSubnetValidators(
|
||||
},
|
||||
Net: subnetID,
|
||||
},
|
||||
defaultPoll,
|
||||
common.WithContext(ctx),
|
||||
defaultPoll,
|
||||
)
|
||||
cancel()
|
||||
if err != nil {
|
||||
@@ -1361,6 +1400,7 @@ func createBlockchainTxs(
|
||||
nil,
|
||||
vmName,
|
||||
common.WithContext(ctx),
|
||||
defaultPoll,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failure creating blockchain tx: %w", err)
|
||||
@@ -1454,7 +1494,7 @@ func (ln *localNetwork) setSubnetConfigFiles(
|
||||
return nil
|
||||
}
|
||||
|
||||
func (*localNetwork) createBlockchains(
|
||||
func (ln *localNetwork) createBlockchains(
|
||||
ctx context.Context,
|
||||
chainSpecs []network.BlockchainSpec,
|
||||
blockchainTxs []*txs.Tx,
|
||||
@@ -1463,29 +1503,52 @@ func (*localNetwork) createBlockchains(
|
||||
) error {
|
||||
fmt.Println()
|
||||
log.Info(luxlog.Green.Wrap("creating each custom chain"))
|
||||
|
||||
// Get platform client to check tx status
|
||||
clientURI, err := ln.getClientURI()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pClient := platformvm.NewClient(clientURI)
|
||||
|
||||
for i, chainSpec := range chainSpecs {
|
||||
vmName := chainSpec.VMName
|
||||
vmID, err := utils.VMID(vmName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
blockchainID := blockchainTxs[i].ID()
|
||||
|
||||
log.Info("creating blockchain",
|
||||
"vm-name", vmName,
|
||||
"vm-ID", vmID.String(),
|
||||
"blockchain-ID", blockchainID.String(),
|
||||
)
|
||||
|
||||
ctx, cancel := createDefaultCtx(ctx)
|
||||
defer cancel()
|
||||
// Check if the transaction was already committed (from createBlockchainTxs)
|
||||
// This can happen when nodes are restarted between tx creation and this call
|
||||
checkCtx, checkCancel := createDefaultCtx(ctx)
|
||||
txStatus, err := pClient.GetTxStatus(checkCtx, blockchainID)
|
||||
checkCancel()
|
||||
if err == nil && txStatus.Status.String() == "Committed" {
|
||||
log.Info("blockchain tx already committed, skipping re-issue",
|
||||
"vm-name", vmName,
|
||||
"blockchain-ID", blockchainID.String(),
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
issueCtx, issueCancel := createDefaultCtx(ctx)
|
||||
defer issueCancel()
|
||||
|
||||
err = w.pWallet.IssueTx(
|
||||
blockchainTxs[i],
|
||||
common.WithContext(ctx),
|
||||
common.WithContext(issueCtx),
|
||||
defaultPoll,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("P-Wallet Tx Error %s %w, blockchainID %s", "IssueCreateBlockchainTx", err, blockchainTxs[i].ID().String())
|
||||
return fmt.Errorf("P-Wallet Tx Error %s %w, blockchainID %s", "IssueCreateBlockchainTx", err, blockchainID.String())
|
||||
}
|
||||
blockchainID := blockchainTxs[i].ID()
|
||||
|
||||
log.Info("created a new blockchain",
|
||||
"vm-name", vmName,
|
||||
@@ -1497,9 +1560,11 @@ func (*localNetwork) createBlockchains(
|
||||
return nil
|
||||
}
|
||||
|
||||
func createDefaultCtx(ctx context.Context) (context.Context, context.CancelFunc) {
|
||||
if ctx == nil {
|
||||
ctx = context.Background()
|
||||
}
|
||||
return context.WithTimeout(ctx, defaultTimeout)
|
||||
// createDefaultCtx creates a fresh timeout context for P-Chain API operations.
|
||||
// It intentionally uses context.Background() instead of deriving from the parent context
|
||||
// to avoid context cancellation propagation during planned node restarts (e.g., during
|
||||
// subnet creation). The parent context may be canceled by the server's stopCh goroutine
|
||||
// during restartNodes, but P-Chain API calls should continue to work after nodes restart.
|
||||
func createDefaultCtx(_ context.Context) (context.Context, context.CancelFunc) {
|
||||
return context.WithTimeout(context.Background(), defaultTimeout)
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
"api-admin-enabled":true,
|
||||
"index-enabled":true,
|
||||
"log-display-level":"ERROR",
|
||||
"log-level": "DEBUG",
|
||||
"log-level": "INFO",
|
||||
"sybil-protection-enabled": false,
|
||||
"sybil-protection-disabled-weight": 100,
|
||||
"network-health-min-conn-peers": 0
|
||||
}
|
||||
|
||||
+34
-3
@@ -152,7 +152,14 @@ func NewConfigForNetwork(binaryPath string, numNodes uint32, networkID uint32) (
|
||||
|
||||
// Create initial stakers for genesis
|
||||
hrp := constants.GetHRP(networkID)
|
||||
rewardAddr, err := address.Format("X", hrp, ids.GenerateTestShortID().Bytes())
|
||||
|
||||
// Treasury address short ID (derived from 0x9011E888251AB053B7bD1cdB598Db4f9DEd94714)
|
||||
// P-Chain Address: P-lux1c7wevm4667l4umtzh93r25wpxlpsadkhka6gv6
|
||||
// X-Chain Address: X-lux1c7wevm4667l4umtzh93r25wpxlpsadkhka6gv6
|
||||
var treasuryShortID ids.ShortID
|
||||
treasuryBytes, _ := hex.DecodeString("c79d966ebad7bf5e6d62b9623551c137c30eb6d7")
|
||||
copy(treasuryShortID[:], treasuryBytes)
|
||||
rewardAddr, err := address.Format("X", hrp, treasuryShortID[:])
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("couldn't format reward address: %w", err)
|
||||
}
|
||||
@@ -173,8 +180,8 @@ func NewConfigForNetwork(binaryPath string, numNodes uint32, networkID uint32) (
|
||||
// Update genesis with initial stakers
|
||||
genesis["initialStakers"] = initialStakers
|
||||
|
||||
// Ensure there's a staked funds entry
|
||||
stakeAddr, err := address.Format("X", hrp, ids.GenerateTestShortID().Bytes())
|
||||
// Ensure there's a staked funds entry - use treasury address
|
||||
stakeAddr, err := address.Format("X", hrp, treasuryShortID[:])
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("couldn't format stake address: %w", err)
|
||||
}
|
||||
@@ -199,6 +206,30 @@ func NewConfigForNetwork(binaryPath string, numNodes uint32, networkID uint32) (
|
||||
},
|
||||
}
|
||||
allocations = append(allocations, stakeAllocation)
|
||||
|
||||
// Add ewoq allocation with immediately available funds for P-chain operations (subnet creation, etc.)
|
||||
// Ewoq ShortID: 3cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c
|
||||
var ewoqShortID ids.ShortID
|
||||
ewoqBytes, _ := hex.DecodeString("3cb7d3842e8cee6a0ebd09f1fe884f6861e1b29c")
|
||||
copy(ewoqShortID[:], ewoqBytes)
|
||||
ewoqAddr, err := address.Format("X", hrp, ewoqShortID[:])
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("couldn't format ewoq address: %w", err)
|
||||
}
|
||||
|
||||
// Allocation with unlockSchedule locktime=0 makes funds available on P-chain immediately
|
||||
ewoqAllocation := map[string]interface{}{
|
||||
"ethAddr": "0x8db97C7cEcE249c2b98bDC0226Cc4C2A57BF52FC", // C-chain address for ewoq
|
||||
"luxAddr": ewoqAddr,
|
||||
"initialAmount": uint64(100000000000000000), // 100M LUX on X-chain
|
||||
"unlockSchedule": []map[string]interface{}{
|
||||
{
|
||||
"amount": uint64(100000000000000000), // 100M LUX available immediately on P-chain
|
||||
"locktime": 0, // Immediately available (no lock)
|
||||
},
|
||||
},
|
||||
}
|
||||
allocations = append(allocations, ewoqAllocation)
|
||||
genesis["allocations"] = allocations
|
||||
|
||||
// Set initial staked funds
|
||||
|
||||
+12
-2
@@ -813,7 +813,15 @@ func (ln *localNetwork) removeNode(ctx context.Context, nodeName string) error {
|
||||
if !paused {
|
||||
// Note: CChainEthAPI returns an empty interface, so no Close() method available
|
||||
// The websocket connection cleanup is handled internally
|
||||
if exitCode := node.process.Stop(ctx); exitCode != 0 {
|
||||
exitCode := node.process.Stop(ctx)
|
||||
// Accept graceful shutdown exit codes:
|
||||
// - 0: normal exit
|
||||
// - -1: process was killed before it could be waited on (signal handling)
|
||||
// - 2: luxd uses this for graceful shutdown via signal
|
||||
// - 130 (128+2): SIGINT (Ctrl+C)
|
||||
// - 143 (128+15): SIGTERM
|
||||
// Only treat other non-zero exit codes as errors
|
||||
if exitCode != 0 && exitCode != -1 && exitCode != 2 && exitCode != 130 && exitCode != 143 {
|
||||
return fmt.Errorf("node %q exited with exit code: %d", nodeName, exitCode)
|
||||
}
|
||||
}
|
||||
@@ -842,7 +850,9 @@ func (ln *localNetwork) pauseNode(ctx context.Context, nodeName string) error {
|
||||
}
|
||||
// Note: CChainEthAPI returns an empty interface, so no Close() method available
|
||||
// The websocket connection cleanup is handled internally
|
||||
if exitCode := node.process.Stop(ctx); exitCode != 0 {
|
||||
exitCode := node.process.Stop(ctx)
|
||||
// Accept graceful shutdown exit codes (see removeNode for details)
|
||||
if exitCode != 0 && exitCode != -1 && exitCode != 2 && exitCode != 130 && exitCode != 143 {
|
||||
return fmt.Errorf("node %q exited with exit code: %d", nodeName, exitCode)
|
||||
}
|
||||
syscall.Sync()
|
||||
|
||||
@@ -29,9 +29,9 @@ func TestMultiEngineOrchestration(t *testing.T) {
|
||||
StakingPort: 19631,
|
||||
LogLevel: "info",
|
||||
Extra: map[string]interface{}{
|
||||
"staking-enabled": false,
|
||||
"sybil-protection-enabled": false,
|
||||
"health-check-frequency": "2s",
|
||||
"dev-mode": true,
|
||||
"sybil-protection-disabled-weight": 100,
|
||||
"health-check-frequency": "2s",
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
+14
-4
@@ -192,6 +192,20 @@ func (lc *localNetwork) createConfig() error {
|
||||
|
||||
cfg.NodeConfigs[i].Name = nodeName
|
||||
|
||||
// Initialize maps if nil to avoid panic when assigning
|
||||
if cfg.NodeConfigs[i].Flags == nil {
|
||||
cfg.NodeConfigs[i].Flags = map[string]interface{}{}
|
||||
}
|
||||
if cfg.NodeConfigs[i].ChainConfigFiles == nil {
|
||||
cfg.NodeConfigs[i].ChainConfigFiles = map[string]string{}
|
||||
}
|
||||
if cfg.NodeConfigs[i].UpgradeConfigFiles == nil {
|
||||
cfg.NodeConfigs[i].UpgradeConfigFiles = map[string]string{}
|
||||
}
|
||||
if cfg.NodeConfigs[i].SubnetConfigFiles == nil {
|
||||
cfg.NodeConfigs[i].SubnetConfigFiles = map[string]string{}
|
||||
}
|
||||
|
||||
for k, v := range lc.options.chainConfigs {
|
||||
cfg.NodeConfigs[i].ChainConfigFiles[k] = v
|
||||
}
|
||||
@@ -202,10 +216,6 @@ func (lc *localNetwork) createConfig() error {
|
||||
cfg.NodeConfigs[i].SubnetConfigFiles[k] = v
|
||||
}
|
||||
|
||||
if cfg.NodeConfigs[i].Flags == nil {
|
||||
cfg.NodeConfigs[i].Flags = map[string]interface{}{}
|
||||
}
|
||||
|
||||
if lc.options.dynamicPorts {
|
||||
// remove http port defined in local network config, to get dynamic port generation
|
||||
delete(cfg.NodeConfigs[i].Flags, config.HTTPPortKey)
|
||||
|
||||
+2
-1
@@ -507,7 +507,8 @@ func (s *server) CreateBlockchains(
|
||||
defer cancel()
|
||||
chainIDs, err := s.network.CreateChains(ctx, chainSpecs)
|
||||
if err != nil {
|
||||
s.log.Error("failed to create blockchains", zap.Error(err))
|
||||
s.log.Error("failed to create blockchains", zap.Error(err), zap.String("errorDetail", err.Error()))
|
||||
fmt.Printf("ERROR: failed to create blockchains: %v\n", err)
|
||||
s.stopAndRemoveNetwork(err)
|
||||
return nil, err
|
||||
} else {
|
||||
|
||||
@@ -11,8 +11,8 @@ engines:
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
extra:
|
||||
staking-enabled: false
|
||||
sybil-protection-enabled: false
|
||||
dev-mode: true
|
||||
sybil-protection-disabled-weight: 100
|
||||
health-check-frequency: 2s
|
||||
|
||||
- name: lux-c
|
||||
|
||||
@@ -11,8 +11,8 @@ engines:
|
||||
log_level: info
|
||||
wait_healthy: true
|
||||
extra:
|
||||
staking-enabled: false
|
||||
sybil-protection-enabled: false
|
||||
dev-mode: true
|
||||
sybil-protection-disabled-weight: 100
|
||||
|
||||
- name: lux-l2-op
|
||||
type: op
|
||||
|
||||
Reference in New Issue
Block a user