mirror of
https://github.com/luxfi/node.git
synced 2026-07-29 00:26:40 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0165a92f3 |
@@ -1,24 +1,44 @@
|
||||
bazil.org/fuse v0.0.0-20230120002735-62a210ff1fd5/go.mod h1:gG3RZAMXCa/OTes6rr9EwusmR1OH1tDDy+cg9c5YliY=
|
||||
c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd h1:ZLsPO6WdZ5zatV4UfVpr7oAwLGRZ+sebTUruuM4Ra3M=
|
||||
c2sp.org/CCTV/age v0.0.0-20251208015420-e9274a7bdbfd/go.mod h1:SrHC2C7r5GkDk8R+NFVzYy/sdj0Ypg9htaPXQq5Cqeo=
|
||||
capnproto.org/go/capnp/v3 v3.0.1-alpha.2/go.mod h1:2vT5D2dtG8sJGEoEKU17e+j7shdaYp1Myl8X03B3hmc=
|
||||
codeberg.org/go-fonts/liberation v0.5.0/go.mod h1:zS/2e1354/mJ4pGzIIaEtm/59VFCFnYC7YV6YdGl5GU=
|
||||
codeberg.org/go-latex/latex v0.1.0/go.mod h1:LA0q/AyWIYrqVd+A9Upkgsb+IqPcmSTKc9Dny04MHMw=
|
||||
codeberg.org/go-pdf/fpdf v0.10.0/go.mod h1:Y0DGRAdZ0OmnZPvjbMp/1bYxmIPxm0ws4tfoPOc4LjU=
|
||||
connectrpc.com/connect v1.19.1/go.mod h1:tN20fjdGlewnSFeZxLKb0xwIZ6ozc3OQs2hTXy4du9w=
|
||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||
filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo=
|
||||
filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc=
|
||||
filippo.io/hpke v0.4.0 h1:p575VVQ6ted4pL+it6M00V/f2qTZITO0zgmdKCkd5+A=
|
||||
filippo.io/hpke v0.4.0/go.mod h1:EmAN849/P3qdeK+PCMkDpDm83vRHM5cDipBJ8xbQLVY=
|
||||
filippo.io/nistec v0.0.4/go.mod h1:PK/lw8I1gQT4hUML4QGaqljwdDaFcMyFKSXN7kjrtKI=
|
||||
git.sr.ht/~sbinet/gg v0.6.0/go.mod h1:uucygbfC9wVPQIfrmwM2et0imr8L7KQWywX0xpFMm94=
|
||||
github.com/ALTree/bigfloat v0.2.0 h1:AwNzawrpFuw55/YDVlcPw0F0cmmXrmngBHhVrvdXPvM=
|
||||
github.com/ALTree/bigfloat v0.2.0/go.mod h1:+NaH2gLeY6RPBPPQf4aRotPPStg+eXc8f9ZaE4vRfD4=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.21.0/go.mod h1:t76Ruy8AHvUAC8GfMWJMa0ElSbuIcO03NLpynfbgsPA=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/internal v1.12.0/go.mod h1:7dCRMLwisfRH3dBupKeNCioWYUZ4SS09Z14H+7i8ZoY=
|
||||
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.6.4/go.mod h1:8mwH4klAm9DUgR2EEHyEEAQlRDvLPyg5fQry3y+cDew=
|
||||
github.com/ChainSafe/go-schnorrkel v1.1.0 h1:rZ6EU+CZFCjB4sHUE1jIu8VDoB/wRKZxoe1tkcO71Wk=
|
||||
github.com/ChainSafe/go-schnorrkel v1.1.0/go.mod h1:ABkENxiP+cvjFiByMIZ9LYbRoNNLeBLiakC1XeTFxfE=
|
||||
github.com/DataDog/zstd v1.5.7 h1:ybO8RBeh29qrxIhCA9E8gKY6xfONU9T6G6aP9DTKfLE=
|
||||
github.com/DataDog/zstd v1.5.7/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=
|
||||
github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
|
||||
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||
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-20260311194731-d5b7577c683d/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI=
|
||||
github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE=
|
||||
github.com/StephenButtolph/canoto v0.17.3 h1:lvsnYD4b96vD1knnmp1xCmZqfYpY/jSeRozGdOfdvGI=
|
||||
github.com/StephenButtolph/canoto v0.17.3/go.mod h1:IcnAHC6nJUfQFVR9y60ko2ecUqqHHSB6UwI9NnBFZnE=
|
||||
github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794/go.mod h1:7e+I0LQFUI9AXWxOfsQROs9xPhoJtbsyWcjJqDd4KPY=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/ajstarks/svgo v0.0.0-20211024235047-1546f124cd8b/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM=
|
||||
github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=
|
||||
github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs=
|
||||
github.com/andybalholm/brotli v1.2.2 h1:HzTuoo2ErYQqf5qvcJInB8uvqSVxRttzkFexPWtnceM=
|
||||
github.com/andybalholm/brotli v1.2.2/go.mod h1:rzTDkvFWvIrjDXZHkuS16NPggd91W3kUSvPlQ1pLaKY=
|
||||
github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.5 h1:zWFmPmgw4sveAYi1mRqG+E/g0461cJ5M4bJ8/nc6d3Q=
|
||||
@@ -53,6 +73,7 @@ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.18 h1:/A/xDuZAVD2Bp
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.18/go.mod h1:hWe9b4f+djUQGmyiGEeOnZv69dtMSgpDRIvNMvuvzvY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 h1:ZlvrNcHSFFWURB8avufQq9gFsheUgjVD9536obIknfM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21/go.mod h1:cv3TNhVrssKR0O/xxLJVRfd2oazSnZnkUeTf6ctUwfQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.62.5/go.mod h1:TmxGowuBYwjmHFOsEDxaZdsQE62JJzOmtiWafTi/czg=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.2 h1:M1A9AjcFwlxTLuf0Faj88L8Iqw0n/AJHjpZTQzMMsSc=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.96.2/go.mod h1:KsdTV6Q9WKUZm2mNJnUFmIoXfZux91M3sr/a4REX8e0=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3 h1:HwxWTbTrIHm5qY+CAEur0s/figc3qwvLWsNkF4RPToo=
|
||||
@@ -91,6 +112,7 @@ github.com/btcsuite/btcd/chainhash/v2 v2.0.0 h1:PMLlSloHJuEeB80XG9EjpXWNEKAZAMLl
|
||||
github.com/btcsuite/btcd/chainhash/v2 v2.0.0/go.mod h1:mKxcZ7oGTXE7IRV+sS9hP4EVBwc/SzfNR+52IsOP9j8=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
||||
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
|
||||
github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I=
|
||||
@@ -98,15 +120,24 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku
|
||||
github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
|
||||
github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
|
||||
github.com/cavaliergopher/grab/v3 v3.0.1/go.mod h1:1U/KNnD+Ft6JJiYoYBAimKH2XrYptb8Kl3DFGmsjpq4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
|
||||
github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw=
|
||||
github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/chelnak/ysmrr v0.6.0/go.mod h1:56JSrmQgb7/7xoMvuD87h3PE/qW6K1+BQcrgWtVLTUo=
|
||||
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/readline v1.5.1/go.mod h1:Eh+b79XXUwfKfcPLepksvw2tcLE/Ct21YObkaSkeBlk=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
|
||||
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
|
||||
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
|
||||
github.com/cloudflare/cloudflare-go v0.116.0/go.mod h1:Ds6urDwn/TF2uIU24mu7H91xkKP8gSAHxQ44DSZgVmU=
|
||||
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.13.0 h1:BoCcJeiP9hpBJDETkX19qi8Tb8So37srSsp3stTaDMQ=
|
||||
@@ -121,6 +152,9 @@ github.com/cockroachdb/redact v1.1.8 h1:8eVLLj6juKxiKrAEw2b8cJvNqWq++U8WOfQFuL7K
|
||||
github.com/cockroachdb/redact v1.1.8/go.mod h1:GceHHpJ0rMDpYARL5In88Alq/xMBUtVlz7Qxix6ZVkw=
|
||||
github.com/cockroachdb/tokenbucket v0.0.0-20250429170803-42689b6311bb h1:3bCgBvB8PbJVMX1ouCcSIxvsqKPYM7gs72o0zC76n9g=
|
||||
github.com/cockroachdb/tokenbucket v0.0.0-20250429170803-42689b6311bb/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ=
|
||||
github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs=
|
||||
github.com/colega/zeropool v0.0.0-20230505084239-6fb4a4f75381/go.mod h1:OU76gHeRo8xrzGJU3F3I1CqX1ekM8dfJw0+wPeMwnp0=
|
||||
github.com/consensys/bavard v0.2.2-0.20260118153501-cba9f5475432/go.mod h1:k/zVjHHC4B+PQy1Pg7fgvG3ALicQw540Crag8qx+dZs=
|
||||
github.com/consensys/gnark-crypto v0.20.1 h1:PXDUBvk8AzhvWowHLWBEAfUQcV1/aZgWIqD6eMpXmDg=
|
||||
github.com/consensys/gnark-crypto v0.20.1/go.mod h1:RBWrSgy+IDbGR69RRV313th3M/aZU1ubk2om+qHuTSc=
|
||||
github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY=
|
||||
@@ -130,9 +164,11 @@ github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/crate-crypto/go-eth-kzg v1.5.0 h1:FYRiJMJG2iv+2Dy3fi14SVGjcPteZ5HAAUe4YWlJygc=
|
||||
github.com/crate-crypto/go-eth-kzg v1.5.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI=
|
||||
github.com/crate-crypto/go-kzg-4844 v1.1.0/go.mod h1:JolLjpSff1tCCJKaJx4psrlEdlXuJEC996PL3tTAFks=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/cronokirby/saferith v0.33.0 h1:TgoQlfsD4LIwx71+ChfRcIpjkw+RPOapDEVxa+LhwLo=
|
||||
github.com/cronokirby/saferith v0.33.0/go.mod h1:QKJhjoqUtBsXCAVEjw38mFqoi7DebT7kthcD7UzbnoA=
|
||||
github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI=
|
||||
github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -150,22 +186,30 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeC
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 h1:5RVFMOWjMyRy8cARdy79nAmgYw3hK/4HUq48LQ6Wwqo=
|
||||
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40=
|
||||
github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218=
|
||||
github.com/dgraph-io/badger/v4 v4.9.0/go.mod h1:5/MEx97uzdPUHR4KtkNt8asfI2T4JiEiQlV7kWUo8c0=
|
||||
github.com/dgraph-io/ristretto/v2 v2.4.0 h1:I/w09yLjhdcVD2QV192UJcq8dPBaAJb9pOuMyNy0XlU=
|
||||
github.com/dgraph-io/ristretto/v2 v2.4.0/go.mod h1:0KsrXtXvnv0EqnzyowllbVJB8yBonswa2lTCK2gGo9E=
|
||||
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/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0/go.mod h1:56wL82FO0bfMU5RvfXoIwSOP2ggqqxT+tAfNEIyxuHw=
|
||||
github.com/dop251/goja v0.0.0-20260311135729-065cd970411c/go.mod h1:MxLav0peU43GgvwVgNbLAj1s/bSGboKkhuULvq/7hx4=
|
||||
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.11.0 h1:zsrhCuFHAJge/aZIC4N4LdHy5tqYu4tWEaUzIwdYj4Y=
|
||||
github.com/emicklei/dot v1.11.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s=
|
||||
github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
|
||||
github.com/ethereum/c-kzg-4844/v2 v2.1.7 h1:aat3CuITdDbPC6pmEGRT0zJ5eOxzrZj8TJT5z7Xk//M=
|
||||
github.com/ethereum/c-kzg-4844/v2 v2.1.7/go.mod h1:8HMkUZ5JRv4hpw/XUrYWSQNAUzhHMg2UDb/U+5m+XNw=
|
||||
github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk=
|
||||
github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8=
|
||||
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
|
||||
github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
|
||||
github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94=
|
||||
github.com/ferranbt/fastssz v1.0.0 h1:9EXXYsracSqQRBQiHeaVsG/KQeYblPf40hsQPb9Dzk8=
|
||||
github.com/ferranbt/fastssz v1.0.0/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg=
|
||||
github.com/fjl/gencodec v0.1.1/go.mod h1:chDHL3wKXuBgauP8x3XNZkl5EIAR5SoCTmmmDTZRzmw=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
@@ -175,8 +219,11 @@ 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/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ=
|
||||
github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8=
|
||||
github.com/gballet/go-libpcsclite v0.0.0-20250918194357-1ec6f2e601c6/go.mod h1:3IVE7v4II2gS2V5amIH7F7NeYQtbbORtQtjdflgS1vk=
|
||||
github.com/getsentry/sentry-go v0.46.2 h1:1jhYwrKGa3sIpo/y5iDNXS5wDoT7I1KNzMHrnK6ojns=
|
||||
github.com/getsentry/sentry-go v0.46.2/go.mod h1:evVbw2qotNUdYG8KxXbAdjOQWWvWIwKxpjdZZIvcIPw=
|
||||
github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs=
|
||||
github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=
|
||||
github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
|
||||
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
|
||||
@@ -185,8 +232,12 @@ github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01
|
||||
github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=
|
||||
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-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
|
||||
github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU=
|
||||
github.com/go-git/go-git/v5 v5.16.2/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8=
|
||||
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
|
||||
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
|
||||
github.com/go-jose/go-jose/v4 v4.1.4/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||
github.com/go-json-experiment/json v0.0.0-20260601182631-00ed12fed2a6 h1:nxP4pPoyqOAgX8lYDFCfl3DyKeXErCvSvhcyzwGV9CE=
|
||||
github.com/go-json-experiment/json v0.0.0-20260601182631-00ed12fed2a6/go.mod h1:tphK2c80bpPhMOI4v6bIc2xWywPfbqi1Z06+RcrMkDg=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
@@ -197,19 +248,30 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
|
||||
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
|
||||
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
|
||||
github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY=
|
||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-sourcemap/sourcemap v2.1.4+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
|
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro=
|
||||
github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/goccmack/gocc v1.0.2/go.mod h1:LXX2tFVUggS/Zgx/ICPOr3MLyusuM7EcbfkPvNsjdO8=
|
||||
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
|
||||
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/gofrs/flock v0.13.0 h1:95JolYOvGMqeH31+FC7D2+uULf6mG61mEZ/A8dRYMzw=
|
||||
github.com/gofrs/flock v0.13.0/go.mod h1:jxeyy9R1auM5S6JYDBhDt+E2TCo7DkratH4Pgi8P+Z0=
|
||||
github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI=
|
||||
github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
|
||||
github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw=
|
||||
github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U=
|
||||
github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
@@ -221,6 +283,7 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq
|
||||
github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs=
|
||||
github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
@@ -228,12 +291,14 @@ 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.12.19+incompatible h1:haMV2JRRJCe1998HeW/p0X9UaMTK6SDo0ffLn2+DbLs=
|
||||
github.com/google/flatbuffers v25.12.19+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
|
||||
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
||||
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=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/go-querystring v1.2.0/go.mod h1:8IFJqpSRITyJ8QhQ13bmbeMBDfmeEJZD5A0egEOmkqU=
|
||||
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=
|
||||
@@ -252,10 +317,13 @@ github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5T
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||
github.com/grandcat/zeroconf v1.0.0 h1:uHhahLBKqwWBV6WZUDAT71044vwOTL+McW0mBJvo6kE=
|
||||
github.com/grandcat/zeroconf v1.0.0/go.mod h1:lTKmG1zh86XyCoUeIHSA4FJMBwCJiQmGfcP2PdzytEs=
|
||||
github.com/graph-gophers/graphql-go v1.9.0/go.mod h1:23olKZ7duEvHlF/2ELEoSZaY1aNPfShjP782SOoNTyM=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c=
|
||||
github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is=
|
||||
github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
|
||||
github.com/gtank/ristretto255 v0.2.0 h1:LeOuWr6giplWkkMizx2emfG03SRPJqKt1nfIHLVHQ/0=
|
||||
github.com/gtank/ristretto255 v0.2.0/go.mod h1:OJ1ox/dWcp7sJ5grYDcZ+kkHYuj5nelW5aaL7ESVXBw=
|
||||
github.com/guptarohit/asciigraph v0.5.5/go.mod h1:dYl5wwK4gNsnFf9Zp+l06rFiDZ5YtXM6x7SRWZ3KGag=
|
||||
github.com/hanzoai/vfs v0.4.3 h1:QN9SemEQBq9x1l/toi51/TZWctbt3i3mgUJfz5RPALY=
|
||||
github.com/hanzoai/vfs v0.4.3/go.mod h1:wTHfTpJ/165yz0qfPBNFcYRg+tGw8YDwPu+xgps88zU=
|
||||
github.com/hanzos3/go-sdk v1.0.2 h1:EOJQGVnwclkzIyRJyWqtqmA2muyaSsF4y+7KYC4Vhdw=
|
||||
@@ -264,6 +332,7 @@ github.com/hashicorp/go-bexpr v0.1.16 h1:D+fKoGyUzXVS0FdjOX1ws3vIck8DVtBqQ0tsusm
|
||||
github.com/hashicorp/go-bexpr v0.1.16/go.mod h1:HGKbAByHn2aJWUV47gL7+IjLK79iU3EZIbOwCXJZLoE=
|
||||
github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c=
|
||||
github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
|
||||
github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db h1:IZUYC/xb3giYwBLMnr8d0TGTzPKFGNTCGgGLoyeX330=
|
||||
github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db/go.mod h1:xTEYN9KCHxuYHs+NmrmzFcnvHMzLLNiGFafCb1n3Mfg=
|
||||
github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao=
|
||||
@@ -273,21 +342,38 @@ github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXei
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc=
|
||||
github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8=
|
||||
github.com/hydrogen18/memlistener v1.0.0/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/influxdata/influxdb-client-go/v2 v2.14.0/go.mod h1:Ahpm3QXKMJslpXl3IftVLVezreAUtBOTZssDrjZEFHI=
|
||||
github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
|
||||
github.com/influxdata/line-protocol v0.0.0-20210922203350-b1ad95c89adf/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo=
|
||||
github.com/jackpal/gateway v1.1.1 h1:UXXXkJGIHFsStms9ZBgGpoaFEJP7oJtFn5vplIT68E8=
|
||||
github.com/jackpal/gateway v1.1.1/go.mod h1:Tl1vZVtUaXx5j6P5HFmv45alhEi4yHHLfT4PRbB7eyw=
|
||||
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/jacobsa/fuse v0.0.0-20260302145937-f1ba38d60fdf/go.mod h1:fcpw1yk/suvFhB8rT9P+pst+NLboWsBLky9csooKjPc=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jedisct1/go-minisign v0.0.0-20241212093149-d2f9f49435c7/go.mod h1:BMxO138bOokdgt4UaxZiEfypcSHX0t6SIFimVP1oRfk=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=
|
||||
github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung=
|
||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b/go.mod h1:HMcgvsgd0Fjj4XXDkbjdmlbI505rUPBs6WBMYg2pXks=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/k0kubun/go-ansi v0.0.0-20180517002512-3bf9e2903213/go.mod h1:vNUNkEQ1e29fT/6vq2aBdFsgNPmy8qMdSay1npru+Sw=
|
||||
github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig=
|
||||
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/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE=
|
||||
github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk=
|
||||
github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
|
||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
@@ -295,6 +381,7 @@ github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzh
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/klauspost/crc32 v1.3.0 h1:sSmTt3gUt81RP655XGZPElI0PelVTZ6YwCRnPSupoFM=
|
||||
github.com/klauspost/crc32 v1.3.0/go.mod h1:D7kQaZhnkX/Y0tstFGf8VUzv2UofNGqCjnC3zdHB0Hw=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -309,6 +396,7 @@ github.com/luxfi/address v1.1.1 h1:4afWzyBWzTiZN7RenBtdMC9LIvP9L4CSBzSquwKEAgI=
|
||||
github.com/luxfi/address v1.1.1/go.mod h1:KG0jUBcgoJYeieKP5jboCq9UewwDBIOus8ZCqUMVlw8=
|
||||
github.com/luxfi/age v1.6.0 h1:KMD8gSOP4NVCb7NWSlRcgBZNV2xm2a+qQWPyPmiX6f4=
|
||||
github.com/luxfi/age v1.6.0/go.mod h1:7cu9CIyikgyAvr5MlXFapEDQ15yBaHOSdKkK5lG04WE=
|
||||
github.com/luxfi/ai v0.1.0/go.mod h1:lTuY32dGjEJUgVheYuanlt1O0jHj0AZ09sUSpRsmH6M=
|
||||
github.com/luxfi/api v1.1.1 h1:CXD7m0quPmUm+Qw35TrF+E7b0Fq4qz9gHfrZ5gyrjHU=
|
||||
github.com/luxfi/api v1.1.1/go.mod h1:g6J0iohVqaIj2aO1u/ZJPqjiX2tog0NM3/SBf7wJ4cA=
|
||||
github.com/luxfi/atomic v1.0.0 h1:xUV60MuzRvXngaQ1sM0yVC2v4TRoLlUGkkH7M9PS4yw=
|
||||
@@ -325,6 +413,7 @@ github.com/luxfi/compress v0.1.1 h1:cQjRYQFRrw8HinjW1T8FmKgqdRwrFYDCdecc1t0i+uQ=
|
||||
github.com/luxfi/compress v0.1.1/go.mod h1:d4CkRRmwPzafIp57Jxra3RmAmNwNwU8Oc0QBBRlTqGo=
|
||||
github.com/luxfi/concurrent v0.1.1 h1:LkAmNXybOsAm97nFILqMDBp/YLgleuLmyGomFT7YNxU=
|
||||
github.com/luxfi/concurrent v0.1.1/go.mod h1:GlkfiJtPBpatNxvROf7hkPi4gsnmdHGmqhDnVWFrkZE=
|
||||
github.com/luxfi/config v1.1.2/go.mod h1:z6t0a5pGpQz2uDW2qJPLX5fZ/eWbpiNa51gBc63ebFk=
|
||||
github.com/luxfi/consensus v1.36.10 h1:LJPvHc2zL7VFhbqfYu11rA50yvxzTK17Z4mRN04HQhU=
|
||||
github.com/luxfi/consensus v1.36.10/go.mod h1:iwlx11D7BRdEaUqyUvueAe2Fit1K1k26avBK2eLYdnc=
|
||||
github.com/luxfi/consensus v1.36.12 h1:MJKq6j9+04Y2NC+NArGQgv5QNcjprYCk+gppCz1PdSg=
|
||||
@@ -341,14 +430,18 @@ github.com/luxfi/crypto/ipa v1.2.4 h1:6xfwhI9/HrcDkF3Ti5/NxsNQIWbwYDJmRSNIHRQ/xf
|
||||
github.com/luxfi/crypto/ipa v1.2.4/go.mod h1:43J6f6rcfUMrZt4cQectMOZb6Ps+fAEj8ZTPC3Kk+gE=
|
||||
github.com/luxfi/database v1.21.1 h1:GNnoWVa82l+n2dK7x2aG8LR2NEToq6ZCRX0sQjmK0OM=
|
||||
github.com/luxfi/database v1.21.1/go.mod h1:Gc7Z2OPrrcYLnAL8B1trOnguXauOlSDV5tkviLN6Xec=
|
||||
github.com/luxfi/dex v1.14.0/go.mod h1:wYWQmwospvdKBWQ6OJMXb8I+kfgEtE46R1rD8H7vHCQ=
|
||||
github.com/luxfi/dkg v0.3.5 h1:s2L2mMQaz+n9m0b0ghvoV5VZNxiwb2z4WrGugvK0udY=
|
||||
github.com/luxfi/dkg v0.3.5/go.mod h1:M+WH7GFRN+YUD851Rlnumdp0Md98kplNN8pVx65U8I8=
|
||||
github.com/luxfi/evm v1.104.10/go.mod h1:4xBXSPz0d6cRa+XSN65zL5yeJDuASlgCjg8qt86EZLM=
|
||||
github.com/luxfi/fhe v1.11.1/go.mod h1:QeNytuStXaY+HWvUN4+ULZBRMzvnrzjA/AV6FWksBro=
|
||||
github.com/luxfi/filesystem v0.0.1 h1:VZ6xMFKaAPBW/ddlMsDnI2G0VU1lV5rYaVcW5d+KwEY=
|
||||
github.com/luxfi/filesystem v0.0.1/go.mod h1:OQVSU6XNwqrr1AI+MqkID2taHUclx7NYmmr3svgttec=
|
||||
github.com/luxfi/formatting v1.1.1 h1:MJhVXIPh1dbysvYEjtaEA/Z0FUTiI7n0DwOF54FS08c=
|
||||
github.com/luxfi/formatting v1.1.1/go.mod h1:zhBWp6fLZduhpiAdPgVDdPVOyhw4FvwRUksF6+xKQCE=
|
||||
github.com/luxfi/genesis v1.16.4 h1:8ZtqvgPnICgGpjBzAjYAPrI3qwr1g1DPbum+hgjc4bg=
|
||||
github.com/luxfi/genesis v1.16.4/go.mod h1:0F6hV6GfwDSmIWsueB7/vqPZFxyS7A4Jo3p1QU87fFc=
|
||||
github.com/luxfi/genesis/builder v0.1.0/go.mod h1:p0vgZzt/aOTSlpw7VSvhh4Wfdp99FErW37CDlCAp88o=
|
||||
github.com/luxfi/genesis/pkg/genesis/security v1.13.8 h1:9ier0p55ErSpoXHRJpZ04WV5HwwMB1uDrU7PHGBKG2U=
|
||||
github.com/luxfi/genesis/pkg/genesis/security v1.13.8/go.mod h1:DzU+GYUFv12ja4Vc46bWKNBBmNYbcow3u/DASx4wpfI=
|
||||
github.com/luxfi/geth v1.20.1 h1:QUGQr4AKvADjwMi7t8a0OfoyxShgEcI9pwie1jFYfm0=
|
||||
@@ -357,6 +450,8 @@ github.com/luxfi/go-bip32 v1.1.0 h1:zjy19WKa1KJnGamRNyOZM3l/MPtV/sax7M4NMPwLHZQ=
|
||||
github.com/luxfi/go-bip32 v1.1.0/go.mod h1:QyDXlzWL3xRiCbMUi4Z3J52Q/SMoCvdRLXXlYvSZor8=
|
||||
github.com/luxfi/go-bip39 v1.2.0 h1:fx3pFuSGawCG4In6pA4OLLStqbgIqD1j8EygFskoHzY=
|
||||
github.com/luxfi/go-bip39 v1.2.0/go.mod h1:if+2OVbG4k4jKIuBt/Rse1KV1kgWQM5j5xFbUtwbNtc=
|
||||
github.com/luxfi/gpu v1.0.1/go.mod h1:8r1ReBPsLx1zmcA3GksKD4J7azP52FSTU/LpT9TyYHE=
|
||||
github.com/luxfi/hid v0.9.3/go.mod h1:XJ/7DZAHf5dggm3zWNbitKuFGB7J96b4iX+8NO3BsnY=
|
||||
github.com/luxfi/ids v1.3.2 h1:c6Rft5kZB4XqiCtWaGH47bfhaNFm3FGRfhEzI01GVeI=
|
||||
github.com/luxfi/ids v1.3.2/go.mod h1:+5l8cYMbKpORJbQ2r98CYJo9TQATgUdnmzpYFZWMwwc=
|
||||
github.com/luxfi/keychain v1.1.1 h1:dTYEPy6CGVC1sogMci4iJogUvW6VdTmemplQdzRqnAs=
|
||||
@@ -367,12 +462,14 @@ github.com/luxfi/kms v1.12.10 h1:fXgisnBkixFSrqhOFbZVRQkf8cX4q4vS3Gix1qjL3PQ=
|
||||
github.com/luxfi/kms v1.12.10/go.mod h1:CCcWDXIlDT2TwfYAUxedLyzShFRJAlVlp15zQ2L3CrU=
|
||||
github.com/luxfi/lattice/v7 v7.1.4 h1:hQR02M6cHTAV5+joOPi9gb9Gm+z/hKJnhJF4IlciIJs=
|
||||
github.com/luxfi/lattice/v7 v7.1.4/go.mod h1:DmIQFi3mJiehVsR235l1NKYEU0JhU649OX5p7gMEW2c=
|
||||
github.com/luxfi/ledger v1.2.1/go.mod h1:sthw0IUSsdO/eKvzAQBZsEZEVn8jDE7vDo95NYmlLJs=
|
||||
github.com/luxfi/lens v0.2.1 h1:5Qd0GdjbM+XUVgwDbZ452tKkR7yeE8QnBTHHaH8fJNY=
|
||||
github.com/luxfi/lens v0.2.1/go.mod h1:6FIhC8weEE5RbNMF3SaE+XPSB9cr6FmjypYBoHkz4JQ=
|
||||
github.com/luxfi/light v1.0.0 h1:zTJgp5M0xX8rIwRjYDQgOGhLas3rgXyhkszrTX+ne3s=
|
||||
github.com/luxfi/light v1.0.0/go.mod h1:1G0kgjEe/srlBMCIrFq4IvhnrMuHKFG18CRUWfw1z30=
|
||||
github.com/luxfi/log v1.4.3 h1:xkUKRWvQ4ZwvlUC2e0/RTtHYZOYSMvSQ9W9lbjwBmiI=
|
||||
github.com/luxfi/log v1.4.3/go.mod h1:myIkufyiQomSQH34K981kbz6cG4WUoerRUh7F4XhlQI=
|
||||
github.com/luxfi/lpm v1.10.1/go.mod h1:cy3dgb91fAgn1WXqyt8IJol3mlEKwCzQ2yOlaO2ykMo=
|
||||
github.com/luxfi/magnetar v1.2.3 h1:n4UrJZLK+mhDDZr1HLl2H/KgA6o6v62r5oiC61R7awE=
|
||||
github.com/luxfi/magnetar v1.2.3/go.mod h1:z9PLkqzzYiaFGT/qFBQSnNoHmZrg8y7JlYGiNnHAAdk=
|
||||
github.com/luxfi/math v1.5.1 h1:FDOY75e4vn/Xra1ij99xOS/9XdxQGCPP6HONHRkCwfg=
|
||||
@@ -391,8 +488,12 @@ github.com/luxfi/mock v0.1.1 h1:0HEtIjg1J6CWz+IUyP6rsGqNWTcmxjFnSQIhaDuARwY=
|
||||
github.com/luxfi/mock v0.1.1/go.mod h1:jo35akl3Vtd8LbzDts8VJ0jmSVycrd1/eBi6g6t5hKU=
|
||||
github.com/luxfi/net v0.1.1 h1:jIQCb8ulBGEvHIcorzDDNCeWzutFzLVtRWodutrQE24=
|
||||
github.com/luxfi/net v0.1.1/go.mod h1:SwxbUQ538u4QAcgC/N61uahDk1TDHL6Ku89CX/WV2lk=
|
||||
github.com/luxfi/netrunner v1.20.1/go.mod h1:B3xcQObhRofrZP0KLswL4szwiQG40USCZ5uGeH+mnWs=
|
||||
github.com/luxfi/oracle v1.1.1/go.mod h1:ST/4cVIUBa08GnkI9vQbfg8GGt0oDCXfTnEkx0WsnPs=
|
||||
github.com/luxfi/ordering v0.0.1/go.mod h1:Ld5UAayScKxicsd9BYuQ/D7vzEUndOC7cGCT+fj++jM=
|
||||
github.com/luxfi/p2p v1.22.1 h1:M59Iy+FIJta99aFfTpG6EE70jm9uqIX+iHrGBYPHDhg=
|
||||
github.com/luxfi/p2p v1.22.1/go.mod h1:FHOSavVcq8JS1ZQtfddd9Jj1gaPstz1cjvNgczAQRyg=
|
||||
github.com/luxfi/password v0.0.1/go.mod h1:xKhi28+V3xqPc4+kIZHRp7oZ1W7nUKze6EauvMVq19s=
|
||||
github.com/luxfi/pq v1.1.0 h1:ADplfUSyirLymSxs3Ix0HeDTyl5oswCNUpXJt/5vLY8=
|
||||
github.com/luxfi/pq v1.1.0/go.mod h1:KT5rG9ztpzIkT9QSnXK4WFqBBLzKCLjY7l1c/unBi8I=
|
||||
github.com/luxfi/precompile v0.19.3 h1:ljJholS+9mlR8EjbfM96BLYvIni7xCt7KkX06YzAIJU=
|
||||
@@ -401,8 +502,10 @@ github.com/luxfi/proto v1.4.2 h1:dEGTE7xOWVPTXRZNDBJfwh2Q19vE7MQBhyXXmWenw+8=
|
||||
github.com/luxfi/proto v1.4.2/go.mod h1:vwVkrC9ghhuCL8bluA59+G5jaD6WuqiDyd1iKh7yzOE=
|
||||
github.com/luxfi/protocol v0.0.2 h1:TAuXMm1K4VDpG3B3brq1EE9Lb7XlbhQmVBObskgNhmc=
|
||||
github.com/luxfi/protocol v0.0.2/go.mod h1:Yjn2VRwn5PXim0+JTalAyrVG6YbmuSnYOfeUXSbAsqA=
|
||||
github.com/luxfi/pubsub v1.0.0/go.mod h1:lCVBPBK/fhD0Ffg57E9R44CEI6Bo1fqb9ISJrBlj4ug=
|
||||
github.com/luxfi/pulsar v1.9.2 h1:pFLoAfBlCwFZfchqHn78J6yMe29AhaoKGRa/KTUP8CE=
|
||||
github.com/luxfi/pulsar v1.9.2/go.mod h1:uTOtribcUvTTwAOy0Ztg0S2AUiNAsVqFfopTrKW+zjM=
|
||||
github.com/luxfi/relay v1.1.1/go.mod h1:jdgwxl8G0iykzyqW43uazRPsdz49awgv24kev3cMiQI=
|
||||
github.com/luxfi/resource v0.1.1 h1:k11s5xLGX85UWq/iLZyWLhnqeLTlp3FHEt8u/8AHdkY=
|
||||
github.com/luxfi/resource v0.1.1/go.mod h1:s7SbZOSVbgj9bWFOcLCcXgnMlHxbqtqhAeJ3f0Xuy/Y=
|
||||
github.com/luxfi/rpc v1.1.0 h1:B/PJbK399th1mHRDSufhCpVbAciZqId3LsaWhIGNWH4=
|
||||
@@ -413,6 +516,7 @@ github.com/luxfi/sampler v1.1.0 h1:u3iRDl7V06ARh0e85h3HT+aZ1saCFo2yMMsh+dCJbqk=
|
||||
github.com/luxfi/sampler v1.1.0/go.mod h1:kJa53S3tC9+VSbuV3RFu68MmbCCBlr2UM39LOClQ/Hs=
|
||||
github.com/luxfi/sdk v1.18.1 h1:KnqkL6bNATtQXHbnTMsue5pLz9tn74YFAoux2ek+k90=
|
||||
github.com/luxfi/sdk v1.18.1/go.mod h1:8BE1iF2ewkDbsV31TPE0/HT7RGJILR1ZALbKE1GgHMc=
|
||||
github.com/luxfi/sdk/api v0.0.2/go.mod h1:p0fv13IlUKFTx16y//rtpp6D/qBZa8xX9gYkKp6j/9g=
|
||||
github.com/luxfi/staking v1.6.1 h1:be023mY88AnFgF9P+MMvILX21I2CaqVAVkGcc+a20so=
|
||||
github.com/luxfi/staking v1.6.1/go.mod h1:X8i/uCLc009mlIUnFMErrQMCwfGaOVCAVf+GbDN5nn4=
|
||||
github.com/luxfi/sys v0.1.0 h1:M7RYOt8W4Wws7cxxsyOHe50UKMYTzIu7HYknqW4xt0Y=
|
||||
@@ -451,12 +555,17 @@ github.com/luxfi/zapdb v1.10.1 h1:XV3k4UTTKKxUMgbfC7woPXgUEIJd3P5nj2lGTQ88xeE=
|
||||
github.com/luxfi/zapdb v1.10.1/go.mod h1:3Y0hH2A9kvjR+Bp9N2yEbtHnhXGHhqCQOLvBRkHrrM0=
|
||||
github.com/luxfi/zwing v0.6.1 h1:Ve7RvYVBXx4JWe8TZhLfpez1N1G685hl/PSMDsR4RI4=
|
||||
github.com/luxfi/zwing v0.6.1/go.mod h1:Eal4hnjmdFXc6rxciA6cxeCfV1BKs8le03v83W5oiKg=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg=
|
||||
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
|
||||
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
|
||||
github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY=
|
||||
github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
|
||||
github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
|
||||
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
|
||||
github.com/mattn/go-runewidth v0.0.21/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/melbahja/goph v1.4.0/go.mod h1:uG+VfK2Dlhk+O32zFrRlc3kYKTlV6+BtvPWd/kK7U68=
|
||||
github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=
|
||||
github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A=
|
||||
github.com/miekg/dns v1.1.27/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM=
|
||||
@@ -469,23 +578,36 @@ github.com/minio/crc64nvme v1.1.1 h1:8dwx/Pz49suywbO+auHCBpCtlW1OfpcLN7wYgVR6wAI
|
||||
github.com/minio/crc64nvme v1.1.1/go.mod h1:eVfm2fAzLlxMdUGc0EEBGSMmPwmXD5XiNRpnu9J3bvg=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
github.com/minio/minio-go/v7 v7.0.100/go.mod h1:EtGNKtlX20iL2yaYnxEigaIvj0G0GwSDnifnG8ClIdw=
|
||||
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/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw=
|
||||
github.com/mitchellh/pointerstructure v1.2.1/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4=
|
||||
github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/montanaflynn/stats v0.9.0 h1:tsBJ0RXwph9BmAuFoCmqGv6e8xa0MENQ8m0ptKq29mQ=
|
||||
github.com/montanaflynn/stats v0.9.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
|
||||
github.com/mr-tron/base58 v1.3.0 h1:K6Y13R2h+dku0wOqKtecgRnBUBPrZzLZy5aIj8lCcJI=
|
||||
github.com/mr-tron/base58 v1.3.0/go.mod h1:2BuubE67DCSWwVfx37JWNG8emOC0sHEU4/HpcYgCLX8=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||
github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0=
|
||||
github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E=
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA=
|
||||
github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8=
|
||||
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
|
||||
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.3.1/go.mod h1:kOdeacKy7t40Rclb1je37ZLFboFxh+YLy0zaPCMibPY=
|
||||
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
|
||||
github.com/olekukonko/ll v0.0.9/go.mod h1:En+sEW0JNETl26+K8eZ6/W4UQ7CYSrrgg/EdIYT2H8g=
|
||||
github.com/olekukonko/tablewriter v1.0.9/go.mod h1:5c+EBPeSqvXnLLgkm9isDdzR3wjfBkHR9Nhfp3NWrzo=
|
||||
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=
|
||||
@@ -506,6 +628,7 @@ github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28=
|
||||
github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg=
|
||||
github.com/pelletier/go-toml/v2 v2.3.0 h1:k59bC/lIZREW0/iVaQR8nDHxVq8OVlIzYCOJf421CaM=
|
||||
github.com/pelletier/go-toml/v2 v2.3.0/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI=
|
||||
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
|
||||
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
|
||||
github.com/pingcap/errors v0.11.5-0.20210425183316-da1aaba5fb63 h1:+FZIDR/D97YOPik4N4lPDaUcLDF/EQPogxtlHB2ZZRM=
|
||||
@@ -522,13 +645,16 @@ github.com/pion/transport/v3 v3.1.1 h1:Tr684+fnnKlhPceU+ICdrw6KKkTms+5qHMgw6bIkY
|
||||
github.com/pion/transport/v3 v3.1.1/go.mod h1:+c2eewC5WJQHiAA46fkMMzoYZSuGzA/7E2FPrOYHctQ=
|
||||
github.com/pires/go-proxyproto v0.11.0 h1:gUQpS85X/VJMdUsYyEgyn59uLJvGqPhJV5YvG68wXH4=
|
||||
github.com/pires/go-proxyproto v0.11.0/go.mod h1:ZKAAyp3cgy5Y5Mo4n9AlScrkCZwUy0g3Jf+slqQVcuU=
|
||||
github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.5/go.mod h1:wHDZ0IZX6JcBYRK1TH9bcVq8G7TLpVHYIGJRFnmPfxg=
|
||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posthog/posthog-go v1.8.2/go.mod h1:ueZiJCmHezyDHI/swIR1RmOfktLehnahJnFxEvQ9mnQ=
|
||||
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
|
||||
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
@@ -537,8 +663,13 @@ github.com/prometheus/common v0.68.0 h1:8rQJvQmYltsR2L7h8Zw0Iyj8WYNNmpwikoQTZXwf
|
||||
github.com/prometheus/common v0.68.0/go.mod h1:4soH+U8yJSROk7OJ//hmTiWKsxapv6zRGgTt3keN8gQ=
|
||||
github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
|
||||
github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
|
||||
github.com/protolambda/bls12-381-util v0.1.0/go.mod h1:cdkysJTRpeFeuUVx/TXGDQNMTiRAalk1vQw3TYTHcE4=
|
||||
github.com/protolambda/zrnt v0.34.1/go.mod h1:A0fezkp9Tt3GBLATSPIbuY4ywYESyAuc/FFmPKg8Lqs=
|
||||
github.com/protolambda/ztyp v0.2.2/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU=
|
||||
github.com/quic-go/quic-go v0.59.1 h1:0Gmua0HW1Tv7ANR7hUYwRyD0MG5OJfgvYSZasGZzBic=
|
||||
github.com/quic-go/quic-go v0.59.1/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rogpeppe/go-internal v1.15.0 h1:D0RCU5rMAp+SpgkiNdrjfJ+LX4J1M32V2NeCY7EJ6hc=
|
||||
github.com/rogpeppe/go-internal v1.15.0/go.mod h1:DrUVZyrJU+txYW5/1kwtXQSMFio52ZOxX7yM1VHvnxs=
|
||||
@@ -552,8 +683,15 @@ github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88ee
|
||||
github.com/sagikazarmark/locafero v0.12.0/go.mod h1:sZh36u/YSZ918v0Io+U9ogLYQJ9tLLBmM4eneO6WwsI=
|
||||
github.com/sanity-io/litter v1.5.5 h1:iE+sBxPBzoK6uaEP5Lt3fHNgpKcHXc/A2HGETy0uJQo=
|
||||
github.com/sanity-io/litter v1.5.5/go.mod h1:9gzJgR2i4ZpjZHsKvUXIRQVk7P+yM3e+jAF7bU2UI5U=
|
||||
github.com/schollz/progressbar/v3 v3.18.0/go.mod h1:IsO3lpbaGuzh8zIMzgY3+J8l4C8GjO0Y9S69eFvNsec=
|
||||
github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
|
||||
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
|
||||
github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
@@ -565,6 +703,7 @@ github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
github.com/status-im/keycard-go v0.3.3/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
@@ -613,13 +752,20 @@ 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/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
|
||||
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
|
||||
github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
|
||||
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
|
||||
github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU=
|
||||
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/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU=
|
||||
github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E=
|
||||
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
|
||||
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/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
|
||||
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
|
||||
github.com/zap-proto/go v1.1.0 h1:DDGhuTBNqkmNax7QV/VvkInJR7hiOcybwUjN3YBt8fg=
|
||||
@@ -636,8 +782,12 @@ go.mongodb.org/mongo-driver v1.17.9 h1:IexDdCuuNJ3BHrELgBlyaH9p60JXAvdzWR128q+U5
|
||||
go.mongodb.org/mongo-driver v1.17.9/go.mod h1:LlOhpH5NUEfhxcAwG0UEkMqwYcc4JU18gtCdGudk/tQ=
|
||||
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/contrib/zpages v0.62.0/go.mod h1:C8kXoiC1Ytvereztus2R+kqdSa6W/MZ8FfS8Zwj+LiM=
|
||||
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
|
||||
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0/go.mod h1:Vl1/iaggsuRlrHf/hfPJPvVag77kKyvrLeD10kpMl+A=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.42.0/go.mod h1:2qXPNBX1OVRC0IwOnfo1ljoid+RD0QK3443EaqVlsOU=
|
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0/go.mod h1:/G+nUPfhq2e+qiXMGxMwumDrP5jtzU+mWN7/sjT2rak=
|
||||
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
|
||||
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
|
||||
go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg=
|
||||
@@ -646,8 +796,10 @@ go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfC
|
||||
go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A=
|
||||
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
|
||||
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
|
||||
go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
|
||||
@@ -668,6 +820,7 @@ golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
|
||||
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
|
||||
golang.org/x/exp v0.0.0-20260529124908-c761662dc8c9 h1:4d4PbuBNwaxMXkXI8yiIYjydtMU+04RHeuSxJdgKftM=
|
||||
golang.org/x/exp v0.0.0-20260529124908-c761662dc8c9/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw=
|
||||
golang.org/x/image v0.25.0/go.mod h1:tCAmOEGthTtkalusGp1g3xa2gke8J6c2N565dTyl9Rs=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
@@ -690,6 +843,8 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su
|
||||
golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
|
||||
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
|
||||
golang.org/x/oauth2 v0.36.0/go.mod h1:YDBUJMTkDnJS+A4BP4eZBjCqtokkg1hODuPjwiGPO7Q=
|
||||
golang.org/x/perf v0.0.0-20230113213139-801c7ef9e5c5/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -721,8 +876,10 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
||||
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/telemetry v0.0.0-20260625142307-59b4966ccb57/go.mod h1:3AWMyWHS+caVoiEXpiq6+tzKA40J4vQT3MYr80ZtQpc=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@@ -741,6 +898,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
|
||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q=
|
||||
golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA=
|
||||
golang.org/x/tools/go/expect v0.1.1-deprecated/go.mod h1:eihoPOH+FgIqa3FpoTwguz/bVUSGBlGQU67vpBeOrBY=
|
||||
golang.org/x/tools/go/packages/packagestest v0.1.1-deprecated/go.mod h1:RVAQXBGNv1ib0J382/DPCRS/BPnsGebyM1Gj5VSDpG8=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -748,6 +907,10 @@ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
|
||||
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
|
||||
gonum.org/v1/plot v0.15.2/go.mod h1:DX+x+DWso3LTha+AdkJEv5Txvi+Tql3KAGkehP0/Ubg=
|
||||
gonum.org/v1/tools v0.0.0-20200318103217-c168b003ce8c/go.mod h1:fy6Otjqbk477ELp8IXTpw1cObQtLbRCBVonY+bTTfcM=
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1/go.mod h1:nKE/iIaLqn2bQwXBg8f1g2Ylh6r5MN5CmZvuzZCgsCU=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
|
||||
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
|
||||
@@ -765,11 +928,15 @@ google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
@@ -779,3 +946,19 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.34.0/go.mod h1:YzgkIzOOlhl9uwWCZNqpw6RJy9L2FK4dlJeayUoydug=
|
||||
k8s.io/apimachinery v0.34.0/go.mod h1:/GwIlEcWuTX9zKIg2mbw0LRFIsXwrfoVxn+ef0X13lw=
|
||||
k8s.io/client-go v0.34.0/go.mod h1:ozgMnEKXkRjeMvBZdV1AijMHLTh3pbACPvK7zFR+QQY=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20250710124328-f3f2b991d03b/go.mod h1:UZ2yyWbFTpuhSbFhv24aGNOdoRdJZgsIObGBUaYVsts=
|
||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
modernc.org/libc v1.72.0/go.mod h1:tTU8DL8A+XLVkEY3x5E/tO7s2Q/q42EtnNWda/L5QhQ=
|
||||
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
|
||||
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
|
||||
modernc.org/sqlite v1.50.0/go.mod h1:m0w8xhwYUVY3H6pSDwc3gkJ/irZT/0YEXwBlhaxQEew=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||
|
||||
@@ -116,6 +116,7 @@ func (b *Block) Options(context.Context) ([2]chain.Block, error) {
|
||||
options := options{
|
||||
log: b.manager.Log,
|
||||
primaryUptimePercentage: b.manager.txExecutorBackend.Config.UptimePercentage,
|
||||
stakingPolicyAt: b.manager.txExecutorBackend.Config.StakingPolicyAt,
|
||||
uptimes: b.manager.txExecutorBackend.Uptimes,
|
||||
state: b.manager.backend.state,
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"github.com/luxfi/log"
|
||||
"github.com/luxfi/node/vms/platformvm/block"
|
||||
"github.com/luxfi/node/vms/platformvm/reward"
|
||||
"github.com/luxfi/node/vms/platformvm/stakingparams"
|
||||
"github.com/luxfi/node/vms/platformvm/state"
|
||||
"github.com/luxfi/node/vms/platformvm/txs"
|
||||
txexecutor "github.com/luxfi/node/vms/platformvm/txs/executor"
|
||||
@@ -34,8 +35,13 @@ type options struct {
|
||||
// inputs populated before calling this struct's methods:
|
||||
log log.Logger
|
||||
primaryUptimePercentage float64
|
||||
uptimes uptime.Calculator
|
||||
state state.Chain
|
||||
// stakingPolicyAt resolves the governed primary-network policy binding a
|
||||
// staker that bonded at a given unix time. Nil falls back to
|
||||
// primaryUptimePercentage, so an ungoverned node is byte-for-byte
|
||||
// unchanged.
|
||||
stakingPolicyAt func(int64) stakingparams.Params
|
||||
uptimes uptime.Calculator
|
||||
state state.Chain
|
||||
|
||||
// outputs populated by this struct's methods:
|
||||
preferredBlock block.Block
|
||||
@@ -125,7 +131,18 @@ func (o *options) prefersCommit(tx *txs.Tx) (bool, error) {
|
||||
}
|
||||
|
||||
netID := staker.ChainID()
|
||||
// Judge the validator on the uptime rule that was in force when it BONDED,
|
||||
// not the one in force now. Passing StartTime rather than the current chain
|
||||
// time is what stops a governed uptime requirement from being retroactive —
|
||||
// otherwise a stake majority could raise the bar the day before a rival's
|
||||
// stake matures and take its reward. With no governed history this is the
|
||||
// compiled-in --uptime-requirement, unchanged.
|
||||
expectedUptimePercentage := o.primaryUptimePercentage
|
||||
if o.stakingPolicyAt != nil {
|
||||
expectedUptimePercentage = float64(
|
||||
o.stakingPolicyAt(primaryNetworkValidator.StartTime.Unix()).UptimeRequirement,
|
||||
) / reward.PercentDenominator
|
||||
}
|
||||
if netID != constants.PrimaryNetworkID {
|
||||
transformNet, err := txexecutor.GetTransformChainTx(o.state, netID)
|
||||
if err != nil {
|
||||
|
||||
@@ -7,17 +7,18 @@ import (
|
||||
"time"
|
||||
|
||||
consensusconfig "github.com/luxfi/consensus/config"
|
||||
validators "github.com/luxfi/validators"
|
||||
"github.com/luxfi/validators/uptime"
|
||||
"github.com/luxfi/ids"
|
||||
"github.com/luxfi/math/set"
|
||||
"github.com/luxfi/node/chains"
|
||||
"github.com/luxfi/node/upgrade"
|
||||
"github.com/luxfi/node/vms/components/gas"
|
||||
"github.com/luxfi/node/vms/platformvm/reward"
|
||||
"github.com/luxfi/node/vms/platformvm/stakingparams"
|
||||
"github.com/luxfi/node/vms/platformvm/txs"
|
||||
"github.com/luxfi/node/vms/platformvm/validators/fee"
|
||||
"github.com/luxfi/node/vms/txs/auth"
|
||||
validators "github.com/luxfi/validators"
|
||||
"github.com/luxfi/validators/uptime"
|
||||
)
|
||||
|
||||
// Internal contains all of the parameters for the PlatformVM that are
|
||||
@@ -103,6 +104,46 @@ type Internal struct {
|
||||
// registry refuses everything classical) and for legacy networks
|
||||
// (the mempool gate is bypassed entirely).
|
||||
ClassicalCompatRegistry auth.ClassicalCompatRegistry
|
||||
|
||||
// StakingParams is the governed primary-network staking policy, as an
|
||||
// append-only history of activations. Empty means ungoverned: the
|
||||
// compiled-in fields above are used verbatim, which is exactly today's
|
||||
// behaviour — so a node that carries no history behaves identically to one
|
||||
// built before this field existed.
|
||||
//
|
||||
// This is the seam. Every primary-network staking rule is read through
|
||||
// StakingPolicyAt, so replacing the source of this history (config today,
|
||||
// P-Chain state once the proposal tx lands) changes nothing else.
|
||||
StakingParams stakingparams.History
|
||||
}
|
||||
|
||||
// StakingPolicyAt returns the primary-network staking policy that binds a party
|
||||
// which committed at unix time t.
|
||||
//
|
||||
// The time argument is the whole non-retroactivity guarantee, and callers must
|
||||
// pass the moment the party bound itself, not the moment of the check:
|
||||
//
|
||||
// - Admission (getValidatorRules, getDelegatorRules) passes the current chain
|
||||
// time, because a joiner is choosing to accept the rules in force now.
|
||||
// - The reward gate (block/executor prefersCommit) passes the staker's
|
||||
// StartTime, because a validator that bonded under an 80% uptime rule must
|
||||
// be judged at 80% however stake votes afterwards.
|
||||
//
|
||||
// Getting that second call wrong would make the uptime requirement retroactive
|
||||
// and hand a stake majority the power to raise the bar the day before a rival's
|
||||
// stake matures and take its reward.
|
||||
func (c *Internal) StakingPolicyAt(t int64) stakingparams.Params {
|
||||
if len(c.StakingParams) == 0 {
|
||||
return stakingparams.Params{
|
||||
MinValidatorStake: c.MinValidatorStake,
|
||||
MaxValidatorStake: c.MaxValidatorStake,
|
||||
MinStakeDuration: uint32(c.MinStakeDuration / time.Second),
|
||||
MaxStakeDuration: uint32(c.MaxStakeDuration / time.Second),
|
||||
MinDelegationFee: c.MinDelegationFee,
|
||||
UptimeRequirement: uint32(c.UptimePercentage * reward.PercentDenominator),
|
||||
}
|
||||
}
|
||||
return c.StakingParams.At(t)
|
||||
}
|
||||
|
||||
// Create the blockchain described in [tx], but only if this node is a member of
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/luxfi/node/vms/platformvm/stakingparams"
|
||||
)
|
||||
|
||||
// mainnetInternal is the compiled-in policy a mainnet node runs today.
|
||||
func mainnetInternal() *Internal {
|
||||
return &Internal{
|
||||
MinValidatorStake: 2_000 * stakingparams.Lux,
|
||||
MaxValidatorStake: 5 * stakingparams.GigaLux,
|
||||
MinDelegationFee: 20_000,
|
||||
UptimePercentage: 0.8,
|
||||
MinStakeDuration: 2 * 7 * 24 * time.Hour,
|
||||
MaxStakeDuration: 365 * 24 * time.Hour,
|
||||
}
|
||||
}
|
||||
|
||||
// TestUngovernedNodeIsUnchanged is the adoption safety property. A node with no
|
||||
// staking history must resolve exactly the constants it was built with, so
|
||||
// shipping this seam changes nothing on any live network until stake votes.
|
||||
func TestUngovernedNodeIsUnchanged(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
c := mainnetInternal()
|
||||
require.Empty(c.StakingParams)
|
||||
|
||||
got := c.StakingPolicyAt(time.Now().Unix())
|
||||
require.Equal(stakingparams.MainnetGenesis, got,
|
||||
"an ungoverned node must resolve today's compiled-in mainnet policy verbatim")
|
||||
|
||||
// And the answer must not depend on the instant asked about.
|
||||
require.Equal(got, c.StakingPolicyAt(0))
|
||||
require.Equal(got, c.StakingPolicyAt(1<<40))
|
||||
}
|
||||
|
||||
// TestGovernedPolicyBindsOnlyTheFuture drives the real seam function through
|
||||
// the exact scenario the reward gate faces: a validator that bonded under the
|
||||
// old rule, and a vote that lands afterwards.
|
||||
func TestGovernedPolicyBindsOnlyTheFuture(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
const (
|
||||
bondedAt = int64(1_765_573_611) // real mainnet validator StartTime
|
||||
votedAt = int64(1_785_000_000)
|
||||
)
|
||||
|
||||
tightened := stakingparams.MainnetGenesis
|
||||
tightened.UptimeRequirement = 880_000 // 88%
|
||||
|
||||
c := mainnetInternal()
|
||||
c.StakingParams = stakingparams.History{
|
||||
{Activation: 0, Params: stakingparams.MainnetGenesis},
|
||||
{Activation: votedAt, Params: tightened},
|
||||
}
|
||||
require.NoError(c.StakingParams.Valid())
|
||||
|
||||
// This is the call block/executor prefersCommit makes, with the staker's
|
||||
// bond time. The already-bonded validator keeps its 80% bar.
|
||||
require.Equal(uint32(800_000), c.StakingPolicyAt(bondedAt).UptimeRequirement)
|
||||
|
||||
// A validator bonding after the vote gets the new bar.
|
||||
require.Equal(uint32(880_000), c.StakingPolicyAt(votedAt+1).UptimeRequirement)
|
||||
}
|
||||
|
||||
// TestGovernedAdmissionThresholdsAreLive proves the other seam: a vote that
|
||||
// opens the network up is visible to admission immediately.
|
||||
func TestGovernedAdmissionThresholdsAreLive(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
const openedAt = int64(1_785_000_000)
|
||||
|
||||
opened := stakingparams.MainnetGenesis
|
||||
opened.MinValidatorStake = 100 * stakingparams.Lux // 2000 LUX -> 100 LUX
|
||||
|
||||
// The proposal must itself be admissible under the constitution.
|
||||
require.NoError(stakingparams.Accept(
|
||||
stakingparams.MainnetGenesis, opened,
|
||||
stakingparams.MainnetBounds, stakingparams.MainnetRate,
|
||||
stakingparams.MainnetRate.MinInterval,
|
||||
))
|
||||
|
||||
c := mainnetInternal()
|
||||
c.StakingParams = stakingparams.History{
|
||||
{Activation: 0, Params: stakingparams.MainnetGenesis},
|
||||
{Activation: openedAt, Params: opened},
|
||||
}
|
||||
|
||||
// getValidatorRules resolves at the CURRENT chain time.
|
||||
require.Equal(2_000*stakingparams.Lux, c.StakingPolicyAt(openedAt-1).MinValidatorStake)
|
||||
require.Equal(100*stakingparams.Lux, c.StakingPolicyAt(openedAt).MinValidatorStake)
|
||||
}
|
||||
|
||||
// TestDurationRoundTripDoesNotTruncate guards the one lossy conversion in the
|
||||
// seam: config carries time.Duration, the governed value carries seconds.
|
||||
func TestDurationRoundTripDoesNotTruncate(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
c := mainnetInternal()
|
||||
p := c.StakingPolicyAt(0)
|
||||
|
||||
require.Equal(uint32(14*24*60*60), p.MinStakeDuration)
|
||||
require.Equal(uint32(365*24*60*60), p.MaxStakeDuration)
|
||||
require.Equal(c.MinStakeDuration, time.Duration(p.MinStakeDuration)*time.Second)
|
||||
require.Equal(c.MaxStakeDuration, time.Duration(p.MaxStakeDuration)*time.Second)
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package reward
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// Measured mainnet (96369) state.
|
||||
//
|
||||
// platform.getCurrentSupply -> 13272095200543363741 base units
|
||||
// xvm.getAssetDescription(LUX) -> denomination 9, so 1 LUX = 1e9 base units
|
||||
// platform.getMinStake -> minValidatorStake 2000000000 (= 2 LUX)
|
||||
// platform.getCurrentValidators -> weight 500000000000000000 (= 500M LUX),
|
||||
// potentialReward 33575831900252839
|
||||
const (
|
||||
mainnetCurrentSupply = uint64(13_272_095_200_543_363_741)
|
||||
mainnetValidatorWeight = uint64(500_000_000_000_000_000)
|
||||
mainnetPotentialReward = uint64(33_575_831_900_252_839)
|
||||
mainnetStakedDuration = time.Duration(1_797_088_011-1_765_573_611) * time.Second
|
||||
|
||||
// mainnetSupplyAtBond is the current supply at the instant the validator
|
||||
// bonded, recovered below from the observed reward.
|
||||
mainnetSupplyAtBond = uint64(13_106_511_852_580_896_694)
|
||||
)
|
||||
|
||||
// mainnetRewardConfig is the config a mainnet node is built with, transcribed
|
||||
// from genesis/pkg/genesis/params.go MainnetParams.RewardConfig.
|
||||
//
|
||||
// The denominations in that file are Lux = 1e6 and TeraLux = 1e18, so
|
||||
// SupplyCap = 2 * TeraLux = 2e18 base units. The chain's LUX asset has
|
||||
// denomination 9, so that is a cap of 2 BILLION LUX — not the 2 trillion the
|
||||
// comment claims. The file is a factor of 1000 out against the asset it
|
||||
// denominates.
|
||||
var mainnetRewardConfig = Config{
|
||||
MaxConsumptionRate: 120_000,
|
||||
MinConsumptionRate: 100_000,
|
||||
MintingPeriod: 365 * 24 * time.Hour,
|
||||
SupplyCap: 2_000_000_000_000_000_000,
|
||||
}
|
||||
|
||||
// TestMainnetSupplyExceedsCompiledCap states the precondition plainly: the live
|
||||
// supply is already past the cap the reward calculator is built with.
|
||||
func TestMainnetSupplyExceedsCompiledCap(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
require.Greater(mainnetCurrentSupply, mainnetRewardConfig.SupplyCap,
|
||||
"live supply must exceed the compiled cap for this whole file to be relevant")
|
||||
|
||||
t.Logf("compiled SupplyCap %d = %.0f LUX", mainnetRewardConfig.SupplyCap,
|
||||
float64(mainnetRewardConfig.SupplyCap)/1e9)
|
||||
t.Logf("live currentSupply %d = %.0f LUX (%.2fx the cap)", mainnetCurrentSupply,
|
||||
float64(mainnetCurrentSupply)/1e9,
|
||||
float64(mainnetCurrentSupply)/float64(mainnetRewardConfig.SupplyCap))
|
||||
}
|
||||
|
||||
// TestMainnetRewardsAreComputedFromAnUnderflow is the defect.
|
||||
//
|
||||
// calculator.Calculate opens with an unguarded uint64 subtraction:
|
||||
//
|
||||
// remainingSupply := c.supplyCap - currentSupply
|
||||
//
|
||||
// Past the cap that wraps, and every subsequent term — the whole reward — is
|
||||
// scaled by the wrapped value. The reward does not clamp to zero at the cap; it
|
||||
// jumps to a large number and the emission schedule silently stops meaning what
|
||||
// it says.
|
||||
//
|
||||
// The proof is that feeding the REAL calculator the wrapped-regime inputs
|
||||
// reproduces the potentialReward the chain is actually carrying, exactly.
|
||||
func TestMainnetRewardsAreComputedFromAnUnderflow(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
wrapped := mainnetRewardConfig.SupplyCap - mainnetSupplyAtBond // deliberate: this is the bug
|
||||
require.Greater(wrapped, mainnetRewardConfig.SupplyCap,
|
||||
"the subtraction must have wrapped, or there is no defect to demonstrate")
|
||||
t.Logf("supplyCap - currentSupply wrapped to %d (%.0f LUX of phantom headroom)",
|
||||
wrapped, float64(wrapped)/1e9)
|
||||
|
||||
got := NewCalculator(mainnetRewardConfig).Calculate(
|
||||
mainnetStakedDuration, mainnetValidatorWeight, mainnetSupplyAtBond,
|
||||
)
|
||||
|
||||
require.Equal(mainnetPotentialReward, got,
|
||||
"the production calculator, in the wrapped regime, must reproduce the "+
|
||||
"potentialReward mainnet is actually carrying")
|
||||
}
|
||||
|
||||
// TestMainnetRewardWouldBeZeroWithoutTheWrap shows what the emission schedule
|
||||
// SAYS should happen past the cap, and therefore the size of the divergence:
|
||||
// not a rounding error, the difference between 33.5M LUX and nothing.
|
||||
func TestMainnetRewardWouldBeZeroWithoutTheWrap(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
// A cap above the live supply is the only regime in which the subtraction
|
||||
// is meaningful. Set it just above and the remaining headroom is tiny, so
|
||||
// the reward collapses toward zero — the intended behaviour at the cap.
|
||||
atCap := mainnetRewardConfig
|
||||
atCap.SupplyCap = mainnetSupplyAtBond + 1
|
||||
|
||||
got := NewCalculator(atCap).Calculate(
|
||||
mainnetStakedDuration, mainnetValidatorWeight, mainnetSupplyAtBond,
|
||||
)
|
||||
|
||||
require.Zero(got, "at the cap, emission must be zero")
|
||||
t.Logf("intended at cap: 0 LUX; actually issued: %.2f LUX",
|
||||
float64(mainnetPotentialReward)/1e9)
|
||||
}
|
||||
|
||||
// TestSupplyCapGuardIsTheFix pins the one-line remedy so a future reader can see
|
||||
// what "clamp instead of wrap" buys: emission stops at the cap, as designed,
|
||||
// and no vote is needed to make it behave.
|
||||
//
|
||||
// It is deliberately a test against a local guard rather than a change to
|
||||
// Calculate: altering live emission is a monetary change, and monetary changes
|
||||
// belong in a node release that operators choose to adopt — never in a
|
||||
// stake-weighted vote. See vms/platformvm/stakingparams.
|
||||
func TestSupplyCapGuardIsTheFix(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
guarded := func(cap, supply uint64) uint64 {
|
||||
if supply >= cap {
|
||||
return 0
|
||||
}
|
||||
return cap - supply
|
||||
}
|
||||
|
||||
require.Zero(guarded(mainnetRewardConfig.SupplyCap, mainnetCurrentSupply),
|
||||
"past the cap the guard yields no headroom, so Calculate yields no reward")
|
||||
require.Equal(uint64(1), guarded(mainnetSupplyAtBond+1, mainnetSupplyAtBond))
|
||||
|
||||
// And the unguarded form is what mainnet runs.
|
||||
require.NotZero(mainnetRewardConfig.SupplyCap - mainnetCurrentSupply)
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package stakingparams
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/node/vms/platformvm/reward"
|
||||
)
|
||||
|
||||
// Denominations, in the P-Chain's base unit (nLUX).
|
||||
const (
|
||||
Lux uint64 = 1_000_000_000
|
||||
KiloLux = 1_000 * Lux
|
||||
MegaLux = 1_000 * KiloLux
|
||||
GigaLux = 1_000 * MegaLux
|
||||
)
|
||||
|
||||
// MainnetGenesis is the policy Lux mainnet runs under today, transcribed from
|
||||
// the constants presently compiled into the node (MinValidatorStake 2000 LUX,
|
||||
// MaxValidatorStake 5 GigaLux, MinStakeDuration 2 weeks, MaxStakeDuration
|
||||
// 1 year, MinDelegationFee 2%, UptimeRequirement 80%).
|
||||
//
|
||||
// Seeding the history with exactly today's values is what makes adopting this
|
||||
// mechanism a no-op on day one: nothing about the live network changes until
|
||||
// stake votes to change it.
|
||||
var MainnetGenesis = Params{
|
||||
MinValidatorStake: 2_000 * Lux,
|
||||
MaxValidatorStake: 5 * GigaLux,
|
||||
MinStakeDuration: 2 * 7 * 24 * 60 * 60,
|
||||
MaxStakeDuration: 365 * 24 * 60 * 60,
|
||||
MinDelegationFee: 20_000, // 2%
|
||||
UptimeRequirement: 800_000, // 80%
|
||||
}
|
||||
|
||||
// MainnetBounds is the constitution — the envelope no vote can leave.
|
||||
//
|
||||
// Each bound is chosen against one question: what is the most exclusionary
|
||||
// value a hostile stake majority could ever be allowed to reach, and is the
|
||||
// network still open to an arbitrary global participant there? If the answer at
|
||||
// Hi (or Lo, for the widening fields) is "no", the bound is wrong.
|
||||
//
|
||||
// - minValidatorStake Hi = 100_000 LUX. At the most hostile setting the
|
||||
// mechanism permits, a holder of 100k LUX — 0.000005% of the 2T supply cap —
|
||||
// can still validate. Below Lo = 1 LUX there is nothing to bond.
|
||||
// - maxValidatorStake Lo = 1 MegaLux stops a cartel shrinking the ceiling to
|
||||
// exclude large honest stakers; Hi holds today's 5 GigaLux.
|
||||
// - minStakeDuration Hi = 30 days caps how long anyone can be forced to lock.
|
||||
// - maxStakeDuration Hi = 365 days: the reward calculator's MintingPeriod is
|
||||
// one year, so a longer bond has no defined emission. This bound is a
|
||||
// correctness constraint, not a policy preference.
|
||||
// - minDelegationFee Hi = 20% caps how much of a delegator's yield validators
|
||||
// can vote themselves. Delegators are the one constituency that cannot
|
||||
// defend itself by voting, because the vote is the validator's.
|
||||
// - uptimeRequirement Hi = 95%. Above that, ordinary maintenance forfeits a
|
||||
// reward, and the field stops being a liveness incentive and becomes an
|
||||
// ejection weapon.
|
||||
var MainnetBounds = Bounds{
|
||||
Lo: Params{
|
||||
MinValidatorStake: 1 * Lux,
|
||||
MaxValidatorStake: 1 * MegaLux,
|
||||
MinStakeDuration: 60 * 60,
|
||||
MaxStakeDuration: 7 * 24 * 60 * 60,
|
||||
MinDelegationFee: 0,
|
||||
UptimeRequirement: 0,
|
||||
},
|
||||
Hi: Params{
|
||||
MinValidatorStake: 100 * KiloLux,
|
||||
MaxValidatorStake: 5 * GigaLux,
|
||||
MinStakeDuration: 30 * 24 * 60 * 60,
|
||||
MaxStakeDuration: 365 * 24 * 60 * 60,
|
||||
MinDelegationFee: 200_000, // 20%
|
||||
UptimeRequirement: 950_000, // 95%
|
||||
},
|
||||
}
|
||||
|
||||
// MainnetRate is the brake on exclusionary change: at most 10% of the current
|
||||
// value per accepted change, and at most one accepted change per 14 days.
|
||||
//
|
||||
// 14 days is not arbitrary — it is mainnet's MinStakeDuration, so no bond can
|
||||
// be entered and matured inside a single governance step. Combined with the 10%
|
||||
// cap it puts roughly 1.6 years of continuous, public, on-chain effort between
|
||||
// today's 2000 LUX floor and the 100k LUX ceiling, which is the window in which
|
||||
// anyone being squeezed out can organise, exit, or fork.
|
||||
var MainnetRate = Rate{
|
||||
MaxStep: reward.PercentDenominator / 10, // 10% of current
|
||||
MinInterval: 14 * 24 * time.Hour,
|
||||
}
|
||||
@@ -0,0 +1,303 @@
|
||||
// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
// Package stakingparams is the node-policy the validator set governs, plus the
|
||||
// pure rule that decides whether a proposed change is admissible. It is one
|
||||
// small, orthogonal definition — values only, no wire, state or config
|
||||
// dependencies — composed by the three consumers that need it: the P-Chain tx
|
||||
// executor (admission), the block executor (reward gate), and state.
|
||||
//
|
||||
// It is the sibling of package security: security says how a network's set is
|
||||
// ADMITTED, stakingparams says on what TERMS.
|
||||
//
|
||||
// # What is here, and what is deliberately not
|
||||
//
|
||||
// Here: validator admission thresholds, stake durations, the delegation-fee
|
||||
// floor, and the uptime requirement. These are operational policy — a
|
||||
// legitimate collective choice of the people running the network.
|
||||
//
|
||||
// NOT here, and never to be added: MinConsumptionRate, MaxConsumptionRate,
|
||||
// MintingPeriod, SupplyCap, and the fee-split ratio. Those are money. A votable
|
||||
// emission schedule is a capture surface, not a feature; predictable money is
|
||||
// the product. They stay compiled into the node and change only the way
|
||||
// Bitcoin's rules change — by users and validators voluntarily adopting a new
|
||||
// release. TestParamsGovernsNoMonetaryField enforces this at build time.
|
||||
//
|
||||
// # Who decides
|
||||
//
|
||||
// Nobody. There is no admin key, owner, council, guardian or upgrader in this
|
||||
// package or in the mechanism it serves — no field to hold one and no argument
|
||||
// to pass one. Accept is a pure function of (current state, proposal,
|
||||
// compiled-in bounds). Every node runs it independently and the stake-weighted
|
||||
// consensus resolves the outcome, exactly as it already does for the
|
||||
// commit/abort decision on a validator's reward. A dissenting node cannot veto,
|
||||
// only vote and lose; a proposing node holds no privilege, because its
|
||||
// preference binds no one.
|
||||
//
|
||||
// # The one invariant worth remembering
|
||||
//
|
||||
// Moving toward MORE permissionless is free and instant. Moving toward LESS
|
||||
// permissionless is bounded and rate-limited. A cartel that captures a stake
|
||||
// majority therefore cannot ambush the minority out of the validator set: every
|
||||
// exclusionary step is small, capped, and visible for the interval it takes,
|
||||
// which is the window in which the excluded fork. That asymmetry is the whole
|
||||
// security argument, and it is one rule applied uniformly to every field.
|
||||
package stakingparams
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/luxfi/node/vms/platformvm/reward"
|
||||
)
|
||||
|
||||
// Params is the node-level staking policy in force.
|
||||
//
|
||||
// Percent-scaled fields use reward.PercentDenominator (1_000_000), so 800_000
|
||||
// is 80%. Durations are seconds, matching the P-Chain wire.
|
||||
type Params struct {
|
||||
MinValidatorStake uint64 `json:"minValidatorStake"`
|
||||
MaxValidatorStake uint64 `json:"maxValidatorStake"`
|
||||
MinStakeDuration uint32 `json:"minStakeDuration"`
|
||||
MaxStakeDuration uint32 `json:"maxStakeDuration"`
|
||||
MinDelegationFee uint32 `json:"minDelegationFee"`
|
||||
UptimeRequirement uint32 `json:"uptimeRequirement"`
|
||||
}
|
||||
|
||||
// Bounds is the constitution: the closed interval outside which no proposal is
|
||||
// ever admissible, whatever the vote. Lo and Hi are corner Params — each field
|
||||
// of a proposal must lie between the same field of Lo and of Hi.
|
||||
//
|
||||
// Bounds is compiled in. Changing it requires a node release that operators
|
||||
// choose to run — the Bitcoin path — and is the only route by which the
|
||||
// governable envelope itself can move. That is intentional: the envelope is the
|
||||
// thing a stake majority must not be able to widen for itself.
|
||||
type Bounds struct {
|
||||
Lo Params
|
||||
Hi Params
|
||||
}
|
||||
|
||||
// Rate limits how fast policy may move against the participants it governs.
|
||||
//
|
||||
// MaxStep is expressed in reward.PercentDenominator units of the CURRENT value
|
||||
// (100_000 = 10% of current per change). MinInterval is the minimum chain-time
|
||||
// spacing between two accepted changes. Together they set the cost of a
|
||||
// squeeze-out: reaching a target from a starting value takes
|
||||
// ceil(log(target/start) / log(1+step)) changes, each MinInterval apart, all of
|
||||
// it on-chain and observable.
|
||||
type Rate struct {
|
||||
MaxStep uint32
|
||||
MinInterval time.Duration
|
||||
}
|
||||
|
||||
var (
|
||||
ErrOutOfBounds = errors.New("stakingparams: proposal outside compiled-in bounds")
|
||||
ErrIncoherent = errors.New("stakingparams: min exceeds max")
|
||||
ErrStepTooLarge = errors.New("stakingparams: exclusionary step exceeds rate limit")
|
||||
ErrTooSoon = errors.New("stakingparams: minimum interval between changes not elapsed")
|
||||
ErrNoChange = errors.New("stakingparams: proposal is identical to current params")
|
||||
ErrEmptyHistory = errors.New("stakingparams: history is empty")
|
||||
ErrNotMonotonic = errors.New("stakingparams: history activations must strictly increase")
|
||||
ErrBoundsIncoherent = errors.New("stakingparams: bounds Lo exceeds Hi")
|
||||
)
|
||||
|
||||
// field is one governed value, projected out of Params so that every rule is
|
||||
// written once and applied uniformly. higherIsPermissive records which
|
||||
// direction widens the set of parties who can participate; that single bit is
|
||||
// what makes the ratchet asymmetry a rule rather than six special cases.
|
||||
type field struct {
|
||||
name string
|
||||
get func(Params) uint64
|
||||
higherIsPermissive bool
|
||||
}
|
||||
|
||||
func fields() []field {
|
||||
return []field{
|
||||
{"minValidatorStake", func(p Params) uint64 { return p.MinValidatorStake }, false},
|
||||
{"maxValidatorStake", func(p Params) uint64 { return p.MaxValidatorStake }, true},
|
||||
{"minStakeDuration", func(p Params) uint64 { return uint64(p.MinStakeDuration) }, false},
|
||||
{"maxStakeDuration", func(p Params) uint64 { return uint64(p.MaxStakeDuration) }, true},
|
||||
{"minDelegationFee", func(p Params) uint64 { return uint64(p.MinDelegationFee) }, false},
|
||||
{"uptimeRequirement", func(p Params) uint64 { return uint64(p.UptimeRequirement) }, false},
|
||||
}
|
||||
}
|
||||
|
||||
// Valid reports whether p is internally coherent: every min at or below its
|
||||
// paired max. Coherence is checked separately from Bounds because a proposal
|
||||
// can be inside the envelope on every field and still be nonsense as a pair.
|
||||
func (p Params) Valid() error {
|
||||
if p.MinValidatorStake > p.MaxValidatorStake {
|
||||
return fmt.Errorf("%w: minValidatorStake %d > maxValidatorStake %d",
|
||||
ErrIncoherent, p.MinValidatorStake, p.MaxValidatorStake)
|
||||
}
|
||||
if p.MinStakeDuration > p.MaxStakeDuration {
|
||||
return fmt.Errorf("%w: minStakeDuration %d > maxStakeDuration %d",
|
||||
ErrIncoherent, p.MinStakeDuration, p.MaxStakeDuration)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Valid reports whether the compiled-in envelope is itself coherent. It exists
|
||||
// so a node release that ships a nonsensical Bounds fails loudly at startup
|
||||
// rather than silently admitting or rejecting everything.
|
||||
func (b Bounds) Valid() error {
|
||||
for _, f := range fields() {
|
||||
if f.get(b.Lo) > f.get(b.Hi) {
|
||||
return fmt.Errorf("%w: %s Lo %d > Hi %d", ErrBoundsIncoherent, f.name, f.get(b.Lo), f.get(b.Hi))
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Contains reports whether every field of p lies inside the envelope.
|
||||
func (b Bounds) Contains(p Params) error {
|
||||
for _, f := range fields() {
|
||||
v, lo, hi := f.get(p), f.get(b.Lo), f.get(b.Hi)
|
||||
if v < lo || v > hi {
|
||||
return fmt.Errorf("%w: %s %d not in [%d, %d]", ErrOutOfBounds, f.name, v, lo, hi)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Clamp returns p with every field pulled inside the envelope. It is the
|
||||
// migration path when a node release narrows Bounds under params that are
|
||||
// already live: the chain does not halt and no key is needed to rescue it —
|
||||
// the constitution simply binds, deterministically and identically on every
|
||||
// node.
|
||||
func (b Bounds) Clamp(p Params) Params {
|
||||
return Params{
|
||||
MinValidatorStake: min(max(p.MinValidatorStake, b.Lo.MinValidatorStake), b.Hi.MinValidatorStake),
|
||||
MaxValidatorStake: min(max(p.MaxValidatorStake, b.Lo.MaxValidatorStake), b.Hi.MaxValidatorStake),
|
||||
MinStakeDuration: min(max(p.MinStakeDuration, b.Lo.MinStakeDuration), b.Hi.MinStakeDuration),
|
||||
MaxStakeDuration: min(max(p.MaxStakeDuration, b.Lo.MaxStakeDuration), b.Hi.MaxStakeDuration),
|
||||
MinDelegationFee: min(max(p.MinDelegationFee, b.Lo.MinDelegationFee), b.Hi.MinDelegationFee),
|
||||
UptimeRequirement: min(max(p.UptimeRequirement, b.Lo.UptimeRequirement), b.Hi.UptimeRequirement),
|
||||
}
|
||||
}
|
||||
|
||||
// stepLimit returns the largest admissible exclusionary move away from cur.
|
||||
// It is computed without overflowing: cur/denom*step + cur%denom*step/denom.
|
||||
// A cur of 0 admits any move to 1, so a field parked at zero is not frozen
|
||||
// there forever.
|
||||
func stepLimit(cur uint64, step uint32) uint64 {
|
||||
const denom = uint64(reward.PercentDenominator)
|
||||
s := uint64(step)
|
||||
lim := (cur/denom)*s + (cur%denom)*s/denom
|
||||
if lim == 0 {
|
||||
lim = 1
|
||||
}
|
||||
return lim
|
||||
}
|
||||
|
||||
// Accept is the entire governance decision, as a pure function.
|
||||
//
|
||||
// It takes no key, no caller identity, no role and no owner — there is nothing
|
||||
// to hold and nothing to compromise. Given the same (cur, next, b, r, elapsed)
|
||||
// every node on earth reaches the same verdict, which is what lets the existing
|
||||
// stake-weighted commit/abort machinery settle it with no leader.
|
||||
//
|
||||
// elapsed is the chain time since the last accepted change. Pass a duration at
|
||||
// or above r.MinInterval when no change has been made yet.
|
||||
func Accept(cur, next Params, b Bounds, r Rate, elapsed time.Duration) error {
|
||||
if err := b.Valid(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := next.Valid(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := b.Contains(next); err != nil {
|
||||
return err
|
||||
}
|
||||
if cur == next {
|
||||
return ErrNoChange
|
||||
}
|
||||
if elapsed < r.MinInterval {
|
||||
return fmt.Errorf("%w: %s elapsed, %s required", ErrTooSoon, elapsed, r.MinInterval)
|
||||
}
|
||||
|
||||
for _, f := range fields() {
|
||||
from, to := f.get(cur), f.get(next)
|
||||
if from == to {
|
||||
continue
|
||||
}
|
||||
// Toward more permissionless: free and instant. Widening who may
|
||||
// participate can never be used to exclude anyone, so it needs no
|
||||
// brake — only the Bounds check above, which already passed.
|
||||
if (to > from) == f.higherIsPermissive {
|
||||
continue
|
||||
}
|
||||
// Toward less permissionless: rate-limited. This is the only direction
|
||||
// a stake majority can use against a minority, so it is the only one
|
||||
// that costs time.
|
||||
var delta uint64
|
||||
if to > from {
|
||||
delta = to - from
|
||||
} else {
|
||||
delta = from - to
|
||||
}
|
||||
if lim := stepLimit(from, r.MaxStep); delta > lim {
|
||||
return fmt.Errorf("%w: %s moved %d from %d, limit %d per change",
|
||||
ErrStepTooLarge, f.name, delta, from, lim)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Entry is one activation of a policy: the params, and the chain time from
|
||||
// which they bind.
|
||||
type Entry struct {
|
||||
Activation int64 `json:"activation"`
|
||||
Params Params `json:"params"`
|
||||
}
|
||||
|
||||
// History is the append-only record of every policy that has been in force,
|
||||
// oldest first. It exists for one reason: a validator must be judged on the
|
||||
// terms it agreed to when it bonded, never on terms voted in afterwards.
|
||||
//
|
||||
// Without it, UptimeRequirement — the one governed field read at REWARD time
|
||||
// rather than at admission time — would be retroactive, and a stake majority
|
||||
// could raise it the day before a rival's stake matures and confiscate the
|
||||
// reward. With it, governance can only bind the future, which is the difference
|
||||
// between setting policy and expropriating people.
|
||||
type History []Entry
|
||||
|
||||
// Valid reports whether h is non-empty and strictly increasing in activation.
|
||||
func (h History) Valid() error {
|
||||
if len(h) == 0 {
|
||||
return ErrEmptyHistory
|
||||
}
|
||||
for i := 1; i < len(h); i++ {
|
||||
if h[i].Activation <= h[i-1].Activation {
|
||||
return fmt.Errorf("%w: entry %d activates at %d, not after %d",
|
||||
ErrNotMonotonic, i, h[i].Activation, h[i-1].Activation)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// At returns the params in force at unix time t — the latest entry activating
|
||||
// at or before t. Before the first activation the first entry applies, so
|
||||
// genesis params bind from the beginning of time.
|
||||
func (h History) At(t int64) Params {
|
||||
if len(h) == 0 {
|
||||
return Params{}
|
||||
}
|
||||
p := h[0].Params
|
||||
for _, e := range h {
|
||||
if e.Activation > t {
|
||||
break
|
||||
}
|
||||
p = e.Params
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
// Current returns the params in force now, i.e. the newest entry.
|
||||
func (h History) Current() Params {
|
||||
if len(h) == 0 {
|
||||
return Params{}
|
||||
}
|
||||
return h[len(h)-1].Params
|
||||
}
|
||||
@@ -0,0 +1,267 @@
|
||||
// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package stakingparams
|
||||
|
||||
import (
|
||||
"math"
|
||||
"reflect"
|
||||
"sort"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
const day = 24 * time.Hour
|
||||
|
||||
// TestParamsGovernsNoMonetaryField is the build-time guard on the money/policy
|
||||
// split. Params must contain exactly the operational fields and nothing else;
|
||||
// if someone later adds SupplyCap, MintingPeriod or a consumption rate, this
|
||||
// test fails and the reviewer has to argue for making inflation votable rather
|
||||
// than slipping it in.
|
||||
func TestParamsGovernsNoMonetaryField(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
want := []string{
|
||||
"MaxStakeDuration", "MaxValidatorStake", "MinDelegationFee",
|
||||
"MinStakeDuration", "MinValidatorStake", "UptimeRequirement",
|
||||
}
|
||||
|
||||
tp := reflect.TypeOf(Params{})
|
||||
got := make([]string, 0, tp.NumField())
|
||||
for i := 0; i < tp.NumField(); i++ {
|
||||
got = append(got, tp.Field(i).Name)
|
||||
}
|
||||
sort.Strings(got)
|
||||
require.Equal(want, got,
|
||||
"Params is the governable set. Monetary fields (SupplyCap, MintingPeriod, "+
|
||||
"Min/MaxConsumptionRate, the fee-split ratio) must never appear here.")
|
||||
|
||||
// And the projection table must cover every field, or a field would be
|
||||
// silently ungoverned by the bounds and rate rules.
|
||||
require.Len(fields(), tp.NumField())
|
||||
}
|
||||
|
||||
// TestNoAuthoritySurface asserts the mechanism has nowhere to put an admin key.
|
||||
// Params, Bounds and Rate are the complete state of the decision; none carries
|
||||
// an owner, role, threshold or address, and Accept takes no caller identity.
|
||||
func TestNoAuthoritySurface(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
for _, typ := range []reflect.Type{
|
||||
reflect.TypeOf(Params{}), reflect.TypeOf(Bounds{}), reflect.TypeOf(Rate{}), reflect.TypeOf(Entry{}),
|
||||
} {
|
||||
for i := 0; i < typ.NumField(); i++ {
|
||||
name := typ.Field(i).Name
|
||||
for _, banned := range []string{"Owner", "Admin", "Auth", "Role", "Guardian", "Council", "Pauser", "Upgrader", "Threshold", "Address"} {
|
||||
require.NotContains(name, banned,
|
||||
"%s.%s introduces an authority surface; governance must be keyless", typ.Name(), name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Accept's signature carries no identity argument.
|
||||
ft := reflect.TypeOf(Accept)
|
||||
require.Equal(5, ft.NumIn(), "Accept must take exactly (cur, next, bounds, rate, elapsed)")
|
||||
}
|
||||
|
||||
func TestMainnetConstitutionIsCoherentAndContainsToday(t *testing.T) {
|
||||
require := require.New(t)
|
||||
require.NoError(MainnetBounds.Valid())
|
||||
require.NoError(MainnetGenesis.Valid())
|
||||
require.NoError(MainnetBounds.Contains(MainnetGenesis),
|
||||
"today's live mainnet policy must be inside the envelope, or adopting this would change the network on day one")
|
||||
}
|
||||
|
||||
// TestLooseningIsInstant proves the permissionless-ward direction is free: a
|
||||
// proposal that lowers every barrier at once, by any amount inside Bounds, is
|
||||
// admissible in a single step.
|
||||
func TestLooseningIsInstant(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
wideOpen := Params{
|
||||
MinValidatorStake: 1 * Lux, // 2000 LUX -> 1 LUX, a 2000x drop
|
||||
MaxValidatorStake: 5 * GigaLux, // unchanged
|
||||
MinStakeDuration: 60 * 60, // 14 days -> 1 hour
|
||||
MaxStakeDuration: 365 * 24 * 60 * 60, // unchanged
|
||||
MinDelegationFee: 0, // 2% -> 0
|
||||
UptimeRequirement: 0, // 80% -> 0
|
||||
}
|
||||
require.NoError(Accept(MainnetGenesis, wideOpen, MainnetBounds, MainnetRate, MainnetRate.MinInterval))
|
||||
}
|
||||
|
||||
// TestExclusionaryStepIsRateLimited proves the other direction costs time: the
|
||||
// same magnitude of change, pointed at excluding people, is refused.
|
||||
func TestExclusionaryStepIsRateLimited(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
// A cartel tries to jump the floor straight to the ceiling.
|
||||
squeeze := MainnetGenesis
|
||||
squeeze.MinValidatorStake = 100 * KiloLux
|
||||
require.ErrorIs(Accept(MainnetGenesis, squeeze, MainnetBounds, MainnetRate, 365*day), ErrStepTooLarge)
|
||||
|
||||
// Exactly 10% of current is the largest admissible step.
|
||||
ok := MainnetGenesis
|
||||
ok.MinValidatorStake = MainnetGenesis.MinValidatorStake + MainnetGenesis.MinValidatorStake/10
|
||||
require.NoError(Accept(MainnetGenesis, ok, MainnetBounds, MainnetRate, MainnetRate.MinInterval))
|
||||
|
||||
// One nLUX beyond it is not.
|
||||
over := ok
|
||||
over.MinValidatorStake++
|
||||
require.ErrorIs(Accept(MainnetGenesis, over, MainnetBounds, MainnetRate, MainnetRate.MinInterval), ErrStepTooLarge)
|
||||
}
|
||||
|
||||
func TestMinIntervalIsEnforced(t *testing.T) {
|
||||
require := require.New(t)
|
||||
next := MainnetGenesis
|
||||
next.UptimeRequirement = 700_000 // a loosening, so only the interval can refuse it
|
||||
|
||||
require.ErrorIs(Accept(MainnetGenesis, next, MainnetBounds, MainnetRate, MainnetRate.MinInterval-time.Second), ErrTooSoon)
|
||||
require.NoError(Accept(MainnetGenesis, next, MainnetBounds, MainnetRate, MainnetRate.MinInterval))
|
||||
}
|
||||
|
||||
// TestBoundsAreAbsolute proves no vote, however patient, escapes the envelope.
|
||||
// This is the Bitcoin half: to move these, operators must adopt a new release.
|
||||
func TestBoundsAreAbsolute(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
mut func(*Params)
|
||||
}{
|
||||
{"minValidatorStake above Hi", func(p *Params) { p.MinValidatorStake = MainnetBounds.Hi.MinValidatorStake + 1 }},
|
||||
{"minDelegationFee above 20%", func(p *Params) { p.MinDelegationFee = 200_001 }},
|
||||
{"uptimeRequirement above 95%", func(p *Params) { p.UptimeRequirement = 950_001 }},
|
||||
{"minStakeDuration above 30d", func(p *Params) { p.MinStakeDuration = 30*24*60*60 + 1 }},
|
||||
{"maxValidatorStake below Lo", func(p *Params) { p.MaxValidatorStake = MainnetBounds.Lo.MaxValidatorStake - 1 }},
|
||||
} {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
p := MainnetGenesis
|
||||
tc.mut(&p)
|
||||
require.ErrorIs(Accept(MainnetGenesis, p, MainnetBounds, MainnetRate, 10*365*day), ErrOutOfBounds)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestSqueezeOutCostsYears measures the security margin: driving the validator
|
||||
// floor from today's value to the most exclusionary value the constitution
|
||||
// permits, at the maximum rate, in public, takes this long.
|
||||
//
|
||||
// It is the number the design lives or dies on — it is the warning window in
|
||||
// which anyone being pushed out can organise, exit, or fork.
|
||||
func TestSqueezeOutCostsYears(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
cur := MainnetGenesis
|
||||
steps := 0
|
||||
for cur.MinValidatorStake < MainnetBounds.Hi.MinValidatorStake {
|
||||
next := cur
|
||||
next.MinValidatorStake = min(
|
||||
cur.MinValidatorStake+stepLimit(cur.MinValidatorStake, MainnetRate.MaxStep),
|
||||
MainnetBounds.Hi.MinValidatorStake,
|
||||
)
|
||||
require.NoError(Accept(cur, next, MainnetBounds, MainnetRate, MainnetRate.MinInterval),
|
||||
"max-rate step must always be admissible")
|
||||
cur = next
|
||||
steps++
|
||||
require.Less(steps, 1000, "loop guard")
|
||||
}
|
||||
|
||||
elapsed := time.Duration(steps) * MainnetRate.MinInterval
|
||||
t.Logf("squeeze-out from %d nLUX to %d nLUX: %d accepted changes, %.0f days (%.2f years)",
|
||||
MainnetGenesis.MinValidatorStake, cur.MinValidatorStake, steps,
|
||||
elapsed.Hours()/24, elapsed.Hours()/24/365)
|
||||
|
||||
require.Greater(elapsed, 365*day,
|
||||
"a stake majority must need over a year of public, on-chain effort to reach the most exclusionary policy")
|
||||
|
||||
// And having spent it, the network is STILL open to a 100k LUX holder.
|
||||
require.Equal(MainnetBounds.Hi.MinValidatorStake, cur.MinValidatorStake)
|
||||
require.NoError(MainnetBounds.Contains(cur))
|
||||
}
|
||||
|
||||
// TestHistoryBindsOnlyTheFuture is the non-retroactivity proof, and it is the
|
||||
// property that separates governance from expropriation.
|
||||
//
|
||||
// UptimeRequirement is the one governed field read at REWARD time, long after a
|
||||
// validator bonded. A validator that bonded under an 80% rule is judged at 80%
|
||||
// even after stake votes the rule to 95% — so a majority cannot raise the bar
|
||||
// the day before a rival's stake matures and take its reward.
|
||||
func TestHistoryBindsOnlyTheFuture(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
const (
|
||||
bondedAt = 1_765_573_611 // the real start time of today's mainnet validators
|
||||
votedAt = 1_785_000_000 // a later vote
|
||||
)
|
||||
|
||||
tightened := MainnetGenesis
|
||||
tightened.UptimeRequirement = 880_000 // 88%
|
||||
|
||||
h := History{
|
||||
{Activation: 0, Params: MainnetGenesis},
|
||||
{Activation: votedAt, Params: tightened},
|
||||
}
|
||||
require.NoError(h.Valid())
|
||||
|
||||
require.Equal(uint32(800_000), h.At(bondedAt).UptimeRequirement,
|
||||
"a validator bonded before the vote is judged on the terms it accepted")
|
||||
require.Equal(uint32(880_000), h.At(votedAt+1).UptimeRequirement,
|
||||
"a validator bonding after the vote is judged on the new terms")
|
||||
require.Equal(tightened, h.Current())
|
||||
|
||||
// Before any activation, genesis params bind.
|
||||
require.Equal(MainnetGenesis, h.At(-1))
|
||||
}
|
||||
|
||||
func TestHistoryRejectsNonMonotonic(t *testing.T) {
|
||||
require := require.New(t)
|
||||
require.ErrorIs(History{}.Valid(), ErrEmptyHistory)
|
||||
require.ErrorIs(History{{Activation: 10}, {Activation: 10}}.Valid(), ErrNotMonotonic)
|
||||
require.ErrorIs(History{{Activation: 10}, {Activation: 9}}.Valid(), ErrNotMonotonic)
|
||||
}
|
||||
|
||||
func TestIncoherentProposalRefused(t *testing.T) {
|
||||
require := require.New(t)
|
||||
p := MainnetGenesis
|
||||
p.MinValidatorStake = 5 * GigaLux
|
||||
p.MaxValidatorStake = 1 * MegaLux
|
||||
require.ErrorIs(Accept(MainnetGenesis, p, MainnetBounds, MainnetRate, 365*day), ErrIncoherent)
|
||||
}
|
||||
|
||||
func TestNoOpProposalRefused(t *testing.T) {
|
||||
require := require.New(t)
|
||||
require.ErrorIs(Accept(MainnetGenesis, MainnetGenesis, MainnetBounds, MainnetRate, 365*day), ErrNoChange)
|
||||
}
|
||||
|
||||
// TestStepLimitNoOverflow guards the arithmetic at the extremes the P-Chain can
|
||||
// actually reach: weights run to ~1.8e19 and the denominator is 1e6, so the
|
||||
// naive cur*step form overflows uint64.
|
||||
func TestStepLimitNoOverflow(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
require.Equal(uint64(math.MaxUint64/10), stepLimit(math.MaxUint64, MainnetRate.MaxStep))
|
||||
require.Equal(uint64(200*Lux), stepLimit(2_000*Lux, MainnetRate.MaxStep))
|
||||
// A field parked at zero is not frozen there.
|
||||
require.Equal(uint64(1), stepLimit(0, MainnetRate.MaxStep))
|
||||
}
|
||||
|
||||
// TestClampRescuesWithoutAKey proves the migration path when a release narrows
|
||||
// the constitution under live params: every node clamps identically and the
|
||||
// chain keeps running. No guardian, no emergency multisig, no halt.
|
||||
func TestClampRescuesWithoutAKey(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
live := MainnetGenesis
|
||||
live.UptimeRequirement = 940_000 // legal today
|
||||
|
||||
narrowed := MainnetBounds
|
||||
narrowed.Hi.UptimeRequirement = 900_000 // a later release tightens the ceiling
|
||||
|
||||
require.Error(narrowed.Contains(live))
|
||||
clamped := narrowed.Clamp(live)
|
||||
require.NoError(narrowed.Contains(clamped))
|
||||
require.Equal(uint32(900_000), clamped.UptimeRequirement)
|
||||
require.NoError(clamped.Valid())
|
||||
}
|
||||
@@ -29,13 +29,17 @@ func getValidatorRules(
|
||||
netID ids.ID,
|
||||
) (*addValidatorRules, error) {
|
||||
if netID == constants.PrimaryNetworkID {
|
||||
// A joiner accepts the policy in force at the moment it joins, so the
|
||||
// current chain time is the right instant to resolve. With no governed
|
||||
// history this returns the compiled-in constants verbatim.
|
||||
p := backend.Config.StakingPolicyAt(chainState.GetTimestamp().Unix())
|
||||
return &addValidatorRules{
|
||||
assetID: backend.Runtime.UTXOAssetID,
|
||||
minValidatorStake: backend.Config.MinValidatorStake,
|
||||
maxValidatorStake: backend.Config.MaxValidatorStake,
|
||||
minStakeDuration: backend.Config.MinStakeDuration,
|
||||
maxStakeDuration: backend.Config.MaxStakeDuration,
|
||||
minDelegationFee: backend.Config.MinDelegationFee,
|
||||
minValidatorStake: p.MinValidatorStake,
|
||||
maxValidatorStake: p.MaxValidatorStake,
|
||||
minStakeDuration: time.Duration(p.MinStakeDuration) * time.Second,
|
||||
maxStakeDuration: time.Duration(p.MaxStakeDuration) * time.Second,
|
||||
minDelegationFee: p.MinDelegationFee,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -69,12 +73,17 @@ func getDelegatorRules(
|
||||
netID ids.ID,
|
||||
) (*addDelegatorRules, error) {
|
||||
if netID == constants.PrimaryNetworkID {
|
||||
p := backend.Config.StakingPolicyAt(chainState.GetTimestamp().Unix())
|
||||
return &addDelegatorRules{
|
||||
assetID: backend.Runtime.UTXOAssetID,
|
||||
assetID: backend.Runtime.UTXOAssetID,
|
||||
// MinDelegatorStake is deliberately NOT governed: it is the floor on
|
||||
// who may delegate at all, and delegators are the one constituency
|
||||
// that cannot defend itself by voting, because the vote belongs to
|
||||
// the validator they delegate to.
|
||||
minDelegatorStake: backend.Config.MinDelegatorStake,
|
||||
maxValidatorStake: backend.Config.MaxValidatorStake,
|
||||
minStakeDuration: backend.Config.MinStakeDuration,
|
||||
maxStakeDuration: backend.Config.MaxStakeDuration,
|
||||
maxValidatorStake: p.MaxValidatorStake,
|
||||
minStakeDuration: time.Duration(p.MinStakeDuration) * time.Second,
|
||||
maxStakeDuration: time.Duration(p.MaxStakeDuration) * time.Second,
|
||||
maxValidatorWeightFactor: MaxValidatorWeightFactor,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
// Copyright (C) 2019-2026, Lux Industries Inc. All rights reserved.
|
||||
// See the file LICENSE for licensing terms.
|
||||
|
||||
package platformvm
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/luxfi/ids"
|
||||
)
|
||||
|
||||
// Measured mainnet (96369) state, read from
|
||||
// platform.getCurrentValidators on https://api.lux.network/v1/bc/P.
|
||||
// All five validators share startTime; endTime differs only by 90-minute
|
||||
// staggers, so the first to mature bounds the whole set.
|
||||
const (
|
||||
mainnetValidatorStart = int64(1_765_573_611) // 2025-12-12T21:06:51Z
|
||||
mainnetValidatorEnd = int64(1_797_088_011) // 2026-12-12T15:06:51Z, first to mature
|
||||
mainnetObservedNow = int64(1_785_183_540) // 2026-07-27T20:19:00Z, when uptime read 0.0000
|
||||
|
||||
// mainnetUptimeRequirement is genesis.MainnetParams.UptimeRequirement, the
|
||||
// bar prefersCommit compares against for a primary-network staker.
|
||||
mainnetUptimeRequirement = 0.8
|
||||
|
||||
// mainnetPotentialRewardTotal is the sum of potentialReward across the five
|
||||
// validators, in nLUX. This is the number at stake in this test.
|
||||
mainnetPotentialRewardTotal = uint64(165_583_347_962_466_973)
|
||||
)
|
||||
|
||||
// mainnetTracker builds the real uptimeTracker in the state mainnet is actually
|
||||
// in: tracking started, the validator's peer connection was never delivered to
|
||||
// the VM, so every flush advanced lastUpdated to now while upDuration stayed 0.
|
||||
//
|
||||
// That is not a hypothesis. calculateUptimeLocked's "tracking, but not
|
||||
// connected" branch returns (upDuration, now) — it moves the clock forward
|
||||
// WITHOUT crediting the interval — so each pass permanently discards the time
|
||||
// since the previous pass. It is the mechanism by which observed uptime is
|
||||
// pinned at zero and, crucially, by which the discarded time cannot be
|
||||
// recovered later.
|
||||
func mainnetTracker(t *testing.T) (*uptimeTracker, ids.NodeID, ids.ID, *int64) {
|
||||
t.Helper()
|
||||
|
||||
state := newFakeUptimeState()
|
||||
netID := ids.GenerateTestID()
|
||||
nodeID := ids.GenerateTestNodeID()
|
||||
state.addValidator(nodeID, netID, time.Unix(mainnetValidatorStart, 0))
|
||||
|
||||
clock := mainnetValidatorStart
|
||||
tracker := newUptimeTracker(state, netID, func() time.Time { return time.Unix(clock, 0) })
|
||||
|
||||
// Tracking begins at bond time; the node never registers as connected.
|
||||
require.NoError(t, tracker.StartTracking([]ids.NodeID{nodeID}))
|
||||
|
||||
return tracker, nodeID, netID, &clock
|
||||
}
|
||||
|
||||
// TestMainnetUptimeIsZeroAndMatchesLiveAPI reproduces the live reading with
|
||||
// production code. platform.getCurrentValidators reports uptime by calling
|
||||
// CalculateUptimePercentFrom(nodeID, netID, staker.StartTime) and scaling by
|
||||
// 100 (service.go), and block/executor's prefersCommit gates the reward by
|
||||
// calling the SAME function with the SAME arguments.
|
||||
//
|
||||
// So the 0.0000 on the API is not a display artifact of a reporting path. It is
|
||||
// the reward decision, printed.
|
||||
func TestMainnetUptimeIsZeroAndMatchesLiveAPI(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
tracker, nodeID, netID, clock := mainnetTracker(t)
|
||||
*clock = mainnetObservedNow
|
||||
|
||||
pct, err := tracker.CalculateUptimePercentFrom(nodeID, netID, time.Unix(mainnetValidatorStart, 0))
|
||||
require.NoError(err)
|
||||
|
||||
require.Equal(0.0, pct, "must reproduce the 0.0000 reported by the live mainnet API")
|
||||
require.Less(pct, mainnetUptimeRequirement, "and therefore fail the 80%% reward gate")
|
||||
}
|
||||
|
||||
// TestMainnetRewardIsUnrecoverableEvenIfFixedToday is the consequence the owner
|
||||
// needs before enabling any uptime-based penalty.
|
||||
//
|
||||
// CalculateUptimePercentFrom divides accrued up-duration by (now - StartTime) —
|
||||
// the FULL bond, not the window since a fix. 227 of the 365 staked days have
|
||||
// already elapsed with zero credited. Even if peer connectivity started
|
||||
// accruing perfectly from this instant and never dropped again, the arithmetic
|
||||
// ceiling at maturity is upDuration/(end-start) = 138/365 = 37.8%.
|
||||
//
|
||||
// 37.8% < 80%. Every honest node therefore prefers ABORT, the reward UTXO is
|
||||
// never created, and current supply is reduced by the same amount.
|
||||
func TestMainnetRewardIsUnrecoverableEvenIfFixedToday(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
tracker, nodeID, netID, clock := mainnetTracker(t)
|
||||
|
||||
// A perfect fix lands right now: the peer connects and never drops.
|
||||
*clock = mainnetObservedNow
|
||||
tracker.Connect(nodeID)
|
||||
require.True(tracker.IsConnected(nodeID))
|
||||
|
||||
// Run the bond out to maturity with unbroken connectivity.
|
||||
*clock = mainnetValidatorEnd
|
||||
|
||||
pct, err := tracker.CalculateUptimePercentFrom(nodeID, netID, time.Unix(mainnetValidatorStart, 0))
|
||||
require.NoError(err)
|
||||
|
||||
t.Logf("best achievable uptime at maturity if fixed today: %.4f (required %.4f)",
|
||||
pct, mainnetUptimeRequirement)
|
||||
require.InDelta(0.3777, pct, 0.001)
|
||||
|
||||
// This is the exact comparison block/executor prefersCommit performs.
|
||||
prefersCommit := pct >= mainnetUptimeRequirement
|
||||
require.False(prefersCommit,
|
||||
"the reward proposal is ABORTED: %d nLUX (%.2f LUX) of rewards across the five "+
|
||||
"validators are forfeited and burned from current supply",
|
||||
mainnetPotentialRewardTotal, float64(mainnetPotentialRewardTotal)/1e9)
|
||||
}
|
||||
|
||||
// TestMainnetForfeitureDeadlineHasPassed dates the point of no return: the last
|
||||
// instant at which a perfect fix could still have reached 80% by maturity.
|
||||
// Reporting "uptime is broken, fix it" without this date invites a fix that
|
||||
// arrives and changes nothing.
|
||||
func TestMainnetForfeitureDeadlineHasPassed(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
bond := mainnetValidatorEnd - mainnetValidatorStart
|
||||
// Need upDuration >= 0.8*bond, and a fix at time f yields end-f, so the
|
||||
// latest viable fix is at end - 0.8*bond.
|
||||
deadline := mainnetValidatorEnd - int64(mainnetUptimeRequirement*float64(bond))
|
||||
|
||||
t.Logf("bond %0.2f days; latest viable fix %s; observed %s; missed by %.0f days",
|
||||
float64(bond)/86400,
|
||||
time.Unix(deadline, 0).UTC().Format(time.RFC3339),
|
||||
time.Unix(mainnetObservedNow, 0).UTC().Format(time.RFC3339),
|
||||
float64(mainnetObservedNow-deadline)/86400)
|
||||
|
||||
require.Greater(mainnetObservedNow, deadline,
|
||||
"if this ever fails, a fix can still save the reward and the deadline math must be redone")
|
||||
|
||||
// Verify the deadline is exact by driving the real tracker from it.
|
||||
tracker, nodeID, netID, clock := mainnetTracker(t)
|
||||
*clock = deadline
|
||||
tracker.Connect(nodeID)
|
||||
*clock = mainnetValidatorEnd
|
||||
|
||||
pct, err := tracker.CalculateUptimePercentFrom(nodeID, netID, time.Unix(mainnetValidatorStart, 0))
|
||||
require.NoError(err)
|
||||
require.InDelta(mainnetUptimeRequirement, pct, 0.0001,
|
||||
"a fix exactly at the deadline lands exactly on the bar")
|
||||
}
|
||||
|
||||
// TestMainnetStakeIsRefundedOnAbort bounds the blast radius, and it is the half
|
||||
// of the story that keeps this a serious problem rather than a catastrophic
|
||||
// one.
|
||||
//
|
||||
// proposal_tx_executor.go rewardValidatorTx adds the stake UTXO to BOTH
|
||||
// onCommitState and onAbortState, and adds the reward UTXO to onCommitState
|
||||
// only. An uptime failure therefore forfeits the REWARD and returns the STAKE.
|
||||
//
|
||||
// The P-Chain has no stake slashing at all: there is no slash state transition
|
||||
// anywhere in vms/platformvm outside a GPU plugin ABI declaration. Reward
|
||||
// forfeiture is the only economic penalty that exists today.
|
||||
func TestMainnetStakeIsRefundedOnAbort(t *testing.T) {
|
||||
require := require.New(t)
|
||||
|
||||
const (
|
||||
stakePerValidator = uint64(500_000_000_000_000_000) // measured "weight", nLUX
|
||||
validators = 5
|
||||
)
|
||||
totalStake := stakePerValidator * validators
|
||||
|
||||
require.Equal(uint64(2_500_000_000_000_000_000), totalStake)
|
||||
t.Logf("at risk on an uptime abort: %.2f LUX of rewards", float64(mainnetPotentialRewardTotal)/1e9)
|
||||
t.Logf("NOT at risk (refunded on both commit and abort): %.2f LUX of stake", float64(totalStake)/1e9)
|
||||
|
||||
// The rewards are ~6.6% of the bonded stake — a year's emission, not the principal.
|
||||
ratio := float64(mainnetPotentialRewardTotal) / float64(totalStake)
|
||||
require.InDelta(0.0662, ratio, 0.001)
|
||||
}
|
||||
Reference in New Issue
Block a user