diff --git a/clients/consensus/chainspec.go b/clients/consensus/chainspec.go index e5d39142..43311d65 100644 --- a/clients/consensus/chainspec.go +++ b/clients/consensus/chainspec.go @@ -51,6 +51,11 @@ type ChainSpec struct { SyncCommitteeSize uint64 `yaml:"SYNC_COMMITTEE_SIZE"` DepositContractAddress []byte `yaml:"DEPOSIT_CONTRACT_ADDRESS"` + // EIP7594: PeerDAS + NumberOfColumns *uint64 `yaml:"NUMBER_OF_COLUMNS"` + DataColumnSidecarSubnetCount *uint64 `yaml:"DATA_COLUMN_SIDECAR_SUBNET_COUNT"` + CustodyRequirement *uint64 `yaml:"CUSTODY_REQUIREMENT"` + // additional dora specific specs WhiskForkEpoch *uint64 } diff --git a/clients/consensus/rpc/beaconapi.go b/clients/consensus/rpc/beaconapi.go index 1be7a0d2..a4ef43d0 100644 --- a/clients/consensus/rpc/beaconapi.go +++ b/clients/consensus/rpc/beaconapi.go @@ -467,7 +467,16 @@ func (bc *BeaconClient) GetNodePeers(ctx context.Context) ([]*v1.Peer, error) { if err != nil { return nil, err } - return result.Data, nil + + // Temporary workaround to filter out peers that are not connected (https://github.com/grandinetech/grandine/issues/46) + filteredPeers := make([]*v1.Peer, 0) + for _, peer := range result.Data { + if peer.State == "connected" { + filteredPeers = append(filteredPeers, peer) + } + } + + return filteredPeers, nil } func (bc *BeaconClient) GetNodeIdentity(ctx context.Context) (*NodeIdentity, error) { diff --git a/go.mod b/go.mod index 1b0fb071..77cd58ac 100644 --- a/go.mod +++ b/go.mod @@ -30,12 +30,41 @@ require ( github.com/timandy/routine v1.1.4 github.com/urfave/negroni v1.0.0 golang.org/x/crypto v0.27.0 - golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 golang.org/x/text v0.18.0 golang.org/x/time v0.6.0 gopkg.in/yaml.v3 v3.0.1 ) +require ( + github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/ipfs/go-cid v0.4.1 // indirect + github.com/libp2p/go-buffer-pool v0.1.0 // indirect + github.com/libp2p/go-libp2p v0.36.3 // indirect + github.com/libp2p/go-libp2p-core v0.0.1 // indirect + github.com/libp2p/go-libp2p-crypto v0.1.0 // indirect + github.com/minio/highwayhash v1.0.2 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.2.0 // indirect + github.com/multiformats/go-multiaddr v0.13.0 // indirect + github.com/multiformats/go-multibase v0.2.0 // indirect + github.com/multiformats/go-multicodec v0.9.0 // indirect + github.com/multiformats/go-multihash v0.2.3 // indirect + github.com/multiformats/go-varint v0.0.7 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/prysmaticlabs/fastssz v0.0.0-20240620202422-a981b8ef89d3 // indirect + github.com/prysmaticlabs/gohashtree v0.0.4-beta.0.20240624100937-73632381301b // indirect + github.com/prysmaticlabs/prysm/v3 v3.2.2 // indirect + github.com/prysmaticlabs/prysm/v5 v5.1.0 // indirect + github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a // indirect + github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect + github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e // indirect + lukechampine.com/blake3 v1.3.0 // indirect +) + require ( dario.cat/mergo v1.0.1 // indirect github.com/Masterminds/goutils v1.1.1 // indirect @@ -91,7 +120,7 @@ require ( github.com/pkg/errors v0.9.1 // indirect github.com/prometheus/client_golang v1.19.1 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.54.0 // indirect + github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/r3labs/sse/v2 v2.10.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect @@ -100,7 +129,7 @@ require ( github.com/shopspring/decimal v1.4.0 // indirect github.com/spf13/cast v1.7.0 // indirect github.com/supranational/blst v0.3.12 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/tdewolff/parse v2.3.4+incompatible // indirect github.com/tdewolff/test v1.0.9 // indirect github.com/tklauser/go-sysconf v0.3.14 // indirect diff --git a/go.sum b/go.sum index 5dd2d869..857844c7 100644 --- a/go.sum +++ b/go.sum @@ -16,19 +16,34 @@ github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERo github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/attestantio/go-eth2-client v0.0.0-20240701211822-0a60485fce68 h1:7WPMn57cFdqlpYRwbEmMdHFXdwu9GVethzEXheTcIpk= +github.com/attestantio/go-eth2-client v0.0.0-20240701211822-0a60485fce68/go.mod h1:vy5jU/uDZ2+RcVzq5BfnG+bQ3/6uu9DGwCrGsPtjJ1A= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4YnC6+E63dPcxHo2sUxDIu8g3QgEJdRY= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32 h1:qkOC5Gd33k54tobS36cXdAzJbeHaduLtnLQQwNoIi78= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +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/snappy-go v0.0.0-20151229074030-0bdef8d06723/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/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= @@ -49,6 +64,7 @@ github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJ github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/coocood/freecache v1.2.4 h1:UdR6Yz/X1HW4fZOuH0Z94KwG851GWOSknua5VUbb/5M= github.com/coocood/freecache v1.2.4/go.mod h1:RBUWa/Cy+OHdfTGFEhEuE1pMCMX51Ncizj7rthiQ3vk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= @@ -59,6 +75,7 @@ github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJ github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +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= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -88,6 +105,7 @@ github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHk 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= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= @@ -108,15 +126,22 @@ 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-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-playground/validator/v10 v10.11.1 h1:prmOlTVv+YjZjmRmNSF3VmspqJIxJWXmqUsHwfTRRkQ= +github.com/go-playground/validator/v10 v10.13.0 h1:cFRQdfaSMCOSfGCCLB20MHvuoHb/s5G8L5pu2ppK5AQ= github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/goccy/go-yaml v1.11.3 h1:B3W9IdWbvrUu2OYQGwvU1nZtvMQJPBKgBUuweJjLj6I= github.com/goccy/go-yaml v1.11.3/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -124,6 +149,7 @@ github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= @@ -135,18 +161,23 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 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/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 h1:FKHo8hFI3A+7w0aUQuYXQ+6EN5stWmeY/AZqtM8xk9k= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= @@ -155,6 +186,8 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= @@ -177,6 +210,10 @@ github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= +github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -231,15 +268,21 @@ github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= 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/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/juliangruber/go-intersect v1.1.0 h1:sc+y5dCjMMx0pAdYk/N6KBm00tD/f3tq+Iox7dYDUrY= github.com/juliangruber/go-intersect v1.1.0/go.mod h1:WMau+1kAmnlQnKiikekNJbtGtfmILU/mMU6H7AgKbWQ= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4= github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= @@ -261,12 +304,23 @@ github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7 github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= +github.com/leodido/go-urn v1.2.3 h1:6BE2vPT0lqoz3fmOesHZiaiFh7889ssCo2GMvLCfiuA= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= +github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p v0.36.3 h1:NHz30+G7D8Y8YmznrVZZla0ofVANrvBl2c+oARfMeDQ= +github.com/libp2p/go-libp2p v0.36.3/go.mod h1:4Y5vFyCUiJuluEPmpnKYf6WFx5ViKPUYs/ixe9ANFZ8= +github.com/libp2p/go-libp2p-core v0.0.1 h1:HSTZtFIq/W5Ue43Zw+uWZyy2Vl5WtF0zDjKN8/DT/1I= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-crypto v0.1.0 h1:k9MFy+o2zGDNGsaoZl0MA3iZ75qXxr9OOoAZF+sD5OQ= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= github.com/lightclient/go-ethereum v0.0.0-20240907155054-183e7b702a00 h1:6fd42xMvs6JF4vN0SBB7bI1ILR4wHl53dn89YNsdpWY= github.com/lightclient/go-ethereum v0.0.0-20240907155054-183e7b702a00/go.mod h1:QeW+MtTpRdBEm2pUFoonByee8zfHv7kGp0wK0odvU1I= github.com/mashingan/smapping v0.1.19 h1:SsEtuPn2UcM1croIupPtGLgWgpYRuS0rSQMvKD9g2BQ= @@ -288,6 +342,10 @@ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= +github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= 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/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= @@ -301,6 +359,30 @@ github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= +github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= +github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= +github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= +github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= +github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= +github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= +github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +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/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -309,14 +391,22 @@ github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+ github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= 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= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE= github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= +github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= +github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= github.com/pk910/dynamic-ssz v0.0.5 h1:VP9heGYUwzlpyhk28P2nCAzhvGsePJOOOO5vQMDh2qQ= github.com/pk910/dynamic-ssz v0.0.5/go.mod h1:b6CrLaB2X7pYA+OSEEbkgXDEcRnjLOZIxZTsMuO/Y9c= github.com/pk910/go-eth2-client v0.0.0-20240828114153-a531e55c7857 h1:VkZSvS91epV5aIBOr4o/x/R6HGSHZ1f741UHogzULF4= @@ -334,6 +424,8 @@ github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.54.0 h1:ZlZy0BgJhTwVZUn7dLOkwCZHUkrAqd3WYtcFCWnM1D8= github.com/prometheus/common v0.54.0/go.mod h1:/TQgMJP5CuVYveyT7n/0Ix8yLNNXy9yRSkhnLTHPDIQ= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/protolambda/bls12-381-util v0.1.0 h1:05DU2wJN7DTU7z28+Q+zejXkIsA/MF8JZQGhtBZZiWk= @@ -342,14 +434,28 @@ github.com/protolambda/zrnt v0.32.3 h1:b3mkBEjcmxtft115cBIQk+2qz1HEb2ExDdduVQqN4 github.com/protolambda/zrnt v0.32.3/go.mod h1:A0fezkp9Tt3GBLATSPIbuY4ywYESyAuc/FFmPKg8Lqs= github.com/protolambda/ztyp v0.2.2 h1:rVcL3vBu9W/aV646zF6caLS/dyn9BN8NYiuJzicLNyY= github.com/protolambda/ztyp v0.2.2/go.mod h1:9bYgKGqg3wJqT9ac1gI2hnVb0STQq7p/1lapqrqY1dU= +github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab h1:Y3PcvUrnneMWLuypZpwPz8P70/DQsz6KgV9JveKpyZs= +github.com/prysmaticlabs/fastssz v0.0.0-20220628121656-93dfe28febab/go.mod h1:MA5zShstUwCQaE9faGHgCGvEWUbG87p4SAXINhmCkvg= +github.com/prysmaticlabs/fastssz v0.0.0-20240620202422-a981b8ef89d3 h1:0LZAwwHnsZFfXm4IK4rzFV4N5IVSKZKLmuBMA4kAlFk= +github.com/prysmaticlabs/fastssz v0.0.0-20240620202422-a981b8ef89d3/go.mod h1:h2OlIZD/M6wFvV3YMZbW16lFgh3Rsye00G44J2cwLyU= github.com/prysmaticlabs/go-bitfield v0.0.0-20240618144021-706c95b2dd15 h1:lC8kiphgdOBTcbTvo8MwkvpKjO0SlAgjv4xIK5FGJ94= github.com/prysmaticlabs/go-bitfield v0.0.0-20240618144021-706c95b2dd15/go.mod h1:8svFBIKKu31YriBG/pNizo9N0Jr9i5PQ+dFkxWg3x5k= +github.com/prysmaticlabs/gohashtree v0.0.2-alpha h1:hk5ZsDQuSkyUMhTd55qB396P1+dtyIKiSwMmYE/hyEU= +github.com/prysmaticlabs/gohashtree v0.0.2-alpha/go.mod h1:4pWaT30XoEx1j8KNJf3TV+E3mQkaufn7mf+jRNb/Fuk= +github.com/prysmaticlabs/gohashtree v0.0.4-beta.0.20240624100937-73632381301b h1:VK7thFOnhxAZ/5aolr5Os4beiubuD08WiuiHyRqgwks= +github.com/prysmaticlabs/gohashtree v0.0.4-beta.0.20240624100937-73632381301b/go.mod h1:HRuvtXLZ4WkaB1MItToVH2e8ZwKwZPY5/Rcby+CvvLY= +github.com/prysmaticlabs/prysm/v3 v3.2.2 h1:8lC6vX4F/gVPVOrOZ49SkHjxZIpl0XLziIvlFKdyLwA= +github.com/prysmaticlabs/prysm/v3 v3.2.2/go.mod h1:tk/LvCJpiq/EpMPkSJwE0OYBLnXOiMktEN+Xt1IIKkE= +github.com/prysmaticlabs/prysm/v5 v5.1.0 h1:TY9A6tm0v7bI1z9YH+xkDh7XH7qm4ZK8sTeyckxbj4A= +github.com/prysmaticlabs/prysm/v5 v5.1.0/go.mod h1:SWb5kE/FhtQrLS2yt+IDj+leB7IhXrcOv6lhDnU1nBY= github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0= github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.3.4 h1:3Z3Eu6FGHZWSfNKJTOUiPatWwfc7DzJRU04jFUqJODw= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= @@ -376,6 +482,12 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a h1:/eS3yfGjQKG+9kayBkj0ip1BGhq6zJ3eaVksphxAaek= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 h1:RC6RW7j+1+HkWaX/Yh71Ee5ZHaHYt7ZP4sQgUrm6cDU= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= +github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= @@ -391,6 +503,7 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= @@ -399,12 +512,16 @@ github.com/supranational/blst v0.3.12 h1:Vfas2U2CFHhniv2QkUm2OVa1+pGTdqtpqm9NnhU github.com/supranational/blst v0.3.12/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tdewolff/minify v2.3.6+incompatible h1:2hw5/9ZvxhWLvBUnHE06gElGYz+Jv9R4Eys0XUzItYo= github.com/tdewolff/minify v2.3.6+incompatible/go.mod h1:9Ov578KJUmAWpS6NeZwRZyT56Uf6o3Mcz9CEsg8USYs= github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxpP46ghf0Qzh38= github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ= github.com/tdewolff/test v1.0.9 h1:SswqJCmeN4B+9gEAi/5uqT0qpi1y2/2O47V/1hhGZT0= github.com/tdewolff/test v1.0.9/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= +github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e h1:cR8/SYRgyQCt5cNCMniB/ZScMkhI9nk8U5C7SbISXjo= +github.com/thomaso-mirodin/intmath v0.0.0-20160323211736-5dc6d854e46e/go.mod h1:Tu4lItkATkonrYuvtVjG0/rhy15qrNGNTjPdaphtZ/8= github.com/timandy/routine v1.1.4 h1:L9eAli/ROJcW6LhmwZcusYQcdAqxAXGOQhEXLQSNWOA= github.com/timandy/routine v1.1.4/go.mod h1:siBcl8iIsGmhLCajRGRcy7Y7FVcicNXkr97JODdt9fc= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= @@ -417,10 +534,13 @@ github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10 h1:CQh github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod h1:x/Pa0FF5Te9kdrlZKJK82YmAkvL8+f989USgz6Jiw7M= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/urfave/cli/v2 v2.26.0 h1:3f3AMg3HpThFNT4I++TKOejZO8yU55t3JnnSr4S4QEI= github.com/urfave/negroni v1.0.0 h1:kIimOitoypq34K7TG7DUaJ9kq/N4Ofuwi1sjz0KipXc= github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +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.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= @@ -444,6 +564,9 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -460,22 +583,32 @@ golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY= golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 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= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= @@ -484,6 +617,8 @@ golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= 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= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -491,7 +626,9 @@ golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -502,14 +639,20 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -543,6 +686,7 @@ golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.6.0 h1:eTDhh4ZXt5Qf0augr54TN6suAUudPcawVZeIAPU7D4U= golang.org/x/time v0.6.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -552,16 +696,21 @@ golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 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= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -570,6 +719,8 @@ google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/Knetic/govaluate.v3 v3.0.0 h1:18mUyIt4ZlRlFZAAfVetz4/rzlJs9yhN+U02F4u1AOc= @@ -587,6 +738,7 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST 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/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= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -596,6 +748,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= +lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= modernc.org/cc/v4 v4.21.4 h1:3Be/Rdo1fpr8GrQ7IVw9OHtplU4gWbb+wNgeoBMmGLQ= modernc.org/cc/v4 v4.21.4/go.mod h1:HM7VJTZbUCR3rV8EYBi9wxnJ0ZBRiGE5OeGXNA0IsLQ= modernc.org/ccgo/v4 v4.19.2 h1:lwQZgvboKD0jBwdaeVCTouxhxAyN6iawF3STraAal8Y= diff --git a/handlers/clients_cl.go b/handlers/clients_cl.go index ca007760..6ddb45b9 100644 --- a/handlers/clients_cl.go +++ b/handlers/clients_cl.go @@ -4,6 +4,7 @@ import ( "fmt" "net/http" "sort" + "strconv" "strings" "time" @@ -141,11 +142,21 @@ func buildCLClientsPageData() (*models.ClientsCLPageData, time.Duration) { Clients: []*models.ClientsCLPageDataClient{}, PeerMap: buildCLPeerMapData(), ShowSensitivePeerInfos: utils.Config.Frontend.ShowSensitivePeerInfos, + ShowPeerDASInfos: utils.Config.Frontend.ShowPeerDASInfos, + PeerDASInfos: &models.ClientCLPagePeerDAS{ + Warnings: models.ClientCLPageDataPeerDASWarnings{ + MissingENRsPeers: []string{}, + MissingCSCFromENRPeers: []string{}, + EmptyColumns: []uint64{}, + }, + }, + Nodes: make(map[string]*models.ClientCLNode), } chainState := services.GlobalBeaconService.GetChainState() var cacheTime time.Duration - if specs := chainState.GetSpecs(); specs != nil { + specs := chainState.GetSpecs() + if specs != nil { cacheTime = specs.SecondsPerSlot } else { cacheTime = 1 * time.Second @@ -163,6 +174,21 @@ func buildCLClientsPageData() (*models.ClientsCLPageData, time.Duration) { for _, client := range services.GlobalBeaconService.GetConsensusClients() { lastHeadSlot, lastHeadRoot := client.GetLastHead() + id := client.GetNodeIdentity() + if id == nil { + continue + } + + // Add client to global nodes map + if _, ok := pageData.Nodes[id.PeerID]; !ok { + pageData.Nodes[id.PeerID] = &models.ClientCLNode{ + PeerID: id.PeerID, + Alias: client.GetName(), + Type: "internal", + ENR: id.Enr, + } + } + peers := client.GetNodePeers() resPeers := []*models.ClientCLPageDataClientPeers{} @@ -175,17 +201,14 @@ func buildCLClientsPageData() (*models.ClientsCLPageData, time.Duration) { peerType = "internal" } - enrKeyValues := map[string]interface{}{} - var nodeID string - - if peer.Enr != "" { // Some clients might not announce the ENR of their peers - parsedEnr, err := utils.DecodeENR(peer.Enr) + peerENRKeyValues := map[string]interface{}{} + if peer.Enr != "" { + rec, err := utils.DecodeENR(peer.Enr) if err != nil { - logrus.WithFields(logrus.Fields{"client": client.GetName(), "peer_enr": peer.Enr}).Error("failed to decode peer enr. ", err) - parsedEnr = &enr.Record{} + logrus.WithFields(logrus.Fields{"node": client.GetName(), "peer": peer.PeerID, "enr": peer.Enr}).Error("failed to decode peer enr. ", err) + rec = &enr.Record{} } - enrKeyValues = utils.GetKeyValuesFromENR(parsedEnr) - nodeID = utils.GetNodeIDFromENR(parsedEnr) + peerENRKeyValues = utils.GetKeyValuesFromENR(rec) } resPeers = append(resPeers, &models.ClientCLPageDataClientPeers{ @@ -195,17 +218,48 @@ func buildCLClientsPageData() (*models.ClientsCLPageData, time.Duration) { Alias: peerAlias, Type: peerType, ENR: peer.Enr, - ENRKeyValues: enrKeyValues, - NodeID: nodeID, + ENRKeyValues: peerENRKeyValues, LastSeenP2PAddress: peer.LastSeenP2PAddress, }) + // Add peer to global nodes map + _, ok := pageData.Nodes[peer.PeerID] + if !ok { + pageData.Nodes[peer.PeerID] = &models.ClientCLNode{ + PeerID: peer.PeerID, + Alias: peerAlias, + Type: peerType, + ENR: peer.Enr, + } + } + + node := pageData.Nodes[peer.PeerID] + if node.ENR == "" && peer.Enr != "" { + node.ENR = peer.Enr + } else if node.ENR != "" && peer.Enr != "" { + // Need to compare `seq` field from ENRs and only store highest + nodeENR, errA := utils.DecodeENR(node.ENR) + if errA != nil { + logrus.WithFields(logrus.Fields{"node": node.Alias, "enr": node.ENR}).Error("failed to decode enr of a node ", errA) + } + peerENR, errB := utils.DecodeENR(peer.Enr) + if errB != nil { + logrus.WithFields(logrus.Fields{"node": node.Alias, "peer": peer.PeerID, "enr": peer.Enr}).Error("failed to decode enr of a peer ", errB) + } + if errA == nil && errB == nil && peerENR.Seq() > nodeENR.Seq() { + node.ENR = peer.Enr // peerENR has higher sequence number, so override. + } + } + + // Increase peer direction counter if peer.Direction == "inbound" { inPeerCount++ } else { outPeerCount++ } } + + // Sort peers by type and alias sort.Slice(resPeers, func(i, j int) bool { if resPeers[i].Type == resPeers[j].Type { return resPeers[i].Alias < resPeers[j].Alias @@ -213,21 +267,6 @@ func buildCLClientsPageData() (*models.ClientsCLPageData, time.Duration) { return resPeers[i].Type > resPeers[j].Type }) - id := client.GetNodeIdentity() - if id == nil { - continue - } - - rec, err := utils.DecodeENR(id.Enr) - if err != nil { - logrus.WithFields(logrus.Fields{"client": client.GetName(), "enr": id.Enr}).Error("failed to decode enr. ", err) - rec = &enr.Record{} - } - - enrkv := utils.GetKeyValuesFromENR(rec) - - nodeID := utils.GetNodeIDFromENR(rec) - resClient := &models.ClientsCLPageDataClient{ Index: int(client.GetIndex()) + 1, Name: client.GetName(), @@ -235,8 +274,6 @@ func buildCLClientsPageData() (*models.ClientsCLPageData, time.Duration) { Peers: resPeers, PeerID: id.PeerID, ENR: id.Enr, - ENRKeyValues: enrkv, - NodeID: nodeID, P2PAddresses: id.P2PAddresses, DisoveryAddresses: id.DiscoveryAddresses, AttestationSubnetSubs: id.Metadata.Attnets, @@ -258,5 +295,157 @@ func buildCLClientsPageData() (*models.ClientsCLPageData, time.Duration) { } pageData.ClientCount = uint64(len(pageData.Clients)) + // Add peer in/out infos to global nodes map + for _, edge := range pageData.PeerMap.ClientDataMapEdges { + pageData.Nodes[edge.From].PeersOut = append(pageData.Nodes[edge.From].PeersOut, edge.To) + pageData.Nodes[edge.To].PeersIn = append(pageData.Nodes[edge.To].PeersIn, edge.From) + } + + columnDistribution := make(map[uint64]map[string]bool) + resultColumnDistribution := make(map[uint64][]string) + + // Verify and parse PeerDAS spec config + if specs != nil { + if specs.NumberOfColumns != nil { + pageData.PeerDASInfos.NumberOfColumns = *specs.NumberOfColumns + } else { + pageData.PeerDASInfos.NumberOfColumns = 128 + logrus.Warnf("NUMBER_OF_COLUMNS is not defined in spec, defaulting to %d", pageData.PeerDASInfos.NumberOfColumns) + pageData.PeerDASInfos.Warnings.MissingSpecValues = true + pageData.PeerDASInfos.Warnings.HasWarnings = true + } + + if specs.DataColumnSidecarSubnetCount != nil { + pageData.PeerDASInfos.DataColumnSidecarSubnetCount = *specs.DataColumnSidecarSubnetCount + } else { + pageData.PeerDASInfos.DataColumnSidecarSubnetCount = 128 + logrus.Warnf("DATA_COLUMN_SIDECAR_SUBNET_COUNT is not defined in spec, defaulting to %d", pageData.PeerDASInfos.DataColumnSidecarSubnetCount) + pageData.PeerDASInfos.Warnings.MissingSpecValues = true + pageData.PeerDASInfos.Warnings.HasWarnings = true + } + + if specs.CustodyRequirement != nil { + pageData.PeerDASInfos.CustodyRequirement = *specs.CustodyRequirement + } else { + pageData.PeerDASInfos.CustodyRequirement = 4 + logrus.Warnf("CUSTODY_REQUIREMENT is not defined in spec, defaulting to %d", pageData.PeerDASInfos.CustodyRequirement) + pageData.PeerDASInfos.Warnings.MissingSpecValues = true + pageData.PeerDASInfos.Warnings.HasWarnings = true + } + } + + // Calculate additional fields for nodes: ENR key values, Node ID, Custody Columns, Custody Column Subnets + for _, v := range pageData.Nodes { + + // Calculate K:V pairs for ENR + if v.ENR != "" { + rec, err := utils.DecodeENR(v.ENR) + if err != nil { + logrus.WithFields(logrus.Fields{"node": v.Alias, "enr": v.ENR}).Error("failed to decode enr. ", err) + rec = &enr.Record{} + } + v.ENRKeyValues = utils.GetKeyValuesFromENR(rec) + } else { + pageData.PeerDASInfos.Warnings.MissingENRsPeers = append(pageData.PeerDASInfos.Warnings.MissingENRsPeers, v.PeerID) + pageData.PeerDASInfos.Warnings.HasWarnings = true + } + + // Calculate node ID + nodeID, err := utils.ConvertPeerIDStringToEnodeID(v.PeerID) + if err != nil { + logrus.WithFields(logrus.Fields{"node": v.Alias, "peer_id": v.PeerID}).Error("failed to convert peer id to enode id. ", err) + } + v.NodeID = nodeID.String() + + custodySubnetCount := pageData.PeerDASInfos.CustodyRequirement + + if cscHex, ok := v.ENRKeyValues["csc"]; ok { + val, err := strconv.ParseUint(cscHex.(string), 0, 64) + if err != nil { + logrus.WithFields(logrus.Fields{"node": v.Alias, "peer_id": v.PeerID, "csc": cscHex.(string)}).Error("failed to decode csc. ", err) + } else { + custodySubnetCount = val + } + } else { + pageData.PeerDASInfos.Warnings.MissingCSCFromENRPeers = append(pageData.PeerDASInfos.Warnings.MissingCSCFromENRPeers, v.PeerID) + pageData.PeerDASInfos.Warnings.HasWarnings = true + } + + // Calculate custody columns and subnets for peer DAS + resColumns, err := utils.CustodyColumnsSlice(nodeID, custodySubnetCount, pageData.PeerDASInfos.NumberOfColumns, pageData.PeerDASInfos.DataColumnSidecarSubnetCount) + if err != nil { + logrus.WithFields(logrus.Fields{"node": v.Alias, "node_id": nodeID}).Error("failed to get custody columns. ", err) + } + + resSubnets, err := utils.CustodyColumnSubnetsSlice(nodeID, custodySubnetCount, pageData.PeerDASInfos.DataColumnSidecarSubnetCount) + if err != nil { + logrus.WithFields(logrus.Fields{"client": v.Alias, "node_id": nodeID}).Error("failed to get custody column subnets. ", err) + } + + // Transform the custody columns to a map for easier access + for _, idx := range resColumns { + if _, ok := columnDistribution[idx]; !ok { + columnDistribution[idx] = make(map[string]bool) + } + columnDistribution[idx][v.PeerID] = true + } + + peerDASInfo := models.ClientCLPageDataPeerDAS{ + CustodyColumns: resColumns, + CustodyColumnSubnets: resSubnets, + CustodySubnetCount: custodySubnetCount, + IsSuperNode: uint64(len(resColumns)) == pageData.PeerDASInfos.NumberOfColumns, + } + v.PeerDAS = &peerDASInfo + } + + // Transform the column distribution to a slice + for k, v := range columnDistribution { + for key := range v { + if _, ok := resultColumnDistribution[k]; !ok { + resultColumnDistribution[k] = []string{} + } + resultColumnDistribution[k] = append(resultColumnDistribution[k], key) + } + + // Sort the peer IDs by type and alias + sort.Slice(resultColumnDistribution[k], func(i, j int) bool { + pA := resultColumnDistribution[k][i] + pB := resultColumnDistribution[k][j] + nodeA := pageData.Nodes[pA] + nodeB := pageData.Nodes[pB] + + // Compare supernodes + if nodeA.PeerDAS.IsSuperNode != nodeB.PeerDAS.IsSuperNode { + return nodeA.PeerDAS.IsSuperNode + } + // Compare node types + if nodeA.Type != nodeB.Type { + return nodeA.Type > nodeB.Type + } + + // If types are the same, compare CustodyColumns length + lenA := len(nodeA.PeerDAS.CustodyColumns) + lenB := len(nodeB.PeerDAS.CustodyColumns) + if lenA != lenB { + return lenA > lenB + } + + // If both types and CustodyColumns lengths are the same, compare aliases + return nodeA.Alias < nodeB.Alias + }) + } + + // Check for empty columns + for i := uint64(0); i < pageData.PeerDASInfos.NumberOfColumns; i++ { + if _, ok := resultColumnDistribution[i]; !ok { + pageData.PeerDASInfos.Warnings.EmptyColumns = append(pageData.PeerDASInfos.Warnings.EmptyColumns, i) + pageData.PeerDASInfos.Warnings.HasWarnings = true + } + } + + pageData.PeerDASInfos.TotalRows = int(pageData.PeerDASInfos.NumberOfColumns) / 32 + pageData.PeerDASInfos.ColumnDistribution = resultColumnDistribution + return pageData, cacheTime } diff --git a/static/css/clients.css b/static/css/clients.css index 6c98b7ee..811102c5 100644 --- a/static/css/clients.css +++ b/static/css/clients.css @@ -138,3 +138,59 @@ Client peers table margin-left: -50px; margin-top: -50px; } + +.dastablepeercount { + font-weight:300; + font-size: 0.6rem; + line-height: 0.5rem; + margin-bottom: 2px; +} + +.dastablenode { + cursor: pointer; + max-width: 25px; + margin: 0 auto; + border: 1px solid #cacaca; + -webkit-transition: opacity 0.3s ease; + -moz-transition: opacity 0.3s ease; + -o-transition: opacity 0.3s ease; + transition: opacity 0.3s ease; + width: 17px; + height: 17px; + + border-radius: 0; +} + +.dastablenode.internal { + border-color: #ffa500ab +} + +.dastablenode.external { + border-color: #075e4d +} + +.dastablenode.supernode { + background-color: rgb(0 246 255 / 20%); + border-radius: 0; +} + +.dastablenode.supernode.highlight { + border-width: 1px !important; +} + +.dastablenode.highlight { + opacity: 1 !important; + border: 1px solid yellow !important; +} + +.dastablenode.blur { + opacity: 0.2; +} + +.peerdetails-modal-peer{ + cursor: pointer; +} + +.peerdetails-modal-peer:hover{ + font-weight: 600; +} diff --git a/templates/clients/clients_cl.html b/templates/clients/clients_cl.html index c80acd4e..6b6bd149 100644 --- a/templates/clients/clients_cl.html +++ b/templates/clients/clients_cl.html @@ -1,4 +1,30 @@ {{ define "page" }} + +{{ $root := . }} + + + +

Consensus clients

@@ -25,7 +51,7 @@

-
+
@@ -38,6 +64,181 @@

+ + {{ if $root.ShowPeerDASInfos }} +
+
+
+

+ +

+
+
+
+ {{ if $root.PeerDASInfos.Warnings.HasWarnings }} + + {{ end}} +

+ Spec configuration: + NUMBER_OF_COLUMNS={{ $root.PeerDASInfos.NumberOfColumns}}, + DATA_COLUMN_SIDECAR_SUBNET_COUNT={{ $root.PeerDASInfos.DataColumnSidecarSubnetCount}} + CUSTODY_REQUIREMENT={{ $root.PeerDASInfos.CustodyRequirement}} + Node count: {{ len $root.Nodes }} +

+ + +
+
+ + +
+
+ + +
+
+ + +
+ + {{ range $k, $p := $root.Nodes }} + +

+
+ + + + + {{ range $i := until $root.PeerDASInfos.TotalRows }} +
+ + + + {{ range $j := until 32 }} + {{ $idx := add ($j) (int (mul (float64 $i) (float64 32))) }} + {{ $peersPerColumn := index $root.PeerDASInfos.ColumnDistribution (int64 $idx) }} + {{ $peerCount := len $peersPerColumn }} + + {{ end }} + + + + + {{ range $j := until 32 }} + {{ $idx := add ($j) (int (mul (float64 $i) (float64 32))) }} + {{ $peersPerColumn := index $root.PeerDASInfos.ColumnDistribution (int64 $idx) }} + {{ $peerCount := len $peersPerColumn }} + + {{ end }} + +
+ {{ $idx }} +
({{ $peerCount }})
+
+
+ {{ with $peers := $peersPerColumn }} + {{ range $i, $p := $peers}} + {{ $peerData := index $root.Nodes $p }} + + + {{ end }} + {{ end }} +
+
+
+ {{ end }} +
+
+
+
+
+ {{ end }} +
@@ -61,7 +262,6 @@

- {{ $root := . }} {{ range $i, $client := .Clients }} {{ $client.Index }} @@ -133,14 +333,14 @@

- {{ if $root.ShowSensitivePeerInfos }} Node ID - {{ $client.NodeID }} + {{ (index $root.Nodes $client.PeerID).NodeID }} + {{ if $root.ShowSensitivePeerInfos }} ENR @@ -153,23 +353,49 @@

{{ end }} - {{ if $root.ShowSensitivePeerInfos }} + {{ if $root.ShowSensitivePeerInfos }}
ENR fields
- - - {{ range $k, $v := $client.ENRKeyValues }} - - - - - {{ end }} - -
{{ $k }} - {{ $v }} - -
-

+ + + {{ range $k, $v := (index $root.Nodes $client.PeerID).ENRKeyValues }} + + + + + {{ end }} + +
{{ $k }} + {{ $v }} + +
+ + {{ if $root.ShowPeerDASInfos }} +
Peer DAS
+ + + + + + + + + + + +
Custody columns +
+ {{ (index $root.Nodes $client.PeerID).PeerDAS.CustodyColumns }} + +
+
Custody subnets +
+ {{ (index $root.Nodes $client.PeerID).PeerDAS.CustodyColumnSubnets }} + +
+
{{ end }} + {{ end }} +
Peers
@@ -191,8 +417,28 @@

{{ if $root.ShowSensitivePeerInfos }}
+ {{ $peerENR := (index $root.Nodes $peer.ID).ENR}} + {{ $reportedPeerENR := $peer.ENR}} + {{ if ne $peerENR $reportedPeerENR }} + + {{ end }} + + + + - {{ if ne $peer.ENR "" }} - - - - - {{ range $k, $v := $peer.ENRKeyValues }} + {{ if ne $peerENR "" }} + {{ range $k, $v := (index $root.Nodes $peer.ID).ENRKeyValues }}
Node ID + {{ (index $root.Nodes $peer.ID).NodeID }} + +
P2P Addr @@ -204,20 +450,13 @@

ENR
- {{ if eq $peer.ENR "" }}Unknown{{ else }}{{ $peer.ENR }}{{ end }} - + {{ if eq $peerENR "" }}Unknown{{ else }}{{ $peerENR }}{{ end }} +
Node ID - {{ $peer.NodeID }} - -
{{ $k }} @@ -229,6 +468,31 @@

{{ end }}

+ {{ if $root.ShowPeerDASInfos }} +
Peer DAS
+ + + + + + + + + + + +
Custody columns +
+ {{ (index $root.Nodes $peer.ID).PeerDAS.CustodyColumns }} + +
+
Custody subnets +
+ {{ (index $root.Nodes $peer.ID).PeerDAS.CustodyColumnSubnets }} + +
+
+ {{ end }}
{{ end}} {{ end }} @@ -271,6 +535,224 @@

var container = document.getElementById("nodemap"); var data = {{ .PeerMap }}; var cy = $_network.create(container, data); + + var nodes = {{ .Nodes }}; + + var showPeerDetailsModal = function(peerID){ + jdenticon.update("#peerDetailsModalTitleImage", peerID); + $('#peerDetailsModalTitle').html(`${nodes[peerID].alias}`); + + let peerDetailsTemplate = ` + + + + + + + + + + + + + + `; + + if (nodes[peerID].enr_kv) { + peerDetailsTemplate += ` + + + + ${Object.entries(nodes[peerID].enr_kv).map(([key, value]) => ` + + + + + `).join('')} + `; + } + + peerDetailsTemplate += ` + + + + + + + + + + + + + + + + + + + + + + + `; + + if (nodes[peerID].peers_in != null){ + nodes[peerID].peers_in.forEach(element => { + peerDetailsTemplate += ` + + + `; + }); + } + + if (nodes[peerID].peers_out != null){ + nodes[peerID].peers_out.forEach(element => { + peerDetailsTemplate += ` + + + `; + }); + } + peerDetailsTemplate += `
Peer ID${peerID}
Node ID${nodes[peerID].node_id}
ENR${nodes[peerID].enr?nodes[peerID].enr:"Unknown"}
ENR Fields
${key}${value}
Peer DAS
Supernode${nodes[peerID].peer_das.is_super_node}
CSC${nodes[peerID].peer_das.custody_subnet_count}
Columns${nodes[peerID].peer_das.custody_columns}
Subnets${nodes[peerID].peer_das.custody_column_subnets}
Peers
+ + + + ${element} ${nodes[element].alias!=element?""+nodes[element].alias+"":""} + +
+ + + + ${element} ${nodes[element].alias!=element?""+nodes[element].alias+"":""} + +
`; + + //peerDetailsTemplate += `
${JSON.stringify(nodes[peerID], null, 2)}
`; + $('#peerDetailsModalBody').html(peerDetailsTemplate) + jdenticon.update(".peer-details-jdenticon",null) + $('#peerDetailsModal').modal('show'); + } + + var lastClickedNode = null; + // PeerDASTable toggle external peers button + $('#showExternalPeersDAS').change(function() { + if (this.checked) { + $('.dastablenode.external').show(); + } else { + $('.dastablenode.external').hide(); + } + }); + + // PeerDASTable toggle internal peers button + $('#showInternalPeersDAS').change(function() { + if (this.checked) { + $('.dastablenode.internal').show(); + } else { + $('.dastablenode.internal').hide(); + } + }); + + // PeerDASTable toggle internal peers button + $('#showSupernodePeersDAS').change(function() { + if (this.checked) { + $('.dastablenode.supernode').show(); + } else { + $('.dastablenode.supernode').hide(); + } + }); + + // PeerDASTable Hover + let hoverTimeout; + $('.dastablenode').hover( + function() { + hoverTimeout = setTimeout(() => { + const searchText = $('#searchDASTablePeers').val().trim().toLowerCase(); + + if (!searchText && lastClickedNode == null) { + const $target = $(this); + const selector = $target.attr('class').split(/\s+/).map(cls => cls!=""?'.' + cls:"").join(''); + $(selector).addClass('highlight'); + $('.dastablenode').addClass('blur'); + } + }, 500); //500ms delay before highlighting + }, + function() { + clearTimeout(hoverTimeout); // Clear the timeout if the mouse leaves before 2 seconds + const searchText = $('#searchDASTablePeers').val().trim().toLowerCase(); + + if (!searchText && lastClickedNode == null) { + const $target = $(this); + const selector = $target.attr('class').split(/\s+/).map(cls => cls!=""?'.' + cls:"").join(''); + $(selector).removeClass('highlight'); + $('.dastablenode').removeClass('blur'); + } + } + ); + + // PeerDASTable Click + $('.dastablenode').on('click', function() { + const $target = $(this); + const selector = $target.attr('class').split(/\s+/).map(cls => '.' + cls).join(''); + + const peerID = $target.data('peerid').toString(); + + + showPeerDetailsModal(peerID); + + // Remove highlight/blur from the last clicked node + if (lastClickedNode != null) { + $(lastClickedNode).removeClass('highlight'); + $('.dastablenode').removeClass('blur'); + } + + // Highlight clicked node and blur others + $(selector).addClass('highlight'); + $('.dastablenode').not(selector).addClass('blur'); + + // Store the clicked node + lastClickedNode = selector; + + // Add node to searchtext + $('#searchDASTablePeers').val(nodes[peerID].alias).trigger("input"); + + }); + + // Event listener to remove highlight when clicking outside + $(document).on('click', function(event) { + const searchText = $('#searchDASTablePeers').val().trim().toLowerCase(); + + if (!searchText && !$(event.target).closest('.dastablenode').length) { + // Remove highlight and blur when clicking outside a .dastablenode element + $('.dastablenode').removeClass('highlight blur'); + lastClickedNode = null; + } + }); + + // PeerDASTable search + $('#searchDASTablePeers').on('input', function() { + const searchText = $(this).val().trim().toLowerCase(); + + if (searchText) { + $('.dastablenode').each(function() { + const peerId = $(this).data('peerid').toString().toLowerCase(); + const alias = $(this).data('alias').toString().toLowerCase(); + if (peerId.includes(searchText) || alias.includes(searchText)) { + $(this).addClass('highlight').removeClass('blur'); // Add 'highlight' if matches, remove 'blur' + } else { + $(this).addClass('blur').removeClass('highlight'); // Add 'blur' if doesn't match, remove 'highlight' + } + }); + } else { + $('.dastablenode').removeClass('blur highlight'); // Remove both classes if search text is cleared + } + }); + + // Clear search input + $('#clearSearchButton').click(function(){ + $('#searchDASTablePeers').val(''); // Clear the input + }); + {{ end }} {{ define "css" }} diff --git a/templates/clients/clients_el.html b/templates/clients/clients_el.html index a6b9a4a0..f277d9fb 100644 --- a/templates/clients/clients_el.html +++ b/templates/clients/clients_el.html @@ -25,7 +25,7 @@

-
+
diff --git a/types/config.go b/types/config.go index 557e9484..39b11c04 100644 --- a/types/config.go +++ b/types/config.go @@ -49,6 +49,7 @@ type Config struct { AllowDutyLoading bool `yaml:"allowDutyLoading" envconfig:"FRONTEND_ALLOW_DUTY_LOADING"` ShowSensitivePeerInfos bool `yaml:"showSensitivePeerInfos" envconfig:"FRONTEND_SHOW_SENSITIVE_PEER_INFOS"` + ShowPeerDASInfos bool `yaml:"showPeerDASInfos" envconfig:"FRONTEND_SHOW_PEER_DAS_INFOS"` } `yaml:"frontend"` RateLimit struct { diff --git a/types/models/clients_cl.go b/types/models/clients_cl.go index ef37bc28..54f17608 100644 --- a/types/models/clients_cl.go +++ b/types/models/clients_cl.go @@ -10,8 +10,12 @@ type ClientsCLPageData struct { ClientCount uint64 `json:"client_count"` PeerMap *ClientCLPageDataPeerMap `json:"peer_map"` ShowSensitivePeerInfos bool `json:"show_sensitive_peer_infos"` + ShowPeerDASInfos bool `json:"show_peer_das_infos"` + PeerDASInfos *ClientCLPagePeerDAS `json:"peer_das"` + Nodes map[string]*ClientCLNode `json:"nodes"` } +// ClientsCLPageDataClient represents a configured endpoint CL client type ClientsCLPageDataClient struct { Index int `json:"index"` Name string `json:"name"` @@ -31,24 +35,51 @@ type ClientsCLPageDataClient struct { Peers []*ClientCLPageDataClientPeers `json:"peers"` PeersInboundCounter uint32 `json:"peers_inbound_counter"` PeersOutboundCounter uint32 `json:"peers_outbound_counter"` + PeerDAS ClientCLPageDataPeerDAS `json:"peer_das"` } +type ClientCLPageDataPeerDAS struct { + CustodyColumns []uint64 `json:"custody_columns"` + CustodyColumnSubnets []uint64 `json:"custody_column_subnets"` + CustodySubnetCount uint64 `json:"custody_subnet_count"` + IsSuperNode bool `json:"is_super_node"` +} + +type ClientCLPageDataPeerDASWarnings struct { + HasWarnings bool `json:"has_warnings"` + // MissingENRs indicates that the client is missing ENRs for some peers + MissingENRs bool `json:"missing_enrs"` + MissingENRsPeers []string `json:"missing_enrs_peers"` + // MissingCSCFromENR indicates that the client is missing the CSC from the ENR for some peers + MissingCSCFromENR bool `json:"missing_csc_from_enr"` + MissingCSCFromENRPeers []string `json:"missing_csc_from_enr_peers"` + // MissingSpecValues indicates that wer were unable to parse the spec values, thus using defaults + MissingSpecValues bool `json:"missing_spec_values"` + // MissingPeersOnColum + EmptyColumns []uint64 `json:"missing_peers_on_column"` +} + +// ClientCLPageDataClientPeers represents the peers of a client type ClientCLPageDataClientPeers struct { - ID string `json:"id"` - Alias string `json:"alias"` - Type string `json:"type"` - State string `json:"state"` - Direction string `json:"direction"` - ENR string `json:"enr"` - ENRKeyValues map[string]interface{} `json:"enr_kv"` - NodeID string `json:"node_id"` - LastSeenP2PAddress string `json:"last_seen_p2p_address"` + ID string `json:"id"` + Alias string `json:"alias"` + Type string `json:"type"` + State string `json:"state"` + Direction string `json:"direction"` + ENR string `json:"enr"` + ENRKeyValues map[string]interface{} `json:"enr_kv"` + NodeID string `json:"node_id"` + LastSeenP2PAddress string `json:"last_seen_p2p_address"` + PeerDAS ClientCLPageDataPeerDAS `json:"peer_das"` } + +// ClientCLPageDataPeerMap represents the data required to draw the network graph type ClientCLPageDataPeerMap struct { ClientPageDataMapNode []*ClientCLPageDataPeerMapNode `json:"nodes"` ClientDataMapEdges []*ClientCLDataMapPeerMapEdge `json:"edges"` } +// ClientCLPageDataPeerMapNode represents a node in the peer graph type ClientCLPageDataPeerMapNode struct { ID string `json:"id"` Label string `json:"label"` @@ -57,8 +88,42 @@ type ClientCLPageDataPeerMapNode struct { Value int `json:"value"` } +// ClientCLDataMapPeerMapEdge represents an edge in the peer graph type ClientCLDataMapPeerMapEdge struct { From string `json:"from"` To string `json:"to"` Interaction string `json:"interaction"` } + +// ClientCLPagePeerDAS represents the DAS information from all clients and peers. +// Used to construct the PeerDAS column custody view. +type ClientCLPagePeerDAS struct { + ColumnDistribution map[uint64][]string `json:"column_distribution"` // Column index -> list of peer IDs // Peer ID -> Peer info + TotalRows int `json:"total_rows"` // Amount of rows to show on the webpage. Each row has 32 columns + NumberOfColumns uint64 `json:"number_of_columns"` // Should match NUMBER_OF_COLUMNS from spec + CustodyRequirement uint64 `json:"custody_requirement"` // Should match CUSTODY_REQUIREMENT from spec + DataColumnSidecarSubnetCount uint64 `json:"data_column_sidecar_subnet_count"` // Should match DATA_COLUMN_SIDECAR_SUBNET_COUNT from spec + Warnings ClientCLPageDataPeerDASWarnings `json:"warnings"` +} + +type ClientCLPagePeerDASPeerInfo struct { + PeerID string `json:"peer_id"` + NodeID string `json:"node_id"` + CSC uint64 `json:"csc"` + Columns []uint64 `json:"columns"` + Subnets []uint64 `json:"subnets"` +} + +// ClientCLNode represents a generic node on the CL network. Can be a client or a peer of a client +// This is useful to generate a generic view of all nodes we know about in the network. +type ClientCLNode struct { + PeerID string `json:"peer_id"` + NodeID string `json:"node_id"` + Type string `json:"type"` // "internal" or "external" . internal nodes are clients, external nodes are peers of clients + Alias string `json:"alias"` // only relevent for internal peers (clients) + ENR string `json:"enr"` + ENRKeyValues map[string]interface{} `json:"enr_kv"` + PeerDAS *ClientCLPageDataPeerDAS `json:"peer_das"` + PeersIn []string `json:"peers_in"` + PeersOut []string `json:"peers_out"` +} diff --git a/utils/enr.go b/utils/enr.go index fabbabcb..70bb037c 100644 --- a/utils/enr.go +++ b/utils/enr.go @@ -4,12 +4,16 @@ import ( "bytes" "encoding/base64" "encoding/hex" + "errors" "net" "strconv" + ethcrypto "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/p2p/enr" "github.com/ethereum/go-ethereum/rlp" + libp2pCrypto "github.com/libp2p/go-libp2p/core/crypto" + libp2pPeer "github.com/libp2p/go-libp2p/core/peer" ) func DecodeENR(raw string) (*enr.Record, error) { @@ -60,12 +64,12 @@ func GetKeyValuesFromENR(r *enr.Record) map[string]interface{} { return fields } -func GetNodeIDFromENR(r *enr.Record) string { +func GetNodeIDFromENR(r *enr.Record) enode.ID { n, err := enode.New(enode.ValidSchemes, r) if err != nil { - return "" + return enode.ID{} } - return n.ID().String() + return n.ID() } // attrFormatters contains formatting functions for well-known ENR keys. @@ -104,3 +108,40 @@ func formatAttrUint(v rlp.RawValue) (string, bool) { } return strconv.FormatUint(x, 10), true } + +// ConvertPeerIDStringToEnodeID converts a libp2p peer ID string to an enode.ID. +func ConvertPeerIDStringToEnodeID(pidStr string) (enode.ID, error) { + // Decode the string into a peer.ID. + pid, err := libp2pPeer.Decode(pidStr) + if err != nil { + return enode.ID{}, err + } + + // Extract the public key from the peer ID. + pubKey, err := pid.ExtractPublicKey() + if err != nil { + return enode.ID{}, err + } + + // Ensure the public key is of type secp256k1. + if pubKey.Type() != libp2pCrypto.Secp256k1 { + return enode.ID{}, errors.New("public key is not secp256k1") + } + + // Get the raw bytes of the public key (compressed format). + pubKeyBytes, err := pubKey.Raw() + if err != nil { + return enode.ID{}, err + } + + // Decompress the public key using Ethereum's crypto library. + ecdsaPubKey, err := ethcrypto.DecompressPubkey(pubKeyBytes) + if err != nil { + return enode.ID{}, err + } + + // Compute the enode.ID from the ECDSA public key. + id := enode.PubkeyToIDV4(ecdsaPubKey) + + return id, nil +} diff --git a/utils/peerdas.go b/utils/peerdas.go new file mode 100644 index 00000000..9414c469 --- /dev/null +++ b/utils/peerdas.go @@ -0,0 +1,117 @@ +package utils + +import ( + "encoding/binary" + "math" + "sort" + + "github.com/ethereum/go-ethereum/p2p/enode" + "github.com/holiman/uint256" + errors "github.com/pkg/errors" + "github.com/prysmaticlabs/prysm/v5/crypto/hash" + "github.com/prysmaticlabs/prysm/v5/encoding/bytesutil" +) + +// Mainly from: prysm/beacon-chain/core/peerdas/helpers.go + +var ( + // Custom errors + errCustodySubnetCountTooLarge = errors.New("custody subnet count larger than data column sidecar subnet count") + + // maxUint256 is the maximum value of a uint256. + maxUint256 = &uint256.Int{math.MaxUint64, math.MaxUint64, math.MaxUint64, math.MaxUint64} +) + +func CustodyColumnSubnets(nodeId enode.ID, custodySubnetCount uint64, dataColumnSidecarSubnetCount uint64) (map[uint64]bool, error) { + // Check if the custody subnet count is larger than the data column sidecar subnet count. + if custodySubnetCount > dataColumnSidecarSubnetCount { + return nil, errCustodySubnetCountTooLarge + } + + // First, compute the subnet IDs that the node should participate in. + subnetIds := make(map[uint64]bool, custodySubnetCount) + + one := uint256.NewInt(1) + + for currentId := new(uint256.Int).SetBytes(nodeId.Bytes()); uint64(len(subnetIds)) < custodySubnetCount; currentId.Add(currentId, one) { + // Convert to big endian bytes. + currentIdBytesBigEndian := currentId.Bytes32() + + // Convert to little endian. + currentIdBytesLittleEndian := bytesutil.ReverseByteOrder(currentIdBytesBigEndian[:]) + + // Hash the result. + hashedCurrentId := hash.Hash(currentIdBytesLittleEndian) + + // Get the subnet ID. + subnetId := binary.LittleEndian.Uint64(hashedCurrentId[:8]) % dataColumnSidecarSubnetCount + + // Add the subnet to the map. + subnetIds[subnetId] = true + + // Overflow prevention. + if currentId.Cmp(maxUint256) == 0 { + currentId = uint256.NewInt(0) + } + } + + return subnetIds, nil +} + +// CustodyColumns computes the columns the node should custody. +// https://github.com/ethereum/consensus-specs/blob/dev/specs/_features/eip7594/das-core.md#helper-functions +func CustodyColumns(nodeId enode.ID, custodySubnetCount uint64, numberOfColumns uint64, dataColumnSidecarSubnetCount uint64) (map[uint64]bool, error) { + + // Compute the custodied subnets. + subnetIds, err := CustodyColumnSubnets(nodeId, custodySubnetCount, dataColumnSidecarSubnetCount) + if err != nil { + return nil, errors.Wrap(err, "custody subnets") + } + + columnsPerSubnet := numberOfColumns / dataColumnSidecarSubnetCount + + // Knowing the subnet ID and the number of columns per subnet, select all the columns the node should custody. + // Columns belonging to the same subnet are contiguous. + columnIndices := make(map[uint64]bool, custodySubnetCount*columnsPerSubnet) + for i := uint64(0); i < columnsPerSubnet; i++ { + for subnetId := range subnetIds { + columnIndex := dataColumnSidecarSubnetCount*i + subnetId + columnIndices[columnIndex] = true + } + } + + return columnIndices, nil +} + +func CustodyColumnsSlice(nodeId enode.ID, custodySubnetCount uint64, numberOfColumns uint64, dataColumnSidecarSubnetCount uint64) ([]uint64, error) { + columns, err := CustodyColumns(nodeId, custodySubnetCount, numberOfColumns, dataColumnSidecarSubnetCount) + if err != nil { + return nil, err + } + columnsSlice := make([]uint64, 0, len(columns)) + for column := range columns { + columnsSlice = append(columnsSlice, column) + } + + sort.Slice(columnsSlice, func(i, j int) bool { + return columnsSlice[i] < columnsSlice[j] + }) + + return columnsSlice, nil +} + +func CustodyColumnSubnetsSlice(nodeId enode.ID, custodySubnetCount uint64, dataColumnSidecarSubnetCount uint64) ([]uint64, error) { + subnets, err := CustodyColumnSubnets(nodeId, custodySubnetCount, dataColumnSidecarSubnetCount) + if err != nil { + return nil, err + } + subnetsSlice := make([]uint64, 0, len(subnets)) + for subnet := range subnets { + subnetsSlice = append(subnetsSlice, subnet) + } + sort.Slice(subnetsSlice, func(i, j int) bool { + return subnetsSlice[i] < subnetsSlice[j] + }) + + return subnetsSlice, nil +}