mirror of
https://github.com/luxfi/netrunner.git
synced 2026-07-27 00:04:23 +00:00
chore(deps): update to latest luxfi packages
- Remove local replace directive for genesis - Update to latest published versions: - genesis v1.5.18 - geth v1.16.67 - crypto v1.17.32 - ids v1.2.6 - database v1.2.18 - p2p v1.18.3 - consensus v1.22.47
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"github.com/luxfi/log"
|
||||
"github.com/luxfi/log/level"
|
||||
"github.com/luxfi/netrunner/cmd/netrunner/commands"
|
||||
"github.com/luxfi/netrunner/cmd/server"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
@@ -38,6 +39,7 @@ OP Stack, and more.`,
|
||||
|
||||
// Add subcommands
|
||||
rootCmd.AddCommand(
|
||||
server.NewCommand(),
|
||||
commands.NewEngineCmd(logger),
|
||||
commands.NewStackCmd(logger),
|
||||
commands.NewStatusCmd(logger),
|
||||
|
||||
@@ -12,13 +12,13 @@ require (
|
||||
github.com/dgraph-io/badger/v4 v4.9.0
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1
|
||||
github.com/luxfi/config v1.0.0
|
||||
github.com/luxfi/consensus v1.22.46
|
||||
github.com/luxfi/consensus v1.22.47
|
||||
github.com/luxfi/const v1.4.0
|
||||
github.com/luxfi/crypto v1.17.27
|
||||
github.com/luxfi/genesis v1.5.17
|
||||
github.com/luxfi/geth v1.16.66
|
||||
github.com/luxfi/crypto v1.17.32
|
||||
github.com/luxfi/genesis v1.5.18
|
||||
github.com/luxfi/geth v1.16.67
|
||||
github.com/luxfi/go-bip39 v1.1.2
|
||||
github.com/luxfi/ids v1.2.5
|
||||
github.com/luxfi/ids v1.2.6
|
||||
github.com/luxfi/keys v1.0.5
|
||||
github.com/luxfi/log v1.2.1
|
||||
github.com/luxfi/math v1.2.0
|
||||
@@ -34,7 +34,6 @@ require (
|
||||
github.com/stretchr/testify v1.11.1
|
||||
go.uber.org/multierr v1.11.0
|
||||
golang.org/x/crypto v0.46.0
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93
|
||||
golang.org/x/mod v0.31.0
|
||||
golang.org/x/sync v0.19.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250811230008-5f3141c8851a
|
||||
@@ -47,14 +46,14 @@ require (
|
||||
github.com/DataDog/zstd v1.5.7 // indirect
|
||||
github.com/Masterminds/semver/v3 v3.4.0 // indirect
|
||||
github.com/Microsoft/go-winio v0.6.2 // indirect
|
||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251221085550-b8e13ca38217 // indirect
|
||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251230134950-44c893854e3f // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/bits-and-blooms/bitset v1.24.4 // indirect
|
||||
github.com/btcsuite/btcd/btcec/v2 v2.3.5 // indirect
|
||||
github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect
|
||||
github.com/cenkalti/backoff/v5 v5.0.3 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.2-0.20251204010831-23491bd573cf // indirect
|
||||
github.com/cloudflare/circl v1.6.2 // indirect
|
||||
github.com/cockroachdb/errors v1.12.0 // indirect
|
||||
github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 // indirect
|
||||
github.com/cockroachdb/logtags v0.0.0-20241215232642-bb51bb14a506 // indirect
|
||||
@@ -67,12 +66,12 @@ require (
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/deckarep/golang-set/v2 v2.8.0 // indirect
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect
|
||||
github.com/dgraph-io/ristretto/v2 v2.2.0 // indirect
|
||||
github.com/dgraph-io/ristretto/v2 v2.3.0 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/ethereum/c-kzg-4844/v2 v2.1.5 // indirect
|
||||
github.com/ethereum/go-verkle v0.2.2 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/getsentry/sentry-go v0.35.1 // indirect
|
||||
github.com/getsentry/sentry-go v0.40.0 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-ole/go-ole v1.3.0 // indirect
|
||||
@@ -82,9 +81,9 @@ require (
|
||||
github.com/golang/mock v1.7.0-rc.1 // indirect
|
||||
github.com/golang/snappy v1.0.0 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/flatbuffers v25.2.10+incompatible // indirect
|
||||
github.com/google/flatbuffers v25.12.19+incompatible // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 // indirect
|
||||
github.com/google/pprof v0.0.0-20251213031049-b05bdaca462f // indirect
|
||||
github.com/google/renameio/v2 v2.0.0 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
@@ -93,16 +92,16 @@ require (
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 // indirect
|
||||
github.com/holiman/uint256 v1.3.2 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/compress v1.18.2 // indirect
|
||||
github.com/kr/pretty v0.3.1 // indirect
|
||||
github.com/kr/text v0.2.0 // indirect
|
||||
github.com/luxfi/address v1.0.0 // indirect
|
||||
github.com/luxfi/cache v1.1.0 // indirect
|
||||
github.com/luxfi/database v1.2.17 // indirect
|
||||
github.com/luxfi/database v1.2.18 // indirect
|
||||
github.com/luxfi/go-bip32 v1.0.2 // indirect
|
||||
github.com/luxfi/keychain v1.0.1 // indirect
|
||||
github.com/luxfi/mock v0.1.0 // indirect
|
||||
github.com/luxfi/p2p v1.18.2 // indirect
|
||||
github.com/luxfi/p2p v1.18.3 // indirect
|
||||
github.com/luxfi/sampler v1.0.0 // indirect
|
||||
github.com/luxfi/staking v1.0.0 // indirect
|
||||
github.com/luxfi/trace v0.1.4 // indirect
|
||||
@@ -132,23 +131,24 @@ require (
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/supranational/blst v0.3.16 // indirect
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.15 // indirect
|
||||
github.com/tklauser/numcpus v0.10.0 // indirect
|
||||
github.com/tklauser/go-sysconf v0.3.16 // indirect
|
||||
github.com/tklauser/numcpus v0.11.0 // indirect
|
||||
github.com/yusufpapurcu/wmi v1.2.4 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||
go.opentelemetry.io/otel v1.37.0 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/otel v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.39.0 // indirect
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.39.0 // indirect
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 // indirect
|
||||
go.uber.org/automaxprocs v1.6.0 // indirect
|
||||
go.uber.org/mock v0.6.0 // indirect
|
||||
go.uber.org/zap v1.27.1 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/exp v0.0.0-20251219203646-944ab1f22d93 // indirect
|
||||
golang.org/x/net v0.48.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
|
||||
@@ -4,8 +4,8 @@ github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1
|
||||
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
|
||||
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
|
||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251221085550-b8e13ca38217 h1:RNTau6sw5B3ltE+2GlzEom63eBMzoLUc+dhjmdIwNpI=
|
||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251221085550-b8e13ca38217/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI=
|
||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251230134950-44c893854e3f h1:a5PUgHGinaD6XrLmIDLQmGHocjIjBsBAcR5gALjZvMU=
|
||||
github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251230134950-44c893854e3f/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI=
|
||||
github.com/VictoriaMetrics/fastcache v1.13.2 h1:2XTB49aLSuCex7e9P5rqrfQcMkzGjh5Vq3GMFa8YpCA=
|
||||
github.com/VictoriaMetrics/fastcache v1.13.2/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
@@ -51,8 +51,12 @@ github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL
|
||||
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/cloudflare/circl v1.6.2-0.20251204010831-23491bd573cf h1:+0huF756d72ZdHxachRP5HYmvRkkOk8CLyKUmJM138c=
|
||||
github.com/cloudflare/circl v1.6.2-0.20251204010831-23491bd573cf/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs=
|
||||
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
|
||||
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
|
||||
github.com/cloudflare/circl v1.6.2 h1:hL7VBpHHKzrV5WTfHCaBsgx/HGbBYlgrwvNXEVDYYsQ=
|
||||
github.com/cloudflare/circl v1.6.2/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
|
||||
github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4=
|
||||
github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU=
|
||||
github.com/cockroachdb/errors v1.12.0 h1:d7oCs6vuIMUQRVbi6jWWWEJZahLCfJpnJSVobd1/sUo=
|
||||
@@ -95,14 +99,14 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjY
|
||||
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
|
||||
github.com/dgraph-io/badger/v4 v4.9.0 h1:tpqWb0NewSrCYqTvywbcXOhQdWcqephkVkbBmaaqHzc=
|
||||
github.com/dgraph-io/badger/v4 v4.9.0/go.mod h1:5/MEx97uzdPUHR4KtkNt8asfI2T4JiEiQlV7kWUo8c0=
|
||||
github.com/dgraph-io/ristretto/v2 v2.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM=
|
||||
github.com/dgraph-io/ristretto/v2 v2.2.0/go.mod h1:RZrm63UmcBAaYWC1DotLYBmTvgkrs0+XhBd7Npn7/zI=
|
||||
github.com/dgraph-io/ristretto/v2 v2.3.0 h1:qTQ38m7oIyd4GAed/QkUZyPFNMnvVWyazGXRwvOt5zk=
|
||||
github.com/dgraph-io/ristretto/v2 v2.3.0/go.mod h1:gpoRV3VzrEY1a9dWAYV6T1U7YzfgttXdd/ZzL1s9OZM=
|
||||
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da h1:aIftn67I1fkbMa512G+w+Pxci9hJPB8oMnkcP3iZF38=
|
||||
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
|
||||
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
|
||||
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/emicklei/dot v1.9.0 h1:FyaJNctdMfaEIbTQ1FkKZ1UCZyJJSkyvkrXOVoNZPKU=
|
||||
github.com/emicklei/dot v1.9.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=
|
||||
github.com/emicklei/dot v1.10.0 h1:z17n0ce/FBMz3QbShSzVGhiW447Qhu7fljzvp3Gs6ig=
|
||||
github.com/emicklei/dot v1.10.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=
|
||||
github.com/ethereum/c-kzg-4844/v2 v2.1.5 h1:aVtoLK5xwJ6c5RiqO8g8ptJ5KU+2Hdquf6G3aXiHh5s=
|
||||
github.com/ethereum/c-kzg-4844/v2 v2.1.5/go.mod h1:u59hRTTah4Co6i9fDWtiCjTrblJv0UwsqZKCc0GfgUs=
|
||||
github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk=
|
||||
@@ -120,8 +124,8 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20250918194357-1ec6f2e601c6 h1:ko+DlyhLqUHpgrvwqs5ybydoGAqjpJQTXpAS7vUqVlM=
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20250918194357-1ec6f2e601c6/go.mod h1:3IVE7v4II2gS2V5amIH7F7NeYQtbbORtQtjdflgS1vk=
|
||||
github.com/getsentry/sentry-go v0.35.1 h1:iopow6UVLE2aXu46xKVIs8Z9D/YZkJrHkgozrxa+tOQ=
|
||||
github.com/getsentry/sentry-go v0.35.1/go.mod h1:C55omcY9ChRQIUcVcGcs+Zdy4ZpQGvNJ7JYHIoSWOtE=
|
||||
github.com/getsentry/sentry-go v0.40.0 h1:VTJMN9zbTvqDqPwheRVLcp0qcUcM+8eFivvGocAaSbo=
|
||||
github.com/getsentry/sentry-go v0.40.0/go.mod h1:eRXCoh3uvmjQLY6qu63BjUZnaBu5L5WhMV1RwYO8W5s=
|
||||
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
|
||||
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
@@ -161,8 +165,8 @@ github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q=
|
||||
github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/flatbuffers v25.12.19+incompatible h1:haMV2JRRJCe1998HeW/p0X9UaMTK6SDo0ffLn2+DbLs=
|
||||
github.com/google/flatbuffers v25.12.19+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
@@ -172,8 +176,8 @@ github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
|
||||
github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY=
|
||||
github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U=
|
||||
github.com/google/pprof v0.0.0-20251213031049-b05bdaca462f h1:HU1RgM6NALf/KW9HEY6zry3ADbDKcmpQ+hJedoNGQYQ=
|
||||
github.com/google/pprof v0.0.0-20251213031049-b05bdaca462f/go.mod h1:67FPmZWbr+KDT/VlpWtw6sO9XSjpJmLuHpoLmWiTGgY=
|
||||
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
|
||||
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
@@ -185,8 +189,8 @@ github.com/gorilla/rpc v1.2.1/go.mod h1:uNpOihAlF5xRFLuTYhfR0yfCTm0WTQSQttkMSptR
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||
github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0=
|
||||
github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
|
||||
github.com/graph-gophers/graphql-go v1.8.0 h1:NT05/H+PdH1/PONExlUycnhULYHBy98dxV63WYc0Ng8=
|
||||
github.com/graph-gophers/graphql-go v1.8.0/go.mod h1:23olKZ7duEvHlF/2ELEoSZaY1aNPfShjP782SOoNTyM=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0 h1:Ovs26xHkKqVztRpIrF/92BcuyuQ/YW4NSIpoGtfXNho=
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.1 h1:X5VWvz21y3gzm9Nw/kaUeku/1+uBhcekkmy4IkffJww=
|
||||
@@ -209,8 +213,8 @@ github.com/influxdata/influxdb-client-go/v2 v2.14.0 h1:AjbBfJuq+QoaXNcrova8smSjw
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.14.0/go.mod h1:Ahpm3QXKMJslpXl3IftVLVezreAUtBOTZssDrjZEFHI=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c h1:qSHzRbhzK8RdXOsAdfDgO49TtqC1oZ+acxPrkfTxcCs=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 h1:W9WBk7wlPfJLvMCdtV4zPulc4uCPrlywQOmbFOhgQNU=
|
||||
github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
|
||||
github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf h1:7JTmneyiNEwVBOHSjoMxiWAqB992atOeepeFYegn5RU=
|
||||
github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus=
|
||||
github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
@@ -219,8 +223,8 @@ github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlT
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/compress v1.18.2 h1:iiPHWW0YrcFgpBYhsA6D1+fqHssJscY/Tm/y2Uqnapk=
|
||||
github.com/klauspost/compress v1.18.2/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
@@ -237,24 +241,24 @@ github.com/luxfi/cache v1.1.0 h1:6LUyGGZ+rrMAJBbAU6+UwkcamXj3zsboRUodIof2Ong=
|
||||
github.com/luxfi/cache v1.1.0/go.mod h1:9GvlEEE9rFPaaWxvVpSPwW8ZMo2+8VMNNcuPa4AwzPg=
|
||||
github.com/luxfi/config v1.0.0 h1:EFIFkdus3YdDklhlwHKJNYLpSVuvWqHm+fs/TGckv5U=
|
||||
github.com/luxfi/config v1.0.0/go.mod h1:71q4A4m7vj+o1qnL1dNk/tVII+Ugiwvi9+jVMN2xxTU=
|
||||
github.com/luxfi/consensus v1.22.46 h1:w97OZjtW/anWvgM0N/q8Y70LEJlqlFG6yeS10rKcnx4=
|
||||
github.com/luxfi/consensus v1.22.46/go.mod h1:cbvtxHH5pab/XJIlHekg66tYaIChTwTt9SNMMgz8+as=
|
||||
github.com/luxfi/consensus v1.22.47 h1:iMVimbKap4T7sCNWs3Pb2yq1LVD9d9/sXmWHMiyCSDQ=
|
||||
github.com/luxfi/consensus v1.22.47/go.mod h1:LWAJvhE36LP8OrR3dPjjdc50vTTL4R2nbrvB+CDvb0w=
|
||||
github.com/luxfi/const v1.4.0 h1:8bHt5I8g76TkeuFIY478aYtfcLgbdkGNo/e/Sy3+6p0=
|
||||
github.com/luxfi/const v1.4.0/go.mod h1:qWfecjdImPY3kXsy3UAe4ZVpMcsp2/iUlHwUMPVREoI=
|
||||
github.com/luxfi/crypto v1.17.27 h1:gFTvoQ7SJDsaBVQfQJBpDG8yVx6J61JdW+G0JFCUK3c=
|
||||
github.com/luxfi/crypto v1.17.27/go.mod h1:v6eaW5ejuzW2gecChWKQqx4CtVhoM1b+e40ro/6WVPg=
|
||||
github.com/luxfi/database v1.2.17 h1:1PE0FlAarorfAMl+vAvO6EDbkS+a4ktL7kvtRk58DWY=
|
||||
github.com/luxfi/database v1.2.17/go.mod h1:IzvNHGFZWdRs5CL5vswqz8/uu8t796cMGlbqPWs032s=
|
||||
github.com/luxfi/genesis v1.5.17 h1:GDv9m8OXBXFOq9714v1PfISPhPpoyozGUpvMT+ysjqY=
|
||||
github.com/luxfi/genesis v1.5.17/go.mod h1:iDMXsNS0ZCnBY7T385Nw6ERobnq+DE5bfuVJds/TuGQ=
|
||||
github.com/luxfi/geth v1.16.66 h1:XS5hMbYZtxCm/G6vjWBA7vRTpajX1FSJvAfkpL8cbN4=
|
||||
github.com/luxfi/geth v1.16.66/go.mod h1:fmimbIf5oLldwc3FzEYaP8Jrf8tBhvDFi0Y/b26Tajk=
|
||||
github.com/luxfi/crypto v1.17.32 h1:qEKDETNMeU7T82UMEEGYh0bbJ0ZZdx0sAMRwFXt69aQ=
|
||||
github.com/luxfi/crypto v1.17.32/go.mod h1:laZTnEq0BD/fnPhd5ke/79WgFhV3TZjmfPxk+b8zbrE=
|
||||
github.com/luxfi/database v1.2.18 h1:yppRuZf3FKnr3v4o+UHNfSW+cXtUIUibtyki0+EqiIs=
|
||||
github.com/luxfi/database v1.2.18/go.mod h1:dYxaF30KGJQzuxA3VH7+WGU5/dhwRyzLgzSk9F3wje0=
|
||||
github.com/luxfi/genesis v1.5.18 h1:DDNFDyYT+AtSX78XBV1nGeuvR4404XPAkXnnrlJSV78=
|
||||
github.com/luxfi/genesis v1.5.18/go.mod h1:888i1w8e67HIpgLuveIdd+3ESWCXHgnz7cijF6dDAKI=
|
||||
github.com/luxfi/geth v1.16.67 h1:ILPG59XNnNKIz1YNO1fJFV+doZXBjcQkb4oXQyz1HUM=
|
||||
github.com/luxfi/geth v1.16.67/go.mod h1:QWPyY3vlGQfm8SX/PE6q4XHTBe7X4Gw+SGDJi5QU1pg=
|
||||
github.com/luxfi/go-bip32 v1.0.2 h1:7vFbb+Wr4Z499q2tuCLdd7wWjtn8sH+HWBlx76mhH9Y=
|
||||
github.com/luxfi/go-bip32 v1.0.2/go.mod h1:bc7/LXDKAJQZ/F0Xjf5yXaTZxY9/ssLb4FC+Hxn/cDk=
|
||||
github.com/luxfi/go-bip39 v1.1.2 h1:p+wLMPGs6MLQh7q0YIsmy2EhHL7LHiELEGTJko6t/Jg=
|
||||
github.com/luxfi/go-bip39 v1.1.2/go.mod h1:96de9VkR2kY/ASAnhMtvt3TSh+PZkAFAngNj0GjRGDo=
|
||||
github.com/luxfi/ids v1.2.5 h1:w4YSj3S6LQiUXhiChUmcbrMCRMfkCaBFIGn0Eo4ZSxk=
|
||||
github.com/luxfi/ids v1.2.5/go.mod h1:vZBjJWSmqMIZuodgnoszvTDvXIwsbnhM2pkktg6FGrg=
|
||||
github.com/luxfi/ids v1.2.6 h1:Ru86pltAcWPhCT7FH/MwwuAYXkeZbt9ZwfuR883c8MI=
|
||||
github.com/luxfi/ids v1.2.6/go.mod h1:svLsj7e6ixJVfRYaQqv9RWjBIW11Vz738+d08BVpeCg=
|
||||
github.com/luxfi/keychain v1.0.1 h1:8tTzPnZSi0M6UtKRBCypnGFrLNry9BvWfS5ol33yDF0=
|
||||
github.com/luxfi/keychain v1.0.1/go.mod h1:X7HLk5QRZ1VHJxovAyBL6z7f/nlosoXlveEtvUGhoaw=
|
||||
github.com/luxfi/keys v1.0.5 h1:ZzE2wHDxSiIcufkYlp7twmTKGB0mczjE67uM3uAP2Ag=
|
||||
@@ -269,10 +273,10 @@ 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.22.75 h1:kOs6bbwP23scRTDN1YTjglcVQgncpaZqmeZIV/Cheqc=
|
||||
github.com/luxfi/node v1.22.75/go.mod h1:97xyVTMBFq/LmbrQ0VMA6DNNWBYSu+3jQG1ztBBEuHc=
|
||||
github.com/luxfi/p2p v1.18.2 h1:elpyXr58wht1KP64D4BcKXft1AEjJ3IRACj/W8vdLI8=
|
||||
github.com/luxfi/p2p v1.18.2/go.mod h1:eM6XpmBFbDjaI7fFuGYBPab77TS1esxHxAOluBLAC0Y=
|
||||
github.com/luxfi/precompiles v0.1.10 h1:M90JTzW+je/uaCBSE2BvoONamBTbuUDskh4fxua6oUE=
|
||||
github.com/luxfi/precompiles v0.1.10/go.mod h1:s4054PbUgIZ/CezXT3BSNGbUqimgzK7LABP0wMhNG/Y=
|
||||
github.com/luxfi/p2p v1.18.3 h1:RUxZdRyQq5YLvaLUb6v86sv5ElFLR16Pq0jen9RAKho=
|
||||
github.com/luxfi/p2p v1.18.3/go.mod h1:9jmpwJqTTrrz3VF+7vgIAjcixB7CvvRcT5p2o4vz3m0=
|
||||
github.com/luxfi/precompile v0.4.0 h1:xvaiUi9rf11Hqn4J9mlsw+KsXWkZmZxByc0GGHn2k+o=
|
||||
github.com/luxfi/precompile v0.4.0/go.mod h1:ZSc4SN4X5S6ASj8VQYVtrlzKQwGFcw9Utq3IFQ1Ua/I=
|
||||
github.com/luxfi/sampler v1.0.0 h1:k8Sf6otW83w4pQp0jXLA+g3J/joB7w7SqXQsWmNTOV0=
|
||||
github.com/luxfi/sampler v1.0.0/go.mod h1:f96/ozlj9vFfZj+akLtrHn4VpulQahwB+MQQhpeIekk=
|
||||
github.com/luxfi/staking v1.0.0 h1:pYI7XMGGb/zK2ATfTIkush/7HPWE7IS2yfmJqj4nzes=
|
||||
@@ -291,8 +295,8 @@ github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHP
|
||||
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
|
||||
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
|
||||
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
|
||||
github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM=
|
||||
github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
@@ -306,8 +310,8 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8m
|
||||
github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A=
|
||||
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
|
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
|
||||
github.com/oapi-codegen/runtime v1.0.0 h1:P4rqFX5fMFWqRzY9M/3YF9+aPSPPB06IzP2P7oOxrWo=
|
||||
github.com/oapi-codegen/runtime v1.0.0/go.mod h1:LmCUMQuPB4M/nLXilQXhHw+BLZdDb18B34OO356yJ/A=
|
||||
github.com/oapi-codegen/runtime v1.1.2 h1:P2+CubHq8fO4Q6fV1tqDBZHCwpVpvPg7oKiYzQgXIyI=
|
||||
github.com/oapi-codegen/runtime v1.1.2/go.mod h1:SK9X900oXmPWilYR5/WKPzt3Kqxn/uS/+lbpREv+eCg=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
@@ -326,8 +330,6 @@ github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAl
|
||||
github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro=
|
||||
github.com/onsi/gomega v1.38.0 h1:c/WX+w8SLAinvuKKQFh77WEucCnPk4j2OTUr7lt7BeY=
|
||||
github.com/onsi/gomega v1.38.0/go.mod h1:OcXcwId0b9QsE7Y49u+BTrL4IdKOBOKnD6VQNTJEB6o=
|
||||
github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8=
|
||||
github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I=
|
||||
github.com/otiai10/mint v1.6.3 h1:87qsV/aw1F5as1eH1zS/yqHY85ANKVMgkDrf9rcxbQs=
|
||||
@@ -340,14 +342,14 @@ github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 h1:+FZIDR/D97YOP
|
||||
github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63/go.mod h1:X2r9ueLEUZgtx2cIogM0v4Zj5uvvzhuuiu7Pn8HzMPg=
|
||||
github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk=
|
||||
github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE=
|
||||
github.com/pion/logging v0.2.3 h1:gHuf0zpoh1GW67Nr6Gj4cv5Z9ZscU7g/EaoC/Ke/igI=
|
||||
github.com/pion/logging v0.2.3/go.mod h1:z8YfknkquMe1csOrxK5kc+5/ZPAzMxbKLX5aXpbpC90=
|
||||
github.com/pion/logging v0.2.4 h1:tTew+7cmQ+Mc1pTBLKH2puKsOvhm32dROumOZ655zB8=
|
||||
github.com/pion/logging v0.2.4/go.mod h1:DffhXTKYdNZU+KtJ5pyQDjvOAh/GsNSyv1lbkFbe3so=
|
||||
github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0=
|
||||
github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ=
|
||||
github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q=
|
||||
github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E=
|
||||
github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0=
|
||||
github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo=
|
||||
github.com/pion/transport/v3 v3.1.1 h1:Tr684+fnnKlhPceU+ICdrw6KKkTms+5qHMgw6bIkYOM=
|
||||
github.com/pion/transport/v3 v3.1.1/go.mod h1:+c2eewC5WJQHiAA46fkMMzoYZSuGzA/7E2FPrOYHctQ=
|
||||
github.com/pires/go-proxyproto v0.8.1 h1:9KEixbdJfhrbtjpz/ZwCdWDD2Xem0NZ38qMYaASJgp0=
|
||||
github.com/pires/go-proxyproto v0.8.1/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
@@ -366,8 +368,6 @@ github.com/prometheus/common v0.67.4 h1:yR3NqWO1/UyO1w2PhUvXlGQs/PtFmoveVO0KZ4+L
|
||||
github.com/prometheus/common v0.67.4/go.mod h1:gP0fq6YjjNCLssJCQp0yk4M8W6ikLURwkdd/YKtTbyI=
|
||||
github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws=
|
||||
github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
@@ -418,39 +418,39 @@ github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5f
|
||||
github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48=
|
||||
github.com/thepudds/fzgen v0.4.3 h1:srUP/34BulQaEwPP/uHZkdjUcUjIzL7Jkf4CBVryiP8=
|
||||
github.com/thepudds/fzgen v0.4.3/go.mod h1:BhhwtRhzgvLWAjjcHDJ9pEiLD2Z9hrVIFjBCHJ//zJ4=
|
||||
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
|
||||
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
|
||||
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
|
||||
github.com/tklauser/numcpus v0.10.0/go.mod h1:BiTKazU708GQTYF4mB+cmlpT2Is1gLk7XVuEeem8LsQ=
|
||||
github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
|
||||
github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=
|
||||
github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
|
||||
github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=
|
||||
github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU=
|
||||
github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4=
|
||||
github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU=
|
||||
github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
|
||||
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
||||
github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342 h1:FnBeRrxr7OU4VvAzt5X7s6266i6cSVkkFPS0TuXWbIg=
|
||||
github.com/xrash/smetrics v0.0.0-20250705151800-55b8f293f342/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0 h1:Ahq7pZmv87yiyn3jeFz/LekZmPLLdKejuO3NcK9MssM=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.37.0/go.mod h1:MJTqhM0im3mRLw1i8uGHnCvUEeS7VwRyxlLC78PA18M=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0 h1:bDMKF3RUSxshZ5OjOTi8rsHGaPKsAt76FaqgvIUySLc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.37.0/go.mod h1:dDT67G/IkA46Mr2l9Uj7HsQVwsjASyV9SjGofsiUZDA=
|
||||
go.opentelemetry.io/otel/metric v1.37.0 h1:mvwbQS5m0tbmqML4NqK+e3aDiO02vsf/WgbsdpcPoZE=
|
||||
go.opentelemetry.io/otel/metric v1.37.0/go.mod h1:04wGrZurHYKOc+RKeye86GwKiTb9FKm1WHtO+4EVr2E=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0 h1:ItB0QUqnjesGRvNcmAcU0LyvkVyGJ2xftD29bWdDvKI=
|
||||
go.opentelemetry.io/otel/sdk v1.37.0/go.mod h1:VredYzxUvuo2q3WRcDnKDjbdvmO0sCzOvVAiY+yUkAg=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0 h1:90lI228XrB9jCMuSdA0673aubgRobVZFhbjxHHspCPc=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.37.0/go.mod h1:cNen4ZWfiD37l5NhS+Keb5RXVWZWpRE+9WyVCpbo5ps=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||
go.opentelemetry.io/proto/otlp v1.7.1 h1:gTOMpGDb0WTBOP8JaO72iL3auEZhVmAQg4ipjOVAtj4=
|
||||
go.opentelemetry.io/proto/otlp v1.7.1/go.mod h1:b2rVh6rfI/s2pHWNlB7ILJcRALpcNDzKhACevjI+ZnE=
|
||||
go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
|
||||
|
||||
+80
-31
@@ -69,11 +69,15 @@ const (
|
||||
// check period while waiting for all validators to be ready
|
||||
// Reduced from 1s to 200ms for faster validator detection
|
||||
waitForValidatorsPullFrequency = 200 * time.Millisecond
|
||||
defaultTimeout = 10 * time.Minute // Increased for mainnet staking validators
|
||||
stakingMinimumLeadTime = 25 * time.Second
|
||||
// FAIL FAST: Reduced from 10 minutes to 30 seconds for local deployments
|
||||
// Most P-chain API calls should complete in <5s on localhost
|
||||
defaultTimeout = 30 * time.Second
|
||||
stakingMinimumLeadTime = 25 * time.Second
|
||||
minStakeDuration = 24 * 14 * time.Hour
|
||||
// dedicated timeout for waiting on chain validators to become active
|
||||
chainValidatorWaitTimeout = 2 * time.Minute
|
||||
// FAIL FAST: Reduced from 45s to 30s for local deployments
|
||||
// For local networks, validators activate quickly (5-10s). If it takes longer,
|
||||
// something is wrong - fail fast with clear error rather than waiting forever.
|
||||
chainValidatorWaitTimeout = 30 * time.Second
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -197,8 +201,9 @@ func (ln *localNetwork) RegisterAliases(
|
||||
return fmt.Errorf("admin client is nil for node %v", nodeName)
|
||||
}
|
||||
// Retry with exponential backoff - nodes may not have discovered chain yet
|
||||
maxRetries := 10
|
||||
baseDelay := 500 * time.Millisecond
|
||||
// FAIL FAST: Reduced retries from 10 to 5, max delay from 5s to 2s
|
||||
maxRetries := 5
|
||||
baseDelay := 300 * time.Millisecond
|
||||
var lastErr error
|
||||
for attempt := 0; attempt < maxRetries; attempt++ {
|
||||
if err := (*adminClient).AliasChain(ctx, chainID, blockchainAlias); err != nil {
|
||||
@@ -214,8 +219,8 @@ func (ln *localNetwork) RegisterAliases(
|
||||
}
|
||||
lastErr = err
|
||||
delay := baseDelay * time.Duration(1<<attempt)
|
||||
if delay > 5*time.Second {
|
||||
delay = 5 * time.Second
|
||||
if delay > 2*time.Second {
|
||||
delay = 2 * time.Second // FAIL FAST: reduced max delay
|
||||
}
|
||||
ln.logger.Debug("alias registration failed, retrying",
|
||||
"node", nodeName,
|
||||
@@ -253,11 +258,17 @@ func (ln *localNetwork) waitForChainsDiscoveredOnAllNodes(
|
||||
fmt.Println()
|
||||
ln.logger.Info(log.Blue.Wrap(log.Bold.Wrap("waiting for chains to be discovered on all nodes...")))
|
||||
|
||||
// Use a longer timeout for chain discovery - VMs may need time to initialize
|
||||
// Especially for first-time deployments where VMs need to be loaded
|
||||
maxWait := 120 * time.Second // Extended timeout for VM initialization
|
||||
pollInterval := 500 * time.Millisecond // Poll frequently
|
||||
// FAIL FAST: Respect the context deadline, don't use hardcoded timeout
|
||||
// For local networks, chain discovery should complete in <30s
|
||||
// The context already has a timeout from the caller
|
||||
maxWait := 30 * time.Second // Max wait for local chain discovery
|
||||
pollInterval := 500 * time.Millisecond
|
||||
|
||||
// Use the earlier of: context deadline or our maxWait
|
||||
deadline := time.Now().Add(maxWait)
|
||||
if ctxDeadline, ok := ctx.Deadline(); ok && ctxDeadline.Before(deadline) {
|
||||
deadline = ctxDeadline
|
||||
}
|
||||
|
||||
for _, chainInfo := range chainInfos {
|
||||
blockchainID := chainInfo.blockchainID.String()
|
||||
@@ -392,9 +403,15 @@ func (ln *localNetwork) waitForBlockchainOnPChain(
|
||||
fmt.Println()
|
||||
ln.logger.Info(log.Blue.Wrap(log.Bold.Wrap("waiting for P-Chain to sync blockchain across all nodes...")))
|
||||
|
||||
maxWait := 60 * time.Second
|
||||
// FAIL FAST: Respect context deadline, don't use hardcoded 60s
|
||||
maxWait := 30 * time.Second // P-chain sync should be fast on localhost
|
||||
pollInterval := 500 * time.Millisecond
|
||||
|
||||
// Use the earlier of: context deadline or our maxWait
|
||||
deadline := time.Now().Add(maxWait)
|
||||
if ctxDeadline, ok := ctx.Deadline(); ok && ctxDeadline.Before(deadline) {
|
||||
deadline = ctxDeadline
|
||||
}
|
||||
|
||||
for _, blockchainID := range blockchainIDs {
|
||||
ln.logger.Info("waiting for blockchain on P-Chain",
|
||||
@@ -490,6 +507,7 @@ func (ln *localNetwork) waitForPeerConnectivity(ctx context.Context) error {
|
||||
|
||||
connected := false
|
||||
attemptCount := 0
|
||||
peerLoop:
|
||||
for time.Now().Before(deadline) {
|
||||
attemptCount++
|
||||
infoClient := node.GetAPIClient().InfoAPI()
|
||||
@@ -500,7 +518,11 @@ func (ln *localNetwork) waitForPeerConnectivity(ctx context.Context) error {
|
||||
"attempts", attemptCount,
|
||||
)
|
||||
}
|
||||
time.Sleep(pollInterval)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("context cancelled while waiting for peers on node %s: %w", nodeName, ctx.Err())
|
||||
case <-time.After(pollInterval):
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -513,7 +535,11 @@ func (ln *localNetwork) waitForPeerConnectivity(ctx context.Context) error {
|
||||
"attempts", attemptCount,
|
||||
)
|
||||
}
|
||||
time.Sleep(pollInterval)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("context cancelled while waiting for peers on node %s: %w", nodeName, ctx.Err())
|
||||
case <-time.After(pollInterval):
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -524,7 +550,7 @@ func (ln *localNetwork) waitForPeerConnectivity(ctx context.Context) error {
|
||||
"numPeers", len(peers),
|
||||
"attempts", attemptCount,
|
||||
)
|
||||
break
|
||||
break peerLoop
|
||||
}
|
||||
|
||||
if attemptCount%10 == 0 {
|
||||
@@ -535,7 +561,11 @@ func (ln *localNetwork) waitForPeerConnectivity(ctx context.Context) error {
|
||||
"attempts", attemptCount,
|
||||
)
|
||||
}
|
||||
time.Sleep(pollInterval)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("context cancelled while waiting for peers on node %s: %w", nodeName, ctx.Err())
|
||||
case <-time.After(pollInterval):
|
||||
}
|
||||
}
|
||||
|
||||
if !connected {
|
||||
@@ -608,7 +638,11 @@ func (ln *localNetwork) waitForPChainHeightSync(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
time.Sleep(pollInterval)
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return fmt.Errorf("context cancelled while waiting for P-Chain sync: %w", ctx.Err())
|
||||
case <-time.After(pollInterval):
|
||||
}
|
||||
}
|
||||
|
||||
// Log final state for debugging
|
||||
@@ -827,9 +861,9 @@ func (ln *localNetwork) installCustomChains(
|
||||
|
||||
// Wait for subnet creation transactions to be fully committed before adding validators
|
||||
// The P-Chain needs time to commit the subnet creation blocks and propagate state to all nodes
|
||||
// Increased from 5s to 15s to ensure state synchronization across all validators
|
||||
// For local networks, this should be very fast (1-2s). For public networks, may need longer.
|
||||
ln.logger.Info("waiting for subnet creation to be committed...")
|
||||
time.Sleep(15 * time.Second)
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
if err = ln.addChainValidators(ctx, platformCli, w, chainIDs, participantsSpecs); err != nil {
|
||||
ln.logger.Error("installCustomChains: failed to add chain validators",
|
||||
@@ -966,10 +1000,12 @@ func (ln *localNetwork) installCustomChains(
|
||||
}
|
||||
|
||||
// Reload VMs after restart to ensure any new VMs are available
|
||||
// CRITICAL FIX: Return error instead of swallowing - VM reload failure means chain won't work
|
||||
if err := ln.reloadVMPlugins(ctx); err != nil {
|
||||
ln.logger.Warn("VM hot-reload after chain creation failed (non-fatal)",
|
||||
ln.logger.Error("VM hot-reload after chain creation failed",
|
||||
"error", err.Error(),
|
||||
)
|
||||
return nil, fmt.Errorf("VM hot-reload failed after chain creation: %w", err)
|
||||
}
|
||||
|
||||
chainInfos := make([]blockchainInfo, len(chainSpecs))
|
||||
@@ -1133,22 +1169,22 @@ func (ln *localNetwork) waitForCustomChainsReady(
|
||||
)
|
||||
}
|
||||
|
||||
// Quick health check with 30s timeout - don't block forever
|
||||
// If network is healthy, chains should come up quickly
|
||||
healthCtx, cancel := context.WithTimeout(ctx, 30*time.Second)
|
||||
// FAIL FAST: 15s timeout for local chain health check
|
||||
// If chain isn't healthy in 15s on localhost, something is wrong - return error immediately
|
||||
healthCtx, cancel := context.WithTimeout(ctx, 15*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := ln.healthy(healthCtx); err != nil {
|
||||
// Log warning but don't fail - chain is created, may just need more time
|
||||
ln.logger.Warn("chain health check timed out, chain may still be starting",
|
||||
// CRITICAL FIX: Return error instead of swallowing it
|
||||
// This was causing CLI to wait forever while errors were logged but not returned
|
||||
ln.logger.Error("chain health check failed - returning error immediately",
|
||||
"error", err.Error(),
|
||||
)
|
||||
ln.logger.Info("use 'lux network status' to check chain health")
|
||||
} else {
|
||||
fmt.Println()
|
||||
ln.logger.Info(log.Green.Wrap("custom chains ready"))
|
||||
return fmt.Errorf("custom chains not ready within 15s: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println()
|
||||
ln.logger.Info(log.Green.Wrap("custom chains ready"))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1192,6 +1228,18 @@ func (ln *localNetwork) restartNodes(
|
||||
trackChainIDsSet.Add(s)
|
||||
}
|
||||
}
|
||||
|
||||
// OPTIMIZATION: Nodes with track-chains=all auto-discover all chains.
|
||||
// They don't need restart for new chain deployment - VM hot-reload is enough.
|
||||
// This prevents race conditions where VMs are killed during initialization.
|
||||
hasTrackAll := trackChainIDsSet.Contains("all")
|
||||
if hasTrackAll {
|
||||
ln.logger.Debug("node has track-chains=all, skipping restart",
|
||||
"nodeName", nodeName,
|
||||
)
|
||||
continue
|
||||
}
|
||||
|
||||
needsRestart := false
|
||||
for _, validatorSpec := range validatorSpecs {
|
||||
if validatorSpec.NodeName == node.name {
|
||||
@@ -2272,7 +2320,8 @@ func (ln *localNetwork) reloadVMPlugins(ctx context.Context) error {
|
||||
// with retry logic to handle hot-loading delays
|
||||
func (ln *localNetwork) verifyVMsAvailable(ctx context.Context, vmIDs []ids.ID) error {
|
||||
const (
|
||||
maxRetries = 10
|
||||
// FAIL FAST: Reduced retries from 10 to 5 (2.5s max)
|
||||
maxRetries = 5
|
||||
retryInterval = 500 * time.Millisecond
|
||||
)
|
||||
|
||||
|
||||
+249
-308
@@ -4,13 +4,13 @@
|
||||
package local
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/const"
|
||||
@@ -31,6 +31,79 @@ import (
|
||||
"github.com/luxfi/node/utils/formatting/address"
|
||||
)
|
||||
|
||||
// patchGenesisPreservingRaw patches a top-level genesis JSON document while guaranteeing that
|
||||
// selected keys are preserved byte-for-byte as raw JSON values (including quotes/escapes for strings).
|
||||
//
|
||||
// This is the correct approach for EVM genesis fields (C-Chain + any subnet EVM genesis) because
|
||||
// parsing via interface{} will corrupt large numeric fields and/or change encoding.
|
||||
//
|
||||
// CRITICAL: Never use map[string]interface{} for genesis - it causes float64 precision loss!
|
||||
func patchGenesisPreservingRaw(
|
||||
in []byte,
|
||||
preserveKeys []string,
|
||||
mutate func(m map[string]json.RawMessage) error,
|
||||
) ([]byte, error) {
|
||||
var m map[string]json.RawMessage
|
||||
if err := json.Unmarshal(in, &m); err != nil {
|
||||
return nil, fmt.Errorf("unmarshal genesis envelope: %w", err)
|
||||
}
|
||||
|
||||
// Snapshot preserved raw values.
|
||||
preserved := make(map[string]json.RawMessage, len(preserveKeys))
|
||||
for _, k := range preserveKeys {
|
||||
if v, ok := m[k]; ok {
|
||||
// deep copy
|
||||
preserved[k] = append(json.RawMessage(nil), v...)
|
||||
}
|
||||
}
|
||||
|
||||
// Apply edits.
|
||||
if err := mutate(m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Restore preserved values (even if mutate touched them by accident).
|
||||
for k, v := range preserved {
|
||||
m[k] = v
|
||||
}
|
||||
|
||||
// Marshal output.
|
||||
out, err := json.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("marshal genesis envelope: %w", err)
|
||||
}
|
||||
|
||||
// Sanity check: ensure preserved keys are still byte-identical.
|
||||
var m2 map[string]json.RawMessage
|
||||
if err := json.Unmarshal(out, &m2); err != nil {
|
||||
return nil, fmt.Errorf("re-unmarshal genesis envelope: %w", err)
|
||||
}
|
||||
for k, v := range preserved {
|
||||
if vv, ok := m2[k]; ok && !bytes.Equal(vv, v) {
|
||||
return nil, fmt.Errorf("FATAL: preserved genesis key %q mutated (byte mismatch)", k)
|
||||
}
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// mustJSON is a helper for assigning scalars/structs back into RawMessage maps.
|
||||
func mustJSON(v any) json.RawMessage {
|
||||
b, err := json.Marshal(v)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// evmGenesisKeys are the keys that MUST be preserved byte-for-byte in genesis.
|
||||
// These correspond to EVM chain genesis configurations.
|
||||
var evmGenesisKeys = []string{
|
||||
"cChainGenesis",
|
||||
// Add subnet EVM genesis keys if embedded in main genesis:
|
||||
// "hanzoGenesis", "spcGenesis", "zooGenesis",
|
||||
}
|
||||
|
||||
// NewConfigForNetwork creates a network config for the specified network ID.
|
||||
// This uses the proper genesis configuration from github.com/luxfi/genesis/configs.
|
||||
//
|
||||
@@ -104,12 +177,9 @@ func NewConfigForNetwork(binaryPath string, numNodes uint32, networkID uint32) (
|
||||
// - Use embedded validator keys from defaultNetworkConfig
|
||||
// - Keep initialStakers from genesis (already matches embedded keys)
|
||||
// - Generate P-chain allocations for the embedded validators
|
||||
|
||||
// Parse genesis to modify it
|
||||
var genesis map[string]interface{}
|
||||
if err := json.Unmarshal(genesisJSON, &genesis); err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to parse genesis: %w", err)
|
||||
}
|
||||
//
|
||||
// CRITICAL: Use patchGenesisPreservingRaw to ensure cChainGenesis bytes are NEVER modified.
|
||||
// Parsing via map[string]interface{} corrupts large numerics (float64 precision loss).
|
||||
|
||||
hrp := constants.GetHRP(networkID)
|
||||
|
||||
@@ -125,147 +195,133 @@ func NewConfigForNetwork(binaryPath string, numNodes uint32, networkID uint32) (
|
||||
numEmbeddedToUse = numEmbedded
|
||||
}
|
||||
|
||||
// For P/X-chain allocations, we need to create them for keys the wallet can use.
|
||||
// C-chain allocations are historic (embedded in genesis), but P/X can be set freely.
|
||||
// REPLACE allocations with ones for the wallet's key (mnemonic or private key).
|
||||
var newAllocations []interface{}
|
||||
// Patch genesis using RawMessage to preserve cChainGenesis byte-exact
|
||||
updatedGenesis, err := patchGenesisPreservingRaw(genesisJSON, evmGenesisKeys, func(m map[string]json.RawMessage) error {
|
||||
// Build P/X-chain allocations for wallet keys
|
||||
var newAllocations []map[string]interface{}
|
||||
|
||||
// If LUX_MNEMONIC is set, create allocations for mnemonic-derived key
|
||||
// Need BOTH X-chain (for transfers) and P-chain (for chain creation/validators)
|
||||
if mnemonic := os.Getenv("LUX_MNEMONIC"); mnemonic != "" {
|
||||
validatorKeys, err := keys.DeriveValidatorsFromMnemonic(mnemonic, 1)
|
||||
if err == nil && len(validatorKeys) > 0 {
|
||||
vk := validatorKeys[0]
|
||||
addr := vk.PChainAddr // Same underlying secp256k1 address
|
||||
xLuxAddr, errX := address.Format("X", hrp, addr[:])
|
||||
pLuxAddr, errP := address.Format("P", hrp, addr[:])
|
||||
if errX == nil && errP == nil {
|
||||
fmt.Printf("🔑 Setting X+P allocations for LUX_MNEMONIC: X=%s, P=%s (2B each)\n", xLuxAddr, pLuxAddr)
|
||||
// X-chain allocation (for asset transfers)
|
||||
newAllocations = append(newAllocations, map[string]interface{}{
|
||||
"ethAddr": vk.CChainAddrHex(),
|
||||
"luxAddr": xLuxAddr,
|
||||
"initialAmount": uint64(2000000000000000000), // 2B LUX
|
||||
"unlockSchedule": []map[string]interface{}{},
|
||||
})
|
||||
// P-chain allocation (for chain creation, validators)
|
||||
// IMPORTANT: Must have unlockSchedule entries for builder to create UTXOs
|
||||
newAllocations = append(newAllocations, map[string]interface{}{
|
||||
"ethAddr": vk.CChainAddrHex(),
|
||||
"luxAddr": pLuxAddr,
|
||||
"initialAmount": uint64(0), // Not used for P-chain, unlockSchedule is used
|
||||
"unlockSchedule": []map[string]interface{}{
|
||||
{
|
||||
"amount": uint64(2000000000000000000), // 2B LUX
|
||||
"locktime": uint64(0), // Immediately available
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If LUX_PRIVATE_KEY is set, also create X+P allocations for it
|
||||
if privKeyHex := os.Getenv("LUX_PRIVATE_KEY"); privKeyHex != "" {
|
||||
privKeyBytes, err := hex.DecodeString(privKeyHex)
|
||||
if err == nil && len(privKeyBytes) == 32 {
|
||||
luxPrivKey, err := luxcrypto.ToPrivateKey(privKeyBytes)
|
||||
if err == nil {
|
||||
pubKey := luxPrivKey.PublicKey()
|
||||
addr := ids.ShortID(pubKey.Address())
|
||||
// If LUX_MNEMONIC is set, create allocations for mnemonic-derived key
|
||||
if mnemonic := os.Getenv("LUX_MNEMONIC"); mnemonic != "" {
|
||||
validatorKeys, err := keys.DeriveValidatorsFromMnemonic(mnemonic, 1)
|
||||
if err == nil && len(validatorKeys) > 0 {
|
||||
vk := validatorKeys[0]
|
||||
addr := vk.PChainAddr
|
||||
xLuxAddr, errX := address.Format("X", hrp, addr[:])
|
||||
pLuxAddr, errP := address.Format("P", hrp, addr[:])
|
||||
if errX == nil && errP == nil {
|
||||
fmt.Printf("🔑 Adding X+P allocations for LUX_PRIVATE_KEY: X=%s, P=%s (2B each)\n", xLuxAddr, pLuxAddr)
|
||||
ethAddr := "0x" + hex.EncodeToString(addr[:])
|
||||
fmt.Printf("🔑 Setting X+P allocations for LUX_MNEMONIC: X=%s, P=%s (2B each)\n", xLuxAddr, pLuxAddr)
|
||||
// X-chain allocation
|
||||
newAllocations = append(newAllocations, map[string]interface{}{
|
||||
"ethAddr": ethAddr,
|
||||
"ethAddr": vk.CChainAddrHex(),
|
||||
"luxAddr": xLuxAddr,
|
||||
"initialAmount": uint64(2000000000000000000), // 2B LUX
|
||||
"unlockSchedule": []map[string]interface{}{},
|
||||
"initialAmount": uint64(2000000000000000000),
|
||||
"unlockSchedule": []interface{}{},
|
||||
})
|
||||
// P-chain allocation - must use unlockSchedule for builder to create UTXOs
|
||||
// P-chain allocation
|
||||
newAllocations = append(newAllocations, map[string]interface{}{
|
||||
"ethAddr": ethAddr,
|
||||
"ethAddr": vk.CChainAddrHex(),
|
||||
"luxAddr": pLuxAddr,
|
||||
"initialAmount": uint64(0), // Not used for P-chain
|
||||
"initialAmount": uint64(0),
|
||||
"unlockSchedule": []map[string]interface{}{
|
||||
{
|
||||
"amount": uint64(2000000000000000000), // 2B LUX
|
||||
"locktime": uint64(0), // Immediately available
|
||||
},
|
||||
{"amount": uint64(2000000000000000000), "locktime": uint64(0)},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we created new allocations, replace the genesis allocations
|
||||
// Otherwise, keep the genesis package's allocations (for backward compatibility)
|
||||
if len(newAllocations) > 0 {
|
||||
genesis["allocations"] = newAllocations
|
||||
}
|
||||
|
||||
// Generate initialStakers from embedded validator keys if not provided in genesis
|
||||
// This is needed because testnet/mainnet genesis may not have initialStakers defined
|
||||
initialStakers, hasStakers := genesis["initialStakers"]
|
||||
stakersSlice, isSlice := initialStakers.([]interface{})
|
||||
if !hasStakers || !isSlice || len(stakersSlice) == 0 {
|
||||
// Generate initialStakers from embedded validator keys
|
||||
var generatedStakers []map[string]interface{}
|
||||
for i := uint32(0); i < numEmbeddedToUse; i++ {
|
||||
embeddedConfig := defaultNetworkConfig.NodeConfigs[i]
|
||||
|
||||
// Get NodeID from staking cert
|
||||
nodeID, err := utils.ToNodeID([]byte(embeddedConfig.StakingKey), []byte(embeddedConfig.StakingCert))
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to get NodeID for node %d: %w", i, err)
|
||||
// If LUX_PRIVATE_KEY is set, also create X+P allocations for it
|
||||
if privKeyHex := os.Getenv("LUX_PRIVATE_KEY"); privKeyHex != "" {
|
||||
privKeyBytes, err := hex.DecodeString(privKeyHex)
|
||||
if err == nil && len(privKeyBytes) == 32 {
|
||||
luxPrivKey, err := luxcrypto.ToPrivateKey(privKeyBytes)
|
||||
if err == nil {
|
||||
pubKey := luxPrivKey.PublicKey()
|
||||
addr := ids.ShortID(pubKey.Address())
|
||||
xLuxAddr, errX := address.Format("X", hrp, addr[:])
|
||||
pLuxAddr, errP := address.Format("P", hrp, addr[:])
|
||||
if errX == nil && errP == nil {
|
||||
fmt.Printf("🔑 Adding X+P allocations for LUX_PRIVATE_KEY: X=%s, P=%s (2B each)\n", xLuxAddr, pLuxAddr)
|
||||
ethAddr := "0x" + hex.EncodeToString(addr[:])
|
||||
newAllocations = append(newAllocations, map[string]interface{}{
|
||||
"ethAddr": ethAddr,
|
||||
"luxAddr": xLuxAddr,
|
||||
"initialAmount": uint64(2000000000000000000),
|
||||
"unlockSchedule": []interface{}{},
|
||||
})
|
||||
newAllocations = append(newAllocations, map[string]interface{}{
|
||||
"ethAddr": ethAddr,
|
||||
"luxAddr": pLuxAddr,
|
||||
"initialAmount": uint64(0),
|
||||
"unlockSchedule": []map[string]interface{}{
|
||||
{"amount": uint64(2000000000000000000), "locktime": uint64(0)},
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get BLS key and compute ProofOfPossession
|
||||
blsKeyBytes, err := base64.StdEncoding.DecodeString(embeddedConfig.StakingSigningKey)
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to decode BLS key for node %d: %w", i, err)
|
||||
}
|
||||
blsSecretKey, err := bls.SecretKeyFromBytes(blsKeyBytes)
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to parse BLS key for node %d: %w", i, err)
|
||||
}
|
||||
pop, err := signer.NewProofOfPossession(blsSecretKey)
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to create ProofOfPossession for node %d: %w", i, err)
|
||||
}
|
||||
|
||||
// Create staker entry - use a reward address derived from the first key or a treasury address
|
||||
// For simplicity, use the X-chain address from the first allocation or default
|
||||
staker := map[string]interface{}{
|
||||
"nodeID": nodeID.String(),
|
||||
"rewardAddress": "P-test1yljhuvjkmtu0y5ls6kf4exsdd8gea9mp7faxl2", // Default testnet treasury
|
||||
"delegationFee": uint32(20000), // 2%
|
||||
"signer": map[string]interface{}{
|
||||
"publicKey": fmt.Sprintf("0x%x", pop.PublicKey[:]),
|
||||
"proofOfPossession": fmt.Sprintf("0x%x", pop.ProofOfPossession[:]),
|
||||
},
|
||||
}
|
||||
generatedStakers = append(generatedStakers, staker)
|
||||
}
|
||||
genesis["initialStakers"] = generatedStakers
|
||||
fmt.Printf("🔧 Generated %d initialStakers from embedded validator keys\n", len(generatedStakers))
|
||||
}
|
||||
|
||||
// Set initialStakedFunds to empty - allocations are for free balance, not staking
|
||||
genesis["initialStakedFunds"] = []string{}
|
||||
// Update allocations if we have new ones
|
||||
if len(newAllocations) > 0 {
|
||||
m["allocations"] = mustJSON(newAllocations)
|
||||
}
|
||||
|
||||
// Update start time to now
|
||||
now := time.Now().Unix()
|
||||
genesis["startTime"] = uint64(now)
|
||||
// Check if we need to generate initialStakers
|
||||
var existingStakers []interface{}
|
||||
if raw, ok := m["initialStakers"]; ok {
|
||||
json.Unmarshal(raw, &existingStakers)
|
||||
}
|
||||
if len(existingStakers) == 0 {
|
||||
// Generate initialStakers from embedded validator keys
|
||||
var generatedStakers []map[string]interface{}
|
||||
for i := uint32(0); i < numEmbeddedToUse; i++ {
|
||||
embeddedConfig := defaultNetworkConfig.NodeConfigs[i]
|
||||
|
||||
// Re-serialize genesis
|
||||
updatedGenesis, err := json.MarshalIndent(genesis, "", " ")
|
||||
nodeID, err := utils.ToNodeID([]byte(embeddedConfig.StakingKey), []byte(embeddedConfig.StakingCert))
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get NodeID for node %d: %w", i, err)
|
||||
}
|
||||
|
||||
blsKeyBytes, err := base64.StdEncoding.DecodeString(embeddedConfig.StakingSigningKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to decode BLS key for node %d: %w", i, err)
|
||||
}
|
||||
blsSecretKey, err := bls.SecretKeyFromBytes(blsKeyBytes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to parse BLS key for node %d: %w", i, err)
|
||||
}
|
||||
pop, err := signer.NewProofOfPossession(blsSecretKey)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create ProofOfPossession for node %d: %w", i, err)
|
||||
}
|
||||
|
||||
staker := map[string]interface{}{
|
||||
"nodeID": nodeID.String(),
|
||||
"rewardAddress": "P-test1yljhuvjkmtu0y5ls6kf4exsdd8gea9mp7faxl2",
|
||||
"delegationFee": uint32(20000),
|
||||
"signer": map[string]interface{}{
|
||||
"publicKey": fmt.Sprintf("0x%x", pop.PublicKey[:]),
|
||||
"proofOfPossession": fmt.Sprintf("0x%x", pop.ProofOfPossession[:]),
|
||||
},
|
||||
}
|
||||
generatedStakers = append(generatedStakers, staker)
|
||||
}
|
||||
m["initialStakers"] = mustJSON(generatedStakers)
|
||||
fmt.Printf("🔧 Generated %d initialStakers from embedded validator keys\n", len(generatedStakers))
|
||||
}
|
||||
|
||||
// Set initialStakedFunds to empty
|
||||
m["initialStakedFunds"] = mustJSON([]string{})
|
||||
|
||||
// Update start time to now
|
||||
now := time.Now().Unix()
|
||||
m["startTime"] = mustJSON(uint64(now))
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to serialize updated genesis: %w", err)
|
||||
return network.Config{}, fmt.Errorf("failed to patch genesis: %w", err)
|
||||
}
|
||||
netConfig.Genesis = string(updatedGenesis)
|
||||
|
||||
@@ -369,11 +425,24 @@ func NewCanonicalCustomConfig(binaryPath string, numNodes uint32) (network.Confi
|
||||
// and loads validator keys from ~/.lux/keys/node{0..n-1}/
|
||||
func newCanonicalConfig(binaryPath string, numNodes uint32, networkID uint32, portBase int) (network.Config, error) {
|
||||
// Load CANONICAL genesis bytes - no parsing/re-serialization
|
||||
genesisBytes, err := configs.GetCanonicalGenesisBytes(networkID)
|
||||
originalGenesisBytes, err := configs.GetCanonicalGenesisBytes(networkID)
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to load canonical genesis: %w", err)
|
||||
}
|
||||
|
||||
// For LOCAL TESTING: Update startTime to now so bootstrap starts immediately.
|
||||
// CRITICAL: Use patchGenesisPreservingRaw to preserve cChainGenesis exact bytes.
|
||||
now := time.Now().Unix()
|
||||
fmt.Printf("📅 Updated genesis startTime to %d (now) for local testing\n", now)
|
||||
|
||||
genesisBytes, err := patchGenesisPreservingRaw(originalGenesisBytes, evmGenesisKeys, func(m map[string]json.RawMessage) error {
|
||||
m["startTime"] = mustJSON(uint64(now))
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to patch genesis: %w", err)
|
||||
}
|
||||
|
||||
// Start with default config
|
||||
netConfig := NewDefaultConfig(binaryPath)
|
||||
netConfig.Genesis = string(genesisBytes)
|
||||
@@ -506,16 +575,11 @@ func NewConfigWithPreExistingKeys(binaryPath string, networkID uint32, keysDir s
|
||||
// Start with the default config structure
|
||||
netConfig := NewDefaultConfig(binaryPath)
|
||||
|
||||
// Parse genesis to modify it
|
||||
var genesis map[string]interface{}
|
||||
if err := json.Unmarshal(genesisJSON, &genesis); err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to parse genesis: %w", err)
|
||||
}
|
||||
|
||||
// Build initial stakers from loaded keys
|
||||
// Build P/X chain data BEFORE patching genesis
|
||||
hrp := constants.GetHRP(networkID)
|
||||
numNodes := uint32(len(validatorKeys))
|
||||
|
||||
// Build initial stakers from loaded keys
|
||||
initialStakers := make([]map[string]interface{}, numNodes)
|
||||
for i, vk := range validatorKeys {
|
||||
rewardAddr, err := address.Format("P", hrp, vk.PChainAddr[:])
|
||||
@@ -526,11 +590,10 @@ func NewConfigWithPreExistingKeys(binaryPath string, networkID uint32, keysDir s
|
||||
staker := map[string]interface{}{
|
||||
"nodeID": vk.NodeID.String(),
|
||||
"rewardAddress": rewardAddr,
|
||||
"delegationFee": 20000, // 2% delegation fee
|
||||
"weight": GigaLux, // 1,000,000,000 LUX (1B) per validator
|
||||
"delegationFee": 20000,
|
||||
"weight": GigaLux,
|
||||
}
|
||||
|
||||
// Add BLS signer if available
|
||||
if len(vk.BLSPublicKey) > 0 && len(vk.BLSPoP) > 0 {
|
||||
staker["signer"] = map[string]interface{}{
|
||||
"publicKey": vk.BLSPublicKeyHex(),
|
||||
@@ -541,44 +604,32 @@ func NewConfigWithPreExistingKeys(binaryPath string, networkID uint32, keysDir s
|
||||
initialStakers[i] = staker
|
||||
}
|
||||
|
||||
// Update genesis with initial stakers (our validator NodeIDs)
|
||||
genesis["initialStakers"] = initialStakers
|
||||
|
||||
// Generate allocations from validator keys (rather than expecting pre-existing allocations)
|
||||
// Each validator gets both X-chain and P-chain allocations
|
||||
// X-chain: 1B LUX immediately available
|
||||
// P-chain: 1B LUX with 1% unlock per year for 100 years starting Jan 1 2020
|
||||
allocations := make([]interface{}, 0, numNodes*2)
|
||||
|
||||
// Constants for P-chain unlock schedule
|
||||
// Build allocations
|
||||
const (
|
||||
oneGigaLux = uint64(1000000000000000000) // 1B LUX in nLUX
|
||||
onePercentPerYear = oneGigaLux / 100 // 1% = 10M LUX
|
||||
jan1_2020 = uint64(1577836800) // Unix timestamp
|
||||
oneYear = uint64(31536000) // seconds
|
||||
oneGigaLux = uint64(1000000000000000000)
|
||||
onePercentPerYear = oneGigaLux / 100
|
||||
jan1_2020 = uint64(1577836800)
|
||||
oneYear = uint64(31536000)
|
||||
)
|
||||
|
||||
var allocations []map[string]interface{}
|
||||
for i, vk := range validatorKeys {
|
||||
// Build P-chain address
|
||||
pChainAddr, err := address.Format("P", hrp, vk.PChainAddr[:])
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to format P-chain address for validator %d: %w", i, err)
|
||||
}
|
||||
// Build X-chain address
|
||||
xChainAddr, err := address.Format("X", hrp, vk.PChainAddr[:])
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to format X-chain address for validator %d: %w", i, err)
|
||||
}
|
||||
|
||||
// X-chain allocation (1B LUX) - immediately available
|
||||
allocations = append(allocations, map[string]interface{}{
|
||||
"ethAddr": vk.CChainAddrHex(),
|
||||
"luxAddr": xChainAddr,
|
||||
"initialAmount": oneGigaLux,
|
||||
"unlockSchedule": []map[string]interface{}{},
|
||||
"unlockSchedule": []interface{}{},
|
||||
})
|
||||
|
||||
// P-chain allocation (1B LUX) - 1% per year for 100 years
|
||||
pchainUnlockSchedule := make([]map[string]interface{}, 100)
|
||||
for year := 0; year < 100; year++ {
|
||||
pchainUnlockSchedule[year] = map[string]interface{}{
|
||||
@@ -595,94 +646,65 @@ func NewConfigWithPreExistingKeys(binaryPath string, networkID uint32, keysDir s
|
||||
|
||||
fmt.Printf(" Validator %d: %s -> X:%s P:%s (1B each)\n", i+1, vk.NodeID.String(), xChainAddr, pChainAddr)
|
||||
}
|
||||
genesis["allocations"] = allocations
|
||||
|
||||
// Set initialStakedFunds to EMPTY - we use explicit weight in initialStakers
|
||||
genesis["initialStakedFunds"] = []string{}
|
||||
|
||||
// Check for LUX_MNEMONIC and add mnemonic-derived allocation with FREE funds
|
||||
// This enables subnet creation without needing the hardcoded treasury key
|
||||
// IMPORTANT: Add this AFTER setting initialStakedFunds so mnemonic funds are NOT staked
|
||||
// Add mnemonic allocation if set
|
||||
if mnemonic := os.Getenv("LUX_MNEMONIC"); mnemonic != "" {
|
||||
fmt.Printf("🔑 LUX_MNEMONIC is set, adding mnemonic allocation to genesis\n")
|
||||
mnemonicAlloc := map[string]interface{}{
|
||||
allocations = append(allocations, map[string]interface{}{
|
||||
"ethAddr": "0x0406d56943a38ad8398a738527f27e2cf01731a8",
|
||||
"luxAddr": "P-lux1qsrd262r5w9dswv2wwzj0un79ncpwvdgkpqzqu",
|
||||
"initialAmount": 0,
|
||||
"unlockSchedule": []map[string]interface{}{
|
||||
{
|
||||
"amount": uint64(100000000000000), // 100,000 LUX
|
||||
"locktime": uint64(0),
|
||||
},
|
||||
{"amount": uint64(100000000000000), "locktime": uint64(0)},
|
||||
},
|
||||
}
|
||||
|
||||
// Append mnemonic allocation directly to our allocations slice
|
||||
fmt.Printf(" Adding mnemonic allocation (NOT staked) to %d existing allocations\n", len(allocations))
|
||||
allocations = append(allocations, mnemonicAlloc)
|
||||
genesis["allocations"] = allocations
|
||||
} else {
|
||||
fmt.Printf("⚠️ LUX_MNEMONIC not set, skipping mnemonic allocation\n")
|
||||
})
|
||||
}
|
||||
|
||||
// Check for LUX_PRIVATE_KEY and add allocations with correct HRP for this network
|
||||
// This enables deploy operations when using a specific private key
|
||||
// Add private key allocation if set
|
||||
var initialStakedFunds []string
|
||||
if privKeyHex := os.Getenv("LUX_PRIVATE_KEY"); privKeyHex != "" {
|
||||
privKeyBytes, err := hex.DecodeString(privKeyHex)
|
||||
if err == nil && len(privKeyBytes) == 32 {
|
||||
// Derive address from private key
|
||||
luxPrivKey, err := luxcrypto.ToPrivateKey(privKeyBytes)
|
||||
if err == nil {
|
||||
pubKey := luxPrivKey.PublicKey()
|
||||
pChainAddr := ids.ShortID(pubKey.Address())
|
||||
|
||||
// Format addresses with the correct HRP for this network
|
||||
xLuxAddr, errX := address.Format("X", hrp, pChainAddr[:])
|
||||
pLuxAddr, errP := address.Format("P", hrp, pChainAddr[:])
|
||||
if errX == nil && errP == nil {
|
||||
ethAddr := "0x" + hex.EncodeToString(pChainAddr[:])
|
||||
fmt.Printf("🔑 Adding LUX_PRIVATE_KEY allocations: X=%s, P=%s (2B each)\n", xLuxAddr, pLuxAddr)
|
||||
|
||||
// X-chain allocation (2B LUX) - immediately available
|
||||
allocations = append(allocations, map[string]interface{}{
|
||||
"ethAddr": ethAddr,
|
||||
"luxAddr": xLuxAddr,
|
||||
"initialAmount": uint64(2000000000000000000), // 2B LUX
|
||||
"unlockSchedule": []map[string]interface{}{},
|
||||
"initialAmount": uint64(2000000000000000000),
|
||||
"unlockSchedule": []interface{}{},
|
||||
})
|
||||
|
||||
// P-chain allocation (2B LUX) - immediately available for subnet creation
|
||||
allocations = append(allocations, map[string]interface{}{
|
||||
"ethAddr": ethAddr,
|
||||
"luxAddr": pLuxAddr,
|
||||
"initialAmount": uint64(0),
|
||||
"unlockSchedule": []map[string]interface{}{
|
||||
{
|
||||
"amount": uint64(2000000000000000000), // 2B LUX
|
||||
"locktime": uint64(0), // Immediately available
|
||||
},
|
||||
{"amount": uint64(2000000000000000000), "locktime": uint64(0)},
|
||||
},
|
||||
})
|
||||
genesis["allocations"] = allocations
|
||||
|
||||
// Add to initialStakedFunds for P-chain access
|
||||
initialStakedFunds, _ := genesis["initialStakedFunds"].([]string)
|
||||
initialStakedFunds = append(initialStakedFunds, xLuxAddr)
|
||||
genesis["initialStakedFunds"] = initialStakedFunds
|
||||
fmt.Printf("🔑 Added %s to initialStakedFunds for P-chain access\n", xLuxAddr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update start time to now
|
||||
// Patch genesis using RawMessage to preserve cChainGenesis byte-exact
|
||||
now := time.Now().Unix()
|
||||
genesis["startTime"] = uint64(now)
|
||||
|
||||
// Re-serialize genesis
|
||||
updatedGenesis, err := json.MarshalIndent(genesis, "", " ")
|
||||
updatedGenesis, err := patchGenesisPreservingRaw(genesisJSON, evmGenesisKeys, func(m map[string]json.RawMessage) error {
|
||||
m["initialStakers"] = mustJSON(initialStakers)
|
||||
m["allocations"] = mustJSON(allocations)
|
||||
m["initialStakedFunds"] = mustJSON(initialStakedFunds)
|
||||
m["startTime"] = mustJSON(uint64(now))
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to serialize updated genesis: %w", err)
|
||||
return network.Config{}, fmt.Errorf("failed to patch genesis: %w", err)
|
||||
}
|
||||
netConfig.Genesis = string(updatedGenesis)
|
||||
|
||||
@@ -848,42 +870,27 @@ func NewConfigFromMnemonic(binaryPath string, networkID uint32, numNodes uint32)
|
||||
// Start with default config
|
||||
netConfig := NewDefaultConfig(binaryPath)
|
||||
|
||||
// Parse genesis to modify it
|
||||
var genesis map[string]interface{}
|
||||
if err := json.Unmarshal(genesisJSON, &genesis); err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to parse genesis: %w", err)
|
||||
}
|
||||
|
||||
hrp := constants.GetHRP(networkID)
|
||||
|
||||
// Build initial stakers from derived keys
|
||||
initialStakers := make([]map[string]interface{}, numNodes)
|
||||
// Each validator gets BOTH X-chain AND P-chain allocations (2 entries per validator)
|
||||
allocations := make([]interface{}, 0, numNodes*2)
|
||||
var allocations []map[string]interface{}
|
||||
|
||||
for i, vk := range validatorKeys {
|
||||
fmt.Printf("🔍 Validator %d: PChainAddr ShortID = %s\n", i, vk.PChainAddr.String())
|
||||
|
||||
// Build P-chain address for staker rewards and P-chain operations
|
||||
pChainAddr, err := address.Format("P", hrp, vk.PChainAddr[:])
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to format P-chain address for validator %d: %w", i, err)
|
||||
}
|
||||
fmt.Printf("🔍 Validator %d: P-chain bech32 = %s\n", i, pChainAddr)
|
||||
|
||||
// Build X-chain address for asset transfers
|
||||
xChainAddr, err := address.Format("X", hrp, vk.PChainAddr[:])
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to format X-chain address for validator %d: %w", i, err)
|
||||
}
|
||||
fmt.Printf("🔍 Validator %d: X-chain bech32 = %s\n", i, xChainAddr)
|
||||
|
||||
// Initial staker entry
|
||||
staker := map[string]interface{}{
|
||||
"nodeID": vk.NodeID.String(),
|
||||
"rewardAddress": xChainAddr, // Rewards go to X-chain address
|
||||
"delegationFee": 20000, // 2% delegation fee
|
||||
"weight": GigaLux, // 1B LUX per validator
|
||||
"rewardAddress": xChainAddr,
|
||||
"delegationFee": 20000,
|
||||
"weight": GigaLux,
|
||||
}
|
||||
if len(vk.BLSPublicKey) > 0 && len(vk.BLSPoP) > 0 {
|
||||
staker["signer"] = map[string]interface{}{
|
||||
@@ -893,26 +900,18 @@ func NewConfigFromMnemonic(binaryPath string, networkID uint32, numNodes uint32)
|
||||
}
|
||||
initialStakers[i] = staker
|
||||
|
||||
// X-chain allocation (2B LUX) - for asset transfers
|
||||
allocations = append(allocations, map[string]interface{}{
|
||||
"ethAddr": vk.CChainAddrHex(),
|
||||
"luxAddr": xChainAddr,
|
||||
"initialAmount": uint64(2000000000000000000), // 2B LUX
|
||||
"unlockSchedule": []map[string]interface{}{},
|
||||
"initialAmount": uint64(2000000000000000000),
|
||||
"unlockSchedule": []interface{}{},
|
||||
})
|
||||
|
||||
// P-chain allocation (2B LUX) - for chain creation, validators
|
||||
// P-chain allocation - MUST use unlockSchedule for P-chain UTXOs
|
||||
// The builder processes unlockSchedule for P-chain, initialAmount for X-chain
|
||||
allocations = append(allocations, map[string]interface{}{
|
||||
"ethAddr": vk.CChainAddrHex(),
|
||||
"luxAddr": pChainAddr,
|
||||
"initialAmount": uint64(0),
|
||||
"unlockSchedule": []map[string]interface{}{
|
||||
{
|
||||
"amount": uint64(2000000000000000000), // 2B LUX
|
||||
"locktime": uint64(0), // locktime 0 = immediately unlocked
|
||||
},
|
||||
{"amount": uint64(2000000000000000000), "locktime": uint64(0)},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -921,43 +920,33 @@ func NewConfigFromMnemonic(binaryPath string, networkID uint32, numNodes uint32)
|
||||
|
||||
// Add wallet key allocation if different from validators
|
||||
if walletNeedsAllocation {
|
||||
// Build X-chain address for wallet
|
||||
walletXAddr, err := address.Format("X", hrp, walletKey.PChainAddr[:])
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to format wallet X-chain address: %w", err)
|
||||
}
|
||||
// Build P-chain address for wallet
|
||||
walletPAddr, err := address.Format("P", hrp, walletKey.PChainAddr[:])
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to format wallet P-chain address: %w", err)
|
||||
}
|
||||
|
||||
// X-chain allocation for wallet (2B LUX)
|
||||
allocations = append(allocations, map[string]interface{}{
|
||||
"ethAddr": walletKey.CChainAddrHex(),
|
||||
"luxAddr": walletXAddr,
|
||||
"initialAmount": uint64(2000000000000000000), // 2B LUX
|
||||
"unlockSchedule": []map[string]interface{}{},
|
||||
"initialAmount": uint64(2000000000000000000),
|
||||
"unlockSchedule": []interface{}{},
|
||||
})
|
||||
|
||||
// P-chain allocation for wallet (2B LUX) - MUST use unlockSchedule
|
||||
allocations = append(allocations, map[string]interface{}{
|
||||
"ethAddr": walletKey.CChainAddrHex(),
|
||||
"luxAddr": walletPAddr,
|
||||
"initialAmount": uint64(0),
|
||||
"unlockSchedule": []map[string]interface{}{
|
||||
{
|
||||
"amount": uint64(2000000000000000000), // 2B LUX
|
||||
"locktime": uint64(0), // locktime 0 = immediately unlocked
|
||||
},
|
||||
{"amount": uint64(2000000000000000000), "locktime": uint64(0)},
|
||||
},
|
||||
})
|
||||
|
||||
fmt.Printf(" Wallet: %s -> X:%s P:%s (2B each)\n", walletKey.PChainAddr.String(), walletXAddr, walletPAddr)
|
||||
}
|
||||
|
||||
// Also add allocations for LUX_PRIVATE_KEY if set and different from wallet key
|
||||
// This is needed when getDefaultKey() in blockchain.go uses LUX_PRIVATE_KEY
|
||||
// Add LUX_PRIVATE_KEY allocations if set and different from wallet key
|
||||
if privKeyHex := os.Getenv("LUX_PRIVATE_KEY"); privKeyHex != "" {
|
||||
privKeyBytes, err := hex.DecodeString(privKeyHex)
|
||||
if err == nil && len(privKeyBytes) == 32 {
|
||||
@@ -966,92 +955,44 @@ func NewConfigFromMnemonic(binaryPath string, networkID uint32, numNodes uint32)
|
||||
pubKey := luxPrivKey.PublicKey()
|
||||
privKeyAddr := ids.ShortID(pubKey.Address())
|
||||
|
||||
// Check if this is different from wallet key
|
||||
if privKeyAddr != walletKey.PChainAddr {
|
||||
privKeyXAddr, errX := address.Format("X", hrp, privKeyAddr[:])
|
||||
privKeyPAddr, errP := address.Format("P", hrp, privKeyAddr[:])
|
||||
if errX == nil && errP == nil {
|
||||
fmt.Printf("🔑 Adding LUX_PRIVATE_KEY allocations (with %s HRP): X=%s P=%s (2B each)\n", hrp, privKeyXAddr, privKeyPAddr)
|
||||
fmt.Printf("🔑 Adding LUX_PRIVATE_KEY allocations: X=%s P=%s (2B each)\n", privKeyXAddr, privKeyPAddr)
|
||||
ethAddr := "0x" + hex.EncodeToString(privKeyAddr[:])
|
||||
|
||||
// X-chain allocation
|
||||
allocations = append(allocations, map[string]interface{}{
|
||||
"ethAddr": ethAddr,
|
||||
"luxAddr": privKeyXAddr,
|
||||
"initialAmount": uint64(2000000000000000000), // 2B LUX
|
||||
"unlockSchedule": []map[string]interface{}{},
|
||||
"initialAmount": uint64(2000000000000000000),
|
||||
"unlockSchedule": []interface{}{},
|
||||
})
|
||||
|
||||
// P-chain allocation - MUST use unlockSchedule
|
||||
allocations = append(allocations, map[string]interface{}{
|
||||
"ethAddr": ethAddr,
|
||||
"luxAddr": privKeyPAddr,
|
||||
"initialAmount": uint64(0),
|
||||
"unlockSchedule": []map[string]interface{}{
|
||||
{
|
||||
"amount": uint64(2000000000000000000), // 2B LUX
|
||||
"locktime": uint64(0), // locktime 0 = immediately unlocked
|
||||
},
|
||||
{"amount": uint64(2000000000000000000), "locktime": uint64(0)},
|
||||
},
|
||||
})
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("🔑 LUX_PRIVATE_KEY matches wallet key, no extra allocation needed\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
genesis["initialStakers"] = initialStakers
|
||||
genesis["allocations"] = allocations
|
||||
|
||||
// CRITICAL: Also update xChainGenesis.allocations!
|
||||
// The X-chain reads allocations from the embedded xChainGenesis JSON string,
|
||||
// NOT from the top-level allocations array. We must update both.
|
||||
if xChainGenesisStr, ok := genesis["xChainGenesis"].(string); ok {
|
||||
var xChainGenesis map[string]interface{}
|
||||
if err := json.Unmarshal([]byte(xChainGenesisStr), &xChainGenesis); err == nil {
|
||||
// Build X-chain specific allocations (only X-chain addresses, use avaxAddr format)
|
||||
xAllocations := make([]map[string]interface{}, 0)
|
||||
for _, alloc := range allocations {
|
||||
allocMap := alloc.(map[string]interface{})
|
||||
luxAddr, _ := allocMap["luxAddr"].(string)
|
||||
// Only include X-chain allocations (start with "X-")
|
||||
if strings.HasPrefix(luxAddr, "X-") {
|
||||
initialAmount, _ := allocMap["initialAmount"].(uint64)
|
||||
if initialAmount > 0 {
|
||||
xAllocations = append(xAllocations, map[string]interface{}{
|
||||
"avaxAddr": luxAddr, // X-chain uses avaxAddr field name
|
||||
"ethAddr": allocMap["ethAddr"],
|
||||
"initialAmount": initialAmount,
|
||||
"unlockSchedule": []interface{}{},
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
xChainGenesis["allocations"] = xAllocations
|
||||
if updatedXChain, err := json.Marshal(xChainGenesis); err == nil {
|
||||
genesis["xChainGenesis"] = string(updatedXChain)
|
||||
fmt.Printf("✅ Updated xChainGenesis with %d allocations\n", len(xAllocations))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IMPORTANT: Set initialStakedFunds to EMPTY so that P-chain allocations
|
||||
// are NOT filtered by the builder. The builder filters allocations where
|
||||
// the underlying ShortID matches initialStakedFunds, which would incorrectly
|
||||
// filter P-chain allocations that share the same address as X-chain validators.
|
||||
// We use explicit weight in initialStakers instead of deriving from stakes.
|
||||
genesis["initialStakedFunds"] = []string{}
|
||||
|
||||
// Update start time to now
|
||||
// Patch genesis using RawMessage to preserve cChainGenesis byte-exact
|
||||
// CRITICAL: Never use map[string]interface{} for genesis - it causes float64 precision loss!
|
||||
now := time.Now().Unix()
|
||||
genesis["startTime"] = uint64(now)
|
||||
|
||||
// Re-serialize genesis
|
||||
updatedGenesis, err := json.MarshalIndent(genesis, "", " ")
|
||||
updatedGenesis, err := patchGenesisPreservingRaw(genesisJSON, evmGenesisKeys, func(m map[string]json.RawMessage) error {
|
||||
m["initialStakers"] = mustJSON(initialStakers)
|
||||
m["allocations"] = mustJSON(allocations)
|
||||
m["initialStakedFunds"] = mustJSON([]string{})
|
||||
m["startTime"] = mustJSON(uint64(now))
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return network.Config{}, fmt.Errorf("failed to serialize genesis: %w", err)
|
||||
return network.Config{}, fmt.Errorf("failed to patch genesis: %w", err)
|
||||
}
|
||||
netConfig.Genesis = string(updatedGenesis)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (C) 2025, Lux Industries Inc. All rights reserved.
|
||||
// Copyright (C) 2021-2025, Lux Industries Inc. All rights reserved.
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
package main
|
||||
|
||||
|
||||
@@ -266,6 +266,14 @@ func (lc *localNetwork) createConfig() error {
|
||||
cfg.Flags[k] = v
|
||||
}
|
||||
|
||||
// Extract track-chains from global config if present
|
||||
// This allows CLI to pass track-chains in globalNodeConfig JSON
|
||||
if trackChainsVal, ok := globalConfig["track-chains"]; ok {
|
||||
if trackChainsStr, ok := trackChainsVal.(string); ok {
|
||||
lc.options.trackChains = trackChainsStr
|
||||
}
|
||||
}
|
||||
|
||||
if lc.pluginDir != "" {
|
||||
cfg.Flags[config.PluginDirKey] = lc.pluginDir
|
||||
}
|
||||
@@ -290,6 +298,12 @@ func (lc *localNetwork) createConfig() error {
|
||||
cfg.NodeConfigs[i].ChainConfigFiles = map[string]string{}
|
||||
}
|
||||
|
||||
// Propagate global config flags to each node config
|
||||
// This ensures track-chains and other global settings apply to all nodes
|
||||
for k, v := range globalConfig {
|
||||
cfg.NodeConfigs[i].Flags[k] = v
|
||||
}
|
||||
|
||||
for k, v := range lc.options.chainConfigs {
|
||||
cfg.NodeConfigs[i].ChainConfigFiles[k] = v
|
||||
}
|
||||
|
||||
+12
-5
@@ -53,9 +53,14 @@ const (
|
||||
|
||||
stopTimeout = 5 * time.Second
|
||||
defaultStartTimeout = 5 * time.Minute
|
||||
// waitForHealthyTimeout increased from 3 to 10 minutes to allow proper
|
||||
// bootstrapping of staking validators in mainnet configuration
|
||||
waitForHealthyTimeout = 10 * time.Minute
|
||||
// waitForHealthyTimeout - 60s for local 5-node network bootstrap
|
||||
// First startup takes longer as nodes need to establish consensus
|
||||
// Subsequent restarts are faster (<10s) but initial bootstrap needs time
|
||||
waitForHealthyTimeout = 60 * time.Second
|
||||
// chainDeployTimeout - 30s MAX for chain deploy operations
|
||||
// FAIL FAST: If chain deploy takes longer than 30s, something is wrong
|
||||
// Most P-chain API calls complete in <5s on localhost
|
||||
chainDeployTimeout = 30 * time.Second
|
||||
|
||||
TimeParseLayout = "2006-01-02 15:04:05"
|
||||
StakingMinimumLeadTime = 25 * time.Second
|
||||
@@ -619,10 +624,12 @@ func (s *server) CreateBlockchains(
|
||||
|
||||
s.logger.Info("CreateBlockchains: starting chain creation",
|
||||
log.Int("numChains", len(chainSpecs)),
|
||||
log.Duration("timeout", waitForHealthyTimeout),
|
||||
log.Duration("timeout", chainDeployTimeout),
|
||||
)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), waitForHealthyTimeout)
|
||||
// FAIL FAST: Use shorter timeout for chain deploy operations
|
||||
// 30s is plenty for local P-chain operations; if it takes longer, something is wrong
|
||||
ctx, cancel := context.WithTimeout(context.Background(), chainDeployTimeout)
|
||||
defer cancel()
|
||||
chainIDs, err := s.network.CreateChains(ctx, chainSpecs)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user