diff --git a/.gitignore b/.gitignore index 82db215..bcfeaee 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ ethereum-metrics-exporter -test_config.yaml \ No newline at end of file +test_config.yaml +config.yaml \ No newline at end of file diff --git a/go.mod b/go.mod index 9caa043..6ae7c07 100644 --- a/go.mod +++ b/go.mod @@ -2,26 +2,31 @@ module github.com/ethpandaops/ethereum-metrics-exporter go 1.17 -// replace github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter => ./pkg/ethereum-metrics-exporter - require ( + github.com/attestantio/go-eth2-client v0.11.7 + github.com/ethereum/go-ethereum v1.10.17 + github.com/nats-io/nats-server/v2 v2.8.4 + github.com/nats-io/nats.go v1.16.0 + github.com/onrik/ethrpc v1.0.0 + github.com/prometheus/client_golang v1.13.0 + github.com/rs/zerolog v1.27.0 + github.com/samcm/beacon v0.10.0 + github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.4.0 - gopkg.in/yaml.v3 v3.0.1 + gopkg.in/yaml.v2 v2.4.0 ) require ( github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 // indirect - github.com/attestantio/go-eth2-client v0.11.3 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/btcsuite/btcd/btcec/v2 v2.1.2 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 // indirect github.com/deckarep/golang-set v1.8.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect - github.com/ethereum/go-ethereum v1.10.17 // indirect github.com/fatih/color v1.13.0 // indirect github.com/ferranbt/fastssz v0.0.0-20220103083642-bc5fefefa28b // indirect - github.com/go-co-op/gocron v1.15.0 // indirect + github.com/go-co-op/gocron v1.16.2 // indirect github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-stack/stack v1.8.0 // indirect github.com/goccy/go-yaml v1.9.5 // indirect @@ -32,9 +37,9 @@ require ( github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect + github.com/jarcoal/httpmock v1.2.0 // indirect github.com/klauspost/compress v1.14.4 // indirect github.com/klauspost/cpuid/v2 v2.0.11 // indirect - github.com/kr/pretty v0.2.1 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect @@ -42,36 +47,29 @@ require ( github.com/minio/sha256-simd v1.0.0 // indirect github.com/mitchellh/mapstructure v1.4.3 // indirect github.com/nats-io/jwt/v2 v2.2.1-0.20220330180145-442af02fd36a // indirect - github.com/nats-io/nats-server/v2 v2.8.4 // indirect - github.com/nats-io/nats.go v1.16.0 // indirect github.com/nats-io/nkeys v0.3.0 // indirect github.com/nats-io/nuid v1.0.1 // indirect - github.com/onrik/ethrpc v1.0.0 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.12.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect + github.com/prometheus/common v0.37.0 // indirect + github.com/prometheus/procfs v0.8.0 // indirect github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 // indirect github.com/r3labs/sse/v2 v2.7.4 // indirect github.com/robfig/cron/v3 v3.0.1 // indirect - github.com/rs/zerolog v1.26.1 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect - github.com/sirupsen/logrus v1.8.1 // indirect - github.com/spf13/cast v1.4.1 // indirect + github.com/spf13/cast v1.5.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect + github.com/tidwall/gjson v1.14.4 // indirect github.com/tklauser/go-sysconf v0.3.5 // indirect github.com/tklauser/numcpus v0.2.2 // indirect golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect - golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect - golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect - golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect + golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect + golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f // indirect + golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8 // indirect golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11 // indirect golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - google.golang.org/protobuf v1.26.0 // indirect + google.golang.org/protobuf v1.28.1 // indirect gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect - gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 256ff7a..9892b37 100644 --- a/go.sum +++ b/go.sum @@ -44,6 +44,7 @@ github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= +github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= @@ -54,8 +55,8 @@ github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk5 github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= -github.com/attestantio/go-eth2-client v0.11.3 h1:jP8W6P1TwLlE3B8jY7Tp+5tVIKHks0Nql/xmnUB+1VQ= -github.com/attestantio/go-eth2-client v0.11.3/go.mod h1:zXL/BxC0cBBhxj+tP7QG7t9Ufoa8GwQLdlbvZRd9+dM= +github.com/attestantio/go-eth2-client v0.11.7 h1:mRCtVZYg/Tmp47mNkWKnro/Wj63+jj1vz9BWNQN8MYo= +github.com/attestantio/go-eth2-client v0.11.7/go.mod h1:zXL/BxC0cBBhxj+tP7QG7t9Ufoa8GwQLdlbvZRd9+dM= github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= github.com/aws/aws-sdk-go-v2/credentials v1.1.1/go.mod h1:mM2iIjwl7LULWtS6JCACyInboHirisUUdkBPoTHMOUo= @@ -73,6 +74,7 @@ github.com/bmizerany/pat v0.0.0-20170815010413-6226ea591a40/go.mod h1:8rLXio+Wji github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/btcsuite/btcd/btcec/v2 v2.1.2 h1:YoYoC9J0jwfukodSBMzZYUVQ8PTiYg4BnOWiJVzTmLs= github.com/btcsuite/btcd/btcec/v2 v2.1.2/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0 h1:MSskdM4/xJYcFzy0altH/C/xHopifpWzHUi1JeVI34Q= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -82,6 +84,8 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9 h1:xz6Nv3zcwO2Lila35hcb0QloCQsc38Al13RNEzWRpX4= +github.com/chuckpreslar/emission v0.0.0-20170206194824-a7ddd980baf9/go.mod h1:2wSM9zJkl1UQEFZgSd68NfCgRz1VL1jzy/RjCg+ULrs= 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= @@ -91,6 +95,7 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/consensys/bavard v0.1.8-0.20210406032232-f3452dc9b572/go.mod h1:Bpd0/3mZuaj6Sj+PqrmIquiOKy397AKGThQPaGzNXAQ= github.com/consensys/gnark-crypto v0.4.1-0.20210426202927-39ac3d4b3f1f/go.mod h1:815PAHg3wvysy0SyIqanF8gZ0Y1wjk/hrDHD/iT88+Q= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -101,6 +106,7 @@ 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= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= @@ -116,6 +122,7 @@ github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= +github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -129,10 +136,15 @@ github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/ferranbt/fastssz v0.0.0-20220103083642-bc5fefefa28b h1:Jea4sHxe4sTegJgpfhWvxSjFF2nyq4/R/qWm6AziPiI= github.com/ferranbt/fastssz v0.0.0-20220103083642-bc5fefefa28b/go.mod h1:S8yiDeAXy8f88W4Ul+0dBMPx49S05byYbmZD6Uv94K4= +github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= +github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= @@ -140,24 +152,29 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/glycerine/go-unsnap-stream v0.0.0-20180323001048-9f0cb55181dd/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE= github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24= github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= -github.com/go-co-op/gocron v1.15.0 h1:XmiPazahD9aq0/QdK5toCVHfgTXfrZ/s83RpAgzr6SM= -github.com/go-co-op/gocron v1.15.0/go.mod h1:On9zUZTv7FBeuj9D/cdYyAWcPUiLqqAx7nsPHd0EmKM= +github.com/go-co-op/gocron v1.16.2 h1:p9ghzsN5PqqPyWXYDO2JlvD1DOUNT8pPSyGYC62XBcY= +github.com/go-co-op/gocron v1.16.2/go.mod h1:W/N9G7bntRo5fVQlmjncvqSt74jxCxHfjyHlgcB33T8= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +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/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/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-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -169,6 +186,7 @@ github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5x github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog= github.com/golang-jwt/jwt/v4 v4.3.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= @@ -217,6 +235,9 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/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.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -229,6 +250,7 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -237,12 +259,15 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +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 v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d h1:dg1dEPuWpEqDnvIw251EVy4zlP8gWbsGj4BsUKCRpYs= github.com/hashicorp/golang-lru v0.5.5-0.20210104140557-80c98217689d/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huin/goupnp v1.0.3-0.20220313090229-ca81a64b4204 h1:+EYBkW+dbi3F/atB+LSQZSWh7+HNrV3A/N0y6DSoy9k= @@ -264,6 +289,8 @@ github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mq github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= 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/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc= +github.com/jarcoal/httpmock v1.2.0/go.mod h1:oCoTsnAz4+UoOUIf5lJOWV2QQIW5UoeUI6aM2YnWAZk= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= @@ -286,6 +313,7 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.14.4 h1:eijASRJcobkVtSt81Olfh7JX43osYLwy5krOJo6YEu4= github.com/klauspost/compress v1.14.4/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5 h1:2U0HzY8BJ8hVwDKIzp7y4voR9CX/nvcfymLmg2UiOio= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.11 h1:i2lw1Pm7Yi/4O6XCSyJWqEHI2MDw2FzUK6o/D21xn2A= @@ -296,12 +324,11 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -309,6 +336,7 @@ github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+ github.com/labstack/echo/v4 v4.2.1/go.mod h1:AA49e0DZ8kk5jTOOCKNuPR6oTnBS0dYiM4FW1e6jwpg= github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= 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/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -328,11 +356,13 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/maxatome/go-testdeep v1.11.0/go.mod h1:011SgQ6efzZYAen6fDn4BqQ+lUR72ysdyKe7Dyogw70= 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.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= @@ -342,6 +372,7 @@ github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.3 h1:OVowDSCllw/YjdLkam3/sm7wEtOy59d8ndGgCcyj8cs= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -358,21 +389,26 @@ github.com/nats-io/jwt/v2 v2.2.1-0.20220330180145-442af02fd36a h1:lem6QCvxR0Y28g github.com/nats-io/jwt/v2 v2.2.1-0.20220330180145-442af02fd36a/go.mod h1:0tqz9Hlu6bCBFLWAASKhE5vUA4c24L9KPUUgvwumE/k= github.com/nats-io/nats-server/v2 v2.8.4 h1:0jQzze1T9mECg8YZEl8+WYUXb9JKluJfCBriPUtluB4= github.com/nats-io/nats-server/v2 v2.8.4/go.mod h1:8zZa+Al3WsESfmgSs98Fi06dRWLH5Bnq90m5bKD/eT4= +github.com/nats-io/nats.go v1.15.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= github.com/nats-io/nats.go v1.16.0 h1:zvLE7fGBQYW6MWaFaRdsgm9qT39PJDQoju+DS8KsO1g= github.com/nats-io/nats.go v1.16.0/go.mod h1:BPko4oXsySz4aSWeFgOHLZs3G4Jq4ZAyE6/zMCxRT6w= github.com/nats-io/nkeys v0.3.0 h1:cgM5tL53EvYRU+2YLXIK0G2mJtK12Ft9oeooSZMA2G8= github.com/nats-io/nkeys v0.3.0/go.mod h1:gvUNGjVcM2IPr5rCsRsC6Wb3Hr2CQAm08dsxtV6A5y4= github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +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/onrik/ethrpc v1.0.0 h1:caG0U/Y1op32mntqmDnwvzue4Tg37cSA2EU8PMIMSjM= github.com/onrik/ethrpc v1.0.0/go.mod h1:RoqOlDiBBs1qYamkcYhxMgkPijxu5R8t55mgUiy4le8= github.com/onsi/ginkgo v1.6.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 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -387,13 +423,15 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/term v0.0.0-20180730021639-bffc007b7fd5/go.mod h1:eCbImbZ95eXtAUIbLAuAVnBnwf83mjf6QIVH8SHYwqQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -404,32 +442,40 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= +github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4= github.com/r3labs/sse/v2 v2.7.4 h1:pvCMswPDlXd/ZUFx1dry0LbXJNHXwWPulLcUGYwClc0= github.com/r3labs/sse/v2 v2.7.4/go.mod h1:hUrYMKfu9WquG9MyI0r6TKiNH+6Sw/QPKm2YbNbU5g8= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= -github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285 h1:d54EL9l+XteliUfUCGsEwwuk65dmmxX85VXF+9T6+50= -github.com/ricochet2200/go-disk-usage/du v0.0.0-20210707232629-ac9918953285/go.mod h1:fxIDly1xtudczrZeOOlfaUvd2OPb2qZAPuWdU2BsBTk= +github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs= github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.26.1 h1:/ihwxqH+4z8UxyI70wM1z9yCvkWcfz/a3mj48k/Zngc= github.com/rs/zerolog v1.26.1/go.mod h1:/wSSJWX7lVrsOwlbyTRSOJvqRlc+WjWlfes+CiJ+tmc= +github.com/rs/zerolog v1.27.0 h1:1T7qCieN22GVc8S4Q2yuexzBb1EqjbgjSH9RohbMjKs= +github.com/rs/zerolog v1.27.0/go.mod h1:7frBqO0oezxmnO7GF86FY++uy8I0Tk/If5ni1G9Qc0U= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/samcm/beacon v0.10.0 h1:kGx0wLydiyH44jHHHoJVZav9P1P/QMm0k2awZwzUZ7A= +github.com/samcm/beacon v0.10.0/go.mod h1:PHKxsJH6MOc4f8xUGOkDfGPIe8jqOjMaIN1hST3faWw= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -439,36 +485,48 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.4.0 h1:y+wJpx64xcgO1V+RcnwW0LEHxTKRi2ZDPSBjWnrg88Q= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 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.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= 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/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM= +github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= +github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef h1:wHSqTBrZW24CsNJDfeh9Ex6Pm0Rcpc7qrgKBiL44vF4= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= @@ -500,7 +558,6 @@ golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e h1:1SzTfNOXwIS2oWiMF+6qu0OUDKb0dauo6MoDUQyu+yU= golang.org/x/crypto v0.0.0-20211215165025-cf75a172585e/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38= golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -579,14 +636,17 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -597,8 +657,9 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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= @@ -659,9 +720,12 @@ golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/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-20220111092808-5a964db01320/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/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 h1:0A+M6Uqn+Eje4kHMK80dtF3JCXC4ykBgQG4Fe06QRhQ= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= 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= @@ -673,6 +737,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -815,14 +880,14 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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= @@ -831,7 +896,9 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= +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/urfave/cli.v1 v1.20.0 h1:NdAVW6RYxDif9DhDHaAortIu956m2c0v+09AZBPTbE0= gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= 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= @@ -843,10 +910,10 @@ gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 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.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/exporter/consensus/api/api.go b/pkg/exporter/consensus/api/api.go deleted file mode 100644 index f2dd5d5..0000000 --- a/pkg/exporter/consensus/api/api.go +++ /dev/null @@ -1,143 +0,0 @@ -package api - -import ( - "bytes" - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "time" - - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/api/types" - "github.com/sirupsen/logrus" -) - -// ConsensusClient is an interface for executing RPC calls to the Ethereum node. -type ConsensusClient interface { - NodePeer(ctx context.Context, peerID string) (types.Peer, error) - NodePeers(ctx context.Context) (types.Peers, error) - NodePeerCount(ctx context.Context) (types.PeerCount, error) -} - -type consensusClient struct { - url string - log logrus.FieldLogger - client http.Client -} - -// NewConsensusClient creates a new ConsensusClient. -func NewConsensusClient(ctx context.Context, log logrus.FieldLogger, url string) ConsensusClient { - client := http.Client{ - Timeout: time.Second * 10, - } - - return &consensusClient{ - url: url, - log: log, - client: client, - } -} - -type apiResponse struct { - Data json.RawMessage `json:"data"` -} - -//nolint:unparam // ctx will probably be used in the future -func (c *consensusClient) post(ctx context.Context, path string, body map[string]interface{}) (json.RawMessage, error) { - jsonData, err := json.Marshal(body) - if err != nil { - return nil, err - } - - rsp, err := c.client.Post(c.url, "application/json", bytes.NewBuffer(jsonData)) - if err != nil { - return nil, err - } - - defer rsp.Body.Close() - - if rsp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("status code: %d", rsp.StatusCode) - } - - data, err := io.ReadAll(rsp.Body) - if err != nil { - return nil, err - } - - resp := new(apiResponse) - if err := json.Unmarshal(data, resp); err != nil { - return nil, err - } - - return resp.Data, nil -} - -//nolint:unparam // ctx will probably be used in the future -func (c *consensusClient) get(ctx context.Context, path string) (json.RawMessage, error) { - rsp, err := c.client.Get(c.url + path) - if err != nil { - return nil, err - } - - defer rsp.Body.Close() - - if rsp.StatusCode != http.StatusOK { - return nil, fmt.Errorf("status code: %d", rsp.StatusCode) - } - - data, err := io.ReadAll(rsp.Body) - if err != nil { - return nil, err - } - - resp := new(apiResponse) - if err := json.Unmarshal(data, resp); err != nil { - return nil, err - } - - return resp.Data, nil -} - -func (c *consensusClient) NodePeers(ctx context.Context) (types.Peers, error) { - data, err := c.get(ctx, "/eth/v1/node/peers") - if err != nil { - return nil, err - } - - rsp := types.Peers{} - if err := json.Unmarshal(data, &rsp); err != nil { - return nil, err - } - - return rsp, nil -} - -func (c *consensusClient) NodePeer(ctx context.Context, peerID string) (types.Peer, error) { - data, err := c.get(ctx, fmt.Sprintf("/eth/v1/node/peers/%s", peerID)) - if err != nil { - return types.Peer{}, err - } - - rsp := types.Peer{} - if err := json.Unmarshal(data, &rsp); err != nil { - return types.Peer{}, err - } - - return rsp, nil -} - -func (c *consensusClient) NodePeerCount(ctx context.Context) (types.PeerCount, error) { - data, err := c.get(ctx, "/eth/v1/node/peer_count") - if err != nil { - return types.PeerCount{}, err - } - - rsp := types.PeerCount{} - if err := json.Unmarshal(data, &rsp); err != nil { - return types.PeerCount{}, err - } - - return rsp, nil -} diff --git a/pkg/exporter/consensus/api/types/agents.go b/pkg/exporter/consensus/api/types/agents.go deleted file mode 100644 index 3d3e981..0000000 --- a/pkg/exporter/consensus/api/types/agents.go +++ /dev/null @@ -1,60 +0,0 @@ -package types - -import ( - "strings" -) - -type Agent string - -const ( - AgentUnknown Agent = "unknown" - AgentLighthouse Agent = "lighthouse" - AgentNimbus Agent = "nimbus" - AgentTeku Agent = "teku" - AgentPrysm Agent = "prysm" - AgentLodestar Agent = "lodestar" -) - -var AllAgents = []Agent{ - AgentUnknown, - AgentLighthouse, - AgentNimbus, - AgentTeku, - AgentPrysm, - AgentLodestar, -} - -type AgentCount struct { - Unknown int `json:"unknown"` - Lighthouse int `json:"lighthouse"` - Nimbus int `json:"nimbus"` - Teku int `json:"teku"` - Prysm int `json:"prysm"` - Lodestar int `json:"lodestar"` -} - -func AgentFromString(agent string) Agent { - asLower := strings.ToLower(agent) - - if strings.Contains(asLower, "lighthouse") { - return AgentLighthouse - } - - if strings.Contains(asLower, "nimbus") { - return AgentNimbus - } - - if strings.Contains(asLower, "teku") { - return AgentTeku - } - - if strings.Contains(asLower, "prysm") { - return AgentPrysm - } - - if strings.Contains(asLower, "lodestar") { - return AgentLodestar - } - - return AgentUnknown -} diff --git a/pkg/exporter/consensus/api/types/agents_test.go b/pkg/exporter/consensus/api/types/agents_test.go deleted file mode 100644 index 26f2a32..0000000 --- a/pkg/exporter/consensus/api/types/agents_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package types - -import "testing" - -func TestAgentParsing(t *testing.T) { - t.Parallel() - - tests := []struct { - input string - expect Agent - }{ - {"Prysm/v2.0.2/4a4a7e97dfd2285a5e48a178f693d870e9a4ff60", AgentPrysm}, - {"Lighthouse/v3.1.0-aa022f4/x86_64-linux", AgentLighthouse}, - {"nimbus", AgentNimbus}, - {"teku/teku/v22.9.0/linux-x86_64/-privatebuild-openjdk64bitservervm-java-17", AgentTeku}, - {"Lodestar/v0.32.0-rc.0-1-gc3b5b6a9/linux-x64/nodejs", AgentLodestar}, - } - - for _, test := range tests { - t.Run(test.input, func(t *testing.T) { - t.Parallel() - if actual := AgentFromString(test.input); actual != test.expect { - t.Errorf("Expected %s, got %s", test.expect, actual) - } - }) - } -} diff --git a/pkg/exporter/consensus/api/types/peer.go b/pkg/exporter/consensus/api/types/peer.go deleted file mode 100644 index 08a7129..0000000 --- a/pkg/exporter/consensus/api/types/peer.go +++ /dev/null @@ -1,108 +0,0 @@ -package types - -var PeerStates = []string{ - "disconnected", - "connected", - "connecting", - "disconnecting", -} - -var PeerDirections = []string{ - "inbound", - "outbound", -} - -type Peer struct { - PeerID string `json:"peer_id"` - ENR string `json:"enr"` - LastSeenP2PAddress string `json:"last_seen_p2p_address"` - State string `json:"state"` - Direction string `json:"direction"` - Agent string `json:"agent"` -} - -func (p *Peer) DeriveAgent() Agent { - return AgentFromString(p.Agent) -} - -type Peers []Peer - -type PeerCount struct { - Disconnected string `json:"disconnected"` - Connected string `json:"connected"` - Connecting string `json:"connecting"` - Disconnecting string `json:"disconnecting"` -} - -func (p *Peers) ByState(state string) Peers { - var peers []Peer - - for _, peer := range *p { - if peer.State == state { - peers = append(peers, peer) - } - } - - return peers -} - -func (p *Peers) ByDirection(direction string) Peers { - var peers []Peer - - for _, peer := range *p { - if peer.Direction == direction { - peers = append(peers, peer) - } - } - - return peers -} - -func (p *Peers) ByStateAndDirection(state, direction string) Peers { - var peers []Peer - - for _, peer := range *p { - if peer.State == state && peer.Direction == direction { - peers = append(peers, peer) - } - } - - return peers -} - -func (p *Peers) ByAgent(agent Agent) Peers { - var peers []Peer - - for _, peer := range *p { - if peer.DeriveAgent() == agent { - peers = append(peers, peer) - } - } - - return peers -} - -func (p *Peers) AgentCount() AgentCount { - count := AgentCount{} - - for _, agent := range AllAgents { - numberOfAgents := len(p.ByAgent(agent)) - - switch agent { - case AgentUnknown: - count.Unknown = numberOfAgents - case AgentLighthouse: - count.Lighthouse = numberOfAgents - case AgentNimbus: - count.Nimbus = numberOfAgents - case AgentTeku: - count.Teku = numberOfAgents - case AgentPrysm: - count.Prysm = numberOfAgents - case AgentLodestar: - count.Lodestar = numberOfAgents - } - } - - return count -} diff --git a/pkg/exporter/consensus/beacon/beacon.go b/pkg/exporter/consensus/beacon/beacon.go deleted file mode 100644 index e54b7fd..0000000 --- a/pkg/exporter/consensus/beacon/beacon.go +++ /dev/null @@ -1,460 +0,0 @@ -package beacon - -import ( - "context" - "errors" - "fmt" - "time" - - eth2client "github.com/attestantio/go-eth2-client" - v1 "github.com/attestantio/go-eth2-client/api/v1" - "github.com/attestantio/go-eth2-client/spec" - "github.com/attestantio/go-eth2-client/spec/phase0" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/api" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/api/types" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon/state" - "github.com/go-co-op/gocron" - "github.com/nats-io/nats.go" - "github.com/sirupsen/logrus" -) - -type Node interface { - // Lifecycle - // Start starts the node. - Start(ctx context.Context) error - // StartAsync starts the node asynchronously. - StartAsync(ctx context.Context) - - // Getters - // GetEpoch returns the epoch for the given epoch. - GetEpoch(ctx context.Context, epoch phase0.Epoch) (*state.Epoch, error) - // GetSlot returns the slot for the given slot. - GetSlot(ctx context.Context, slot phase0.Slot) (*state.Slot, error) - // GetSpec returns the spec for the node. - GetSpec(ctx context.Context) (*state.Spec, error) - // GetSyncState returns the sync state for the node. - GetSyncState(ctx context.Context) (*v1.SyncState, error) - // GetGenesis returns the genesis for the node. - GetGenesis(ctx context.Context) (*v1.Genesis, error) - // GetNodeVersion returns the node version. - GetNodeVersion(ctx context.Context) (string, error) - - // Subscriptions - // - Proxied Beacon events - // OnEvent is called when a beacon event is received. - OnEvent(ctx context.Context, handler func(ctx context.Context, ev *v1.Event) error) (*nats.Subscription, error) - // OnBlock is called when a block is received. - OnBlock(ctx context.Context, handler func(ctx context.Context, ev *v1.BlockEvent) error) (*nats.Subscription, error) - // OnAttestation is called when an attestation is received. - OnAttestation(ctx context.Context, handler func(ctx context.Context, ev *phase0.Attestation) error) (*nats.Subscription, error) - // OnFinalizedCheckpoint is called when a finalized checkpoint is received. - OnFinalizedCheckpoint(ctx context.Context, handler func(ctx context.Context, ev *v1.FinalizedCheckpointEvent) error) (*nats.Subscription, error) - // OnHead is called when the head is received. - OnHead(ctx context.Context, handler func(ctx context.Context, ev *v1.HeadEvent) error) (*nats.Subscription, error) - // OnChainReOrg is called when a chain reorg is received. - OnChainReOrg(ctx context.Context, handler func(ctx context.Context, ev *v1.ChainReorgEvent) error) (*nats.Subscription, error) - // OnVoluntaryExit is called when a voluntary exit is received. - OnVoluntaryExit(ctx context.Context, handler func(ctx context.Context, ev *phase0.VoluntaryExit) error) (*nats.Subscription, error) - - // - Custom events - // OnReady is called when the node is ready. - OnReady(ctx context.Context, handler func(ctx context.Context, event *ReadyEvent) error) (*nats.Subscription, error) - // OnEpochChanged is called when the current epoch changes. - OnEpochChanged(ctx context.Context, handler func(ctx context.Context, event *EpochChangedEvent) error) (*nats.Subscription, error) - // OnSlotChanged is called when the current slot changes. - OnSlotChanged(ctx context.Context, handler func(ctx context.Context, event *SlotChangedEvent) error) (*nats.Subscription, error) - // OnEpochSlotChanged is called when the current epoch or slot changes. - OnEpochSlotChanged(ctx context.Context, handler func(ctx context.Context, event *EpochSlotChangedEvent) error) (*nats.Subscription, error) - // OnBlockInserted is called when a block is inserted. - OnBlockInserted(ctx context.Context, handler func(ctx context.Context, event *BlockInsertedEvent) error) (*nats.Subscription, error) - // OnSyncStatus is called when the sync status changes. - OnSyncStatus(ctx context.Context, handler func(ctx context.Context, event *SyncStatusEvent) error) (*nats.Subscription, error) - // OnNodeVersionUpdated is called when the node version is updated. - OnNodeVersionUpdated(ctx context.Context, handler func(ctx context.Context, event *NodeVersionUpdatedEvent) error) (*nats.Subscription, error) - // OnPeersUpdated is called when the peers are updated. - OnPeersUpdated(ctx context.Context, handler func(ctx context.Context, event *PeersUpdatedEvent) error) (*nats.Subscription, error) - // OnSpecUpdated is called when the spec is updated. - OnSpecUpdated(ctx context.Context, handler func(ctx context.Context, event *SpecUpdatedEvent) error) (*nats.Subscription, error) - // OnEmptySlot is called when an empty slot is detected. - OnEmptySlot(ctx context.Context, handler func(ctx context.Context, event *EmptySlotEvent) error) (*nats.Subscription, error) -} - -// Node represents an Ethereum beacon node. It computes values based on the spec. -type node struct { - // Helpers - log logrus.FieldLogger - - // Clients - api api.ConsensusClient - client eth2client.Service - broker *nats.EncodedConn - - // Internal data stores - genesis *v1.Genesis - state *state.Container - lastEventTime time.Time - syncing *v1.SyncState - nodeVersion string - peers types.Peers -} - -func NewNode(ctx context.Context, log logrus.FieldLogger, ap api.ConsensusClient, client eth2client.Service, broker *nats.EncodedConn) Node { - return &node{ - log: log.WithField("module", "consensus/beacon"), - api: ap, - client: client, - broker: broker, - - syncing: &v1.SyncState{ - IsSyncing: false, - }, - } -} - -func (n *node) Start(ctx context.Context) error { - if err := n.bootstrap(ctx); err != nil { - return err - } - - if err := n.fetchSyncStatus(ctx); err != nil { - return err - } - - s := gocron.NewScheduler(time.Local) - - if _, err := s.Every("15s").Do(func() { - if err := n.fetchSyncStatus(ctx); err != nil { - n.log.WithError(err).Error("Failed to fetch sync status") - } - }); err != nil { - return err - } - - if _, err := s.Every("15m").Do(func() { - if err := n.fetchNodeVersion(ctx); err != nil { - n.log.WithError(err).Error("Failed to fetch node version") - } - }); err != nil { - return err - } - - if _, err := s.Every("15s").Do(func() { - if err := n.fetchPeers(ctx); err != nil { - n.log.WithError(err).Error("Failed to fetch peers") - } - }); err != nil { - return err - } - - s.StartAsync() - - return nil -} - -func (n *node) StartAsync(ctx context.Context) { - go func() { - if err := n.Start(ctx); err != nil { - n.log.WithError(err).Error("Failed to start beacon node") - } - }() -} - -func (n *node) GetEpoch(ctx context.Context, epoch phase0.Epoch) (*state.Epoch, error) { - if n.state == nil { - return nil, errors.New("state is not initialized") - } - - return n.state.GetEpoch(ctx, epoch) -} - -func (n *node) GetSlot(ctx context.Context, slot phase0.Slot) (*state.Slot, error) { - if n.state == nil { - return nil, errors.New("state is not initialized") - } - - return n.state.GetSlot(ctx, slot) -} - -func (n *node) GetSpec(ctx context.Context) (*state.Spec, error) { - if n.state == nil { - return nil, errors.New("state is not initialized") - } - - sp := n.state.Spec() - - if sp == nil { - return nil, errors.New("spec not yet available") - } - - return sp, nil -} - -func (n *node) GetSyncState(ctx context.Context) (*v1.SyncState, error) { - return n.syncing, nil -} - -func (n *node) GetGenesis(ctx context.Context) (*v1.Genesis, error) { - return n.genesis, nil -} - -func (n *node) GetNodeVersion(ctx context.Context) (string, error) { - return n.nodeVersion, nil -} - -func (n *node) bootstrap(ctx context.Context) error { - if err := n.initializeState(ctx); err != nil { - return err - } - - if err := n.subscribeDownstream(ctx); err != nil { - return err - } - - if err := n.subscribeToSelf(ctx); err != nil { - return err - } - - if err := n.publishReady(ctx); err != nil { - return err - } - - //nolint:errcheck // we dont care if this errors out since it runs indefinitely in a goroutine - go n.ensureBeaconSubscription(ctx) - - return nil -} - -func (n *node) fetchSyncStatus(ctx context.Context) error { - provider, isProvider := n.client.(eth2client.NodeSyncingProvider) - if !isProvider { - return errors.New("client does not implement eth2client.NodeSyncingProvider") - } - - status, err := provider.NodeSyncing(ctx) - if err != nil { - return err - } - - n.syncing = status - - if err := n.publishSyncStatus(ctx, status); err != nil { - return err - } - - return nil -} - -func (n *node) fetchPeers(ctx context.Context) error { - peers, err := n.api.NodePeers(ctx) - if err != nil { - return err - } - - n.peers = peers - - return n.publishPeersUpdated(ctx, peers) -} - -func (n *node) subscribeToSelf(ctx context.Context) error { - // Listen for beacon block events and insert them in to our state - if _, err := n.OnBlock(ctx, func(ctx context.Context, ev *v1.BlockEvent) error { - if n.syncing.IsSyncing { - return nil - } - - start := time.Now() - - // Sleep a little for the beacon node to actually save the block - time.Sleep(200 * time.Millisecond) - - // Grab the entire block from the beacon node - block, err := n.getBlock(ctx, fmt.Sprintf("%v", ev.Slot)) - if err != nil { - return err - } - - if block == nil { - return errors.New("fetched block is nil") - } - - // Insert the beacon block into the state - if err := n.state.AddBeaconBlock(ctx, block, start); err != nil { - return err - } - - return nil - }); err != nil { - return err - } - - return nil -} - -func (n *node) subscribeDownstream(ctx context.Context) error { - if err := n.state.OnEpochSlotChanged(ctx, n.handleStateEpochSlotChanged); err != nil { - return err - } - - if err := n.state.OnBlockInserted(ctx, n.handleDownstreamBlockInserted); err != nil { - return err - } - - if err := n.state.OnEmptySlot(ctx, n.handleDownstreamEmptySlot); err != nil { - return err - } - - return nil -} - -func (n *node) fetchNodeVersion(ctx context.Context) error { - provider, isProvider := n.client.(eth2client.NodeVersionProvider) - if !isProvider { - return errors.New("client does not implement eth2client.NodeVersionProvider") - } - - version, err := provider.NodeVersion(ctx) - if err != nil { - return err - } - - n.nodeVersion = version - - return n.publishNodeVersionUpdated(ctx, version) -} - -func (n *node) handleDownstreamBlockInserted(ctx context.Context, epoch phase0.Epoch, slot state.Slot) error { - if err := n.publishBlockInserted(ctx, slot.Number()); err != nil { - return err - } - - return nil -} - -func (n *node) handleDownstreamEmptySlot(ctx context.Context, epoch phase0.Epoch, slot state.Slot) error { - if n.syncing.IsSyncing { - return nil - } - - if err := n.publishEmptySlot(ctx, slot.Number()); err != nil { - return err - } - - return nil -} - -func (n *node) handleStateEpochSlotChanged(ctx context.Context, epochNumber phase0.Epoch, slot phase0.Slot) error { - n.log.WithFields(logrus.Fields{ - "epoch": epochNumber, - "slot": slot, - }).Debug("Current epoch/slot changed") - - for i := epochNumber; i < epochNumber+1; i++ { - epoch, err := n.state.GetEpoch(ctx, i) - if err != nil { - return err - } - - if epoch.HaveProposerDuties() { - continue - } - - if n.syncing.IsSyncing { - continue - } - - if err := n.fetchEpochProposerDuties(ctx, i); err != nil { - return err - } - } - - return nil -} - -func (n *node) fetchEpochProposerDuties(ctx context.Context, epoch phase0.Epoch) error { - duties, err := n.getProserDuties(ctx, epoch) - if err != nil { - return err - } - - if err := n.state.SetProposerDuties(ctx, epoch, duties); err != nil { - return err - } - - return nil -} - -func (n *node) initializeState(ctx context.Context) error { - n.log.Info("Initializing beacon state") - - sp, err := n.getSpec(ctx) - if err != nil { - return err - } - - genesis, err := n.fetchGenesis(ctx) - if err != nil { - return err - } - - st := state.NewContainer(ctx, n.log, sp, genesis) - - if err := st.Init(ctx); err != nil { - return err - } - - n.state = &st - - n.log.Info("Beacon state initialized! Ready to serve requests...") - - return nil -} - -func (n *node) getSpec(ctx context.Context) (*state.Spec, error) { - provider, isProvider := n.client.(eth2client.SpecProvider) - if !isProvider { - return nil, errors.New("client does not implement eth2client.SpecProvider") - } - - data, err := provider.Spec(ctx) - if err != nil { - return nil, err - } - - sp := state.NewSpec(data) - - if err := n.publishSpecUpdated(ctx, &sp); err != nil { - return nil, err - } - - return &sp, nil -} - -func (n *node) getProserDuties(ctx context.Context, epoch phase0.Epoch) ([]*v1.ProposerDuty, error) { - n.log.WithField("epoch", epoch).Debug("Fetching proposer duties") - - provider, isProvider := n.client.(eth2client.ProposerDutiesProvider) - if !isProvider { - return nil, errors.New("client does not implement eth2client.ProposerDutiesProvider") - } - - duties, err := provider.ProposerDuties(ctx, epoch, nil) - if err != nil { - return nil, err - } - - return duties, nil -} - -func (n *node) getBlock(ctx context.Context, blockID string) (*spec.VersionedSignedBeaconBlock, error) { - provider, isProvider := n.client.(eth2client.SignedBeaconBlockProvider) - if !isProvider { - return nil, errors.New("client does not implement eth2client.SignedBeaconBlockProvider") - } - - signedBeaconBlock, err := provider.SignedBeaconBlock(ctx, blockID) - if err != nil { - return nil, err - } - - return signedBeaconBlock, nil -} diff --git a/pkg/exporter/consensus/beacon/event.go b/pkg/exporter/consensus/beacon/event.go deleted file mode 100644 index f6a405a..0000000 --- a/pkg/exporter/consensus/beacon/event.go +++ /dev/null @@ -1,72 +0,0 @@ -package beacon - -import ( - v1 "github.com/attestantio/go-eth2-client/api/v1" - "github.com/attestantio/go-eth2-client/spec/phase0" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/api/types" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon/state" -) - -const ( - // Custom events derived from our pseudo beacon node - topicEpochChanged = "epoch_changed" - topicSlotChanged = "slot_changed" - topicEpochSlotChanged = "epoch_slot_changed" - topicBlockInserted = "block_inserted" - topicReady = "ready" - topicSyncStatus = "sync_status" - topicNodeVersionUpdated = "node_version_updated" - topicPeersUpdated = "peers_updated" - topicSpecUpdated = "spec_updated" - topicEmptySlot = "slot_empty" - - // Official beacon events that are proxied - topicAttestation = "attestation" - topicBlock = "block" - topicChainReorg = "chain_reorg" - topicFinalizedCheckpoint = "finalized_checkpoint" - topicHead = "head" - topicVoluntaryExit = "voluntary_exit" - topicContributionAndProof = "contribution_and_proof" - topicEvent = "raw_event" -) - -type EpochChangedEvent struct { - Epoch phase0.Epoch -} - -type SlotChangedEvent struct { - Slot phase0.Slot -} - -type EpochSlotChangedEvent struct { - Epoch phase0.Epoch - Slot phase0.Slot -} - -type BlockInsertedEvent struct { - Slot phase0.Slot -} - -type ReadyEvent struct { -} - -type SyncStatusEvent struct { - State *v1.SyncState -} - -type NodeVersionUpdatedEvent struct { - Version string -} - -type PeersUpdatedEvent struct { - Peers types.Peers -} - -type SpecUpdatedEvent struct { - Spec *state.Spec -} - -type EmptySlotEvent struct { - Slot phase0.Slot -} diff --git a/pkg/exporter/consensus/beacon/genesis.go b/pkg/exporter/consensus/beacon/genesis.go deleted file mode 100644 index c38fe75..0000000 --- a/pkg/exporter/consensus/beacon/genesis.go +++ /dev/null @@ -1,25 +0,0 @@ -package beacon - -import ( - "context" - "errors" - - eth2client "github.com/attestantio/go-eth2-client" - v1 "github.com/attestantio/go-eth2-client/api/v1" -) - -func (n *node) fetchGenesis(ctx context.Context) (*v1.Genesis, error) { - provider, isProvider := n.client.(eth2client.GenesisProvider) - if !isProvider { - return nil, errors.New("client does not implement eth2client.GenesisProvider") - } - - genesis, err := provider.Genesis(ctx) - if err != nil { - return nil, err - } - - n.genesis = genesis - - return genesis, nil -} diff --git a/pkg/exporter/consensus/beacon/publisher.go b/pkg/exporter/consensus/beacon/publisher.go deleted file mode 100644 index 7ca677a..0000000 --- a/pkg/exporter/consensus/beacon/publisher.go +++ /dev/null @@ -1,99 +0,0 @@ -package beacon - -import ( - "context" - - v1 "github.com/attestantio/go-eth2-client/api/v1" - "github.com/attestantio/go-eth2-client/spec/phase0" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/api/types" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon/state" -) - -// Official beacon events that are proxied -func (n *node) publishBlock(ctx context.Context, event *v1.BlockEvent) error { - return n.broker.Publish(topicBlock, event) -} - -func (n *node) publishAttestation(ctx context.Context, event *phase0.Attestation) error { - return n.broker.Publish(topicAttestation, event) -} - -func (n *node) publishChainReOrg(ctx context.Context, event *v1.ChainReorgEvent) error { - return n.broker.Publish(topicChainReorg, event) -} - -func (n *node) publishFinalizedCheckpoint(ctx context.Context, event *v1.FinalizedCheckpointEvent) error { - return n.broker.Publish(topicFinalizedCheckpoint, event) -} - -func (n *node) publishHead(ctx context.Context, event *v1.HeadEvent) error { - return n.broker.Publish(topicHead, event) -} - -func (n *node) publishVoluntaryExit(ctx context.Context, event *phase0.VoluntaryExit) error { - return n.broker.Publish(topicVoluntaryExit, event) -} - -func (n *node) publishEvent(ctx context.Context, event *v1.Event) error { - return n.broker.Publish(topicEvent, event) -} - -// Custom Events derived from our pseudo beacon node -func (n *node) publishReady(ctx context.Context) error { - return n.broker.Publish(topicReady, nil) -} - -func (n *node) publishEpochChanged(ctx context.Context, epoch phase0.Epoch) error { - return n.broker.Publish(topicEpochChanged, &EpochChangedEvent{ - Epoch: epoch, - }) -} - -func (n *node) publishSlotChanged(ctx context.Context, slot phase0.Slot) error { - return n.broker.Publish(topicSlotChanged, &SlotChangedEvent{ - Slot: slot, - }) -} - -func (n *node) publishEpochSlotChanged(ctx context.Context, epoch phase0.Epoch, slot phase0.Slot) error { - return n.broker.Publish(topicEpochSlotChanged, &EpochSlotChangedEvent{ - Epoch: epoch, - Slot: slot, - }) -} - -func (n *node) publishBlockInserted(ctx context.Context, slot phase0.Slot) error { - return n.broker.Publish(topicBlockInserted, &BlockInsertedEvent{ - Slot: slot, - }) -} - -func (n *node) publishSyncStatus(ctx context.Context, st *v1.SyncState) error { - return n.broker.Publish(topicSyncStatus, &SyncStatusEvent{ - State: st, - }) -} - -func (n *node) publishNodeVersionUpdated(ctx context.Context, version string) error { - return n.broker.Publish(topicNodeVersionUpdated, &NodeVersionUpdatedEvent{ - Version: version, - }) -} - -func (n *node) publishPeersUpdated(ctx context.Context, peers types.Peers) error { - return n.broker.Publish(topicPeersUpdated, &PeersUpdatedEvent{ - Peers: peers, - }) -} - -func (n *node) publishSpecUpdated(ctx context.Context, spec *state.Spec) error { - return n.broker.Publish(topicSpecUpdated, &SpecUpdatedEvent{ - Spec: spec, - }) -} - -func (n *node) publishEmptySlot(ctx context.Context, slot phase0.Slot) error { - return n.broker.Publish(topicEmptySlot, &EmptySlotEvent{ - Slot: slot, - }) -} diff --git a/pkg/exporter/consensus/beacon/state/block.go b/pkg/exporter/consensus/beacon/state/block.go deleted file mode 100644 index 2462bae..0000000 --- a/pkg/exporter/consensus/beacon/state/block.go +++ /dev/null @@ -1,13 +0,0 @@ -package state - -import ( - "time" - - "github.com/attestantio/go-eth2-client/spec" -) - -// TimedBlock is a block with a timestamp. -type TimedBlock struct { - Block *spec.VersionedSignedBeaconBlock - SeenAt time.Time -} diff --git a/pkg/exporter/consensus/beacon/state/epoch.go b/pkg/exporter/consensus/beacon/state/epoch.go deleted file mode 100644 index cc48a9f..0000000 --- a/pkg/exporter/consensus/beacon/state/epoch.go +++ /dev/null @@ -1,114 +0,0 @@ -package state - -import ( - "errors" - "time" - - v1 "github.com/attestantio/go-eth2-client/api/v1" - "github.com/attestantio/go-eth2-client/spec" - "github.com/attestantio/go-eth2-client/spec/phase0" -) - -type Epoch struct { - slots Slots - Number phase0.Epoch - FirstSlot phase0.Slot - LastSlot phase0.Slot - StartTime time.Time - EndTime time.Time - Duration time.Duration - bundle BlockTimeCalculatorBundle - - haveProposerDuties bool -} - -func NewEpoch(epochNumber phase0.Epoch, slotsPerEpoch phase0.Slot, bundle BlockTimeCalculatorBundle) Epoch { - firstSlot := uint64(epochNumber) * uint64(slotsPerEpoch) - lastSlot := (firstSlot + uint64(slotsPerEpoch)) - 1 - - e := Epoch{ - slots: NewSlots(bundle), - - Number: epochNumber, - FirstSlot: phase0.Slot(firstSlot), - LastSlot: phase0.Slot(lastSlot), - StartTime: bundle.Genesis.GenesisTime.Add(time.Duration(firstSlot) * bundle.SecondsPerSlot), - EndTime: bundle.Genesis.GenesisTime.Add((time.Duration(lastSlot) * bundle.SecondsPerSlot)).Add(bundle.SecondsPerSlot), - Duration: bundle.SecondsPerSlot * time.Duration(slotsPerEpoch), - bundle: bundle, - - haveProposerDuties: false, - } - - return e -} - -func (e *Epoch) AddBlock(block *spec.VersionedSignedBeaconBlock, seenAt time.Time) error { - if block == nil { - return errors.New("block is nil") - } - - slotNumber, err := block.Slot() - if err != nil { - return err - } - - slot, err := e.slots.Get(slotNumber) - if err != nil { - return err - } - - return slot.AddBlock(&TimedBlock{ - Block: block, - SeenAt: seenAt, - }) -} - -func (e *Epoch) GetSlotProposer(slotNumber phase0.Slot) (*v1.ProposerDuty, error) { - slot, err := e.slots.Get(slotNumber) - if err != nil { - return nil, err - } - - return slot.ProposerDuty() -} - -func (e *Epoch) SetProposerDuties(duties []*v1.ProposerDuty) error { - for _, duty := range duties { - slot, err := e.slots.Get(duty.Slot) - if err != nil { - return err - } - - if err := slot.SetProposerDuty(duty); err != nil { - return err - } - } - - e.haveProposerDuties = true - - return nil -} - -func (e *Epoch) HaveProposerDuties() bool { - return e.haveProposerDuties -} - -func (e *Epoch) GetSlot(slotNumber phase0.Slot) (*Slot, error) { - return e.slots.Get(slotNumber) -} - -func (e *Epoch) InitializeSlots() error { - start := uint64(e.FirstSlot) - end := uint64(e.LastSlot) - - for i := start; i <= end; i++ { - slot := NewSlot(phase0.Slot(i), e.bundle) - - if err := e.slots.Add(&slot); err != nil { - return err - } - } - - return nil -} diff --git a/pkg/exporter/consensus/beacon/state/epochs.go b/pkg/exporter/consensus/beacon/state/epochs.go deleted file mode 100644 index e7b4ba6..0000000 --- a/pkg/exporter/consensus/beacon/state/epochs.go +++ /dev/null @@ -1,86 +0,0 @@ -package state - -import ( - "errors" - "sync" - - v1 "github.com/attestantio/go-eth2-client/api/v1" - "github.com/attestantio/go-eth2-client/spec/phase0" -) - -type Epochs struct { - spec *Spec - state map[phase0.Epoch]*Epoch - genesis *v1.Genesis - bundle BlockTimeCalculatorBundle - mu *sync.Mutex -} - -func NewEpochs(spec *Spec, genesis *v1.Genesis) Epochs { - return Epochs{ - spec: spec, - state: make(map[phase0.Epoch]*Epoch), - genesis: genesis, - bundle: BlockTimeCalculatorBundle{ - Genesis: genesis, - SecondsPerSlot: spec.SecondsPerSlot, - }, - mu: &sync.Mutex{}, - } -} - -func (e *Epochs) GetEpoch(epoch phase0.Epoch) (*Epoch, error) { - e.mu.Lock() - defer e.mu.Unlock() - - if e.state[epoch] == nil { - return nil, errors.New("epoch not found") - } - - return e.state[epoch], nil -} - -func (e *Epochs) Exists(number phase0.Epoch) bool { - e.mu.Lock() - defer e.mu.Unlock() - - _, ok := e.state[number] - - return ok -} - -func (e *Epochs) NewInitializedEpoch(number phase0.Epoch) (*Epoch, error) { - epoch := NewEpoch(number, e.spec.SlotsPerEpoch, e.bundle) - - if err := epoch.InitializeSlots(); err != nil { - return nil, err - } - - if err := e.AddEpoch(number, &epoch); err != nil { - return nil, err - } - - return &epoch, nil -} - -func (e *Epochs) AddEpoch(number phase0.Epoch, epoch *Epoch) error { - e.mu.Lock() - defer e.mu.Unlock() - - if epoch == nil { - return errors.New("epoch is nil") - } - - e.state[number] = epoch - - return nil -} - -func (e *Epochs) RemoveEpoch(number phase0.Epoch) error { - e.mu.Lock() - defer e.mu.Unlock() - - delete(e.state, number) - - return nil -} diff --git a/pkg/exporter/consensus/beacon/state/fork_epoch.go b/pkg/exporter/consensus/beacon/state/fork_epoch.go deleted file mode 100644 index d9160de..0000000 --- a/pkg/exporter/consensus/beacon/state/fork_epoch.go +++ /dev/null @@ -1,66 +0,0 @@ -package state - -import ( - "errors" - - "github.com/attestantio/go-eth2-client/spec/phase0" -) - -// ForkEpoch is a beacon fork that activates at a specific epoch. -type ForkEpoch struct { - Epoch phase0.Epoch - Name string -} - -// Active returns true if the fork is active at the given slot. -func (f *ForkEpoch) Active(slot, slotsPerEpoch phase0.Slot) bool { - return phase0.Epoch(int(slot)/int(slotsPerEpoch)) >= f.Epoch -} - -// ForkEpochs is a list of forks that activate at specific epochs. -type ForkEpochs []ForkEpoch - -// Active returns a list of forks that are active at the given slot. -func (f *ForkEpochs) Active(slot, slotsPerEpoch phase0.Slot) []ForkEpoch { - activated := []ForkEpoch{} - - for _, fork := range *f { - if fork.Active(slot, slotsPerEpoch) { - activated = append(activated, fork) - } - } - - return activated -} - -// CurrentFork returns the current fork at the given slot. -func (f *ForkEpochs) Scheduled(slot, slotsPerEpoch phase0.Slot) []ForkEpoch { - scheduled := []ForkEpoch{} - - for _, fork := range *f { - if !fork.Active(slot, slotsPerEpoch) { - scheduled = append(scheduled, fork) - } - } - - return scheduled -} - -// CurrentFork returns the current fork at the given slot. -func (f *ForkEpochs) CurrentFork(slot, slotsPerEpoch phase0.Slot) (ForkEpoch, error) { - largest := ForkEpoch{ - Epoch: 0, - } - - for _, fork := range f.Active(slot, slotsPerEpoch) { - if fork.Active(slot, slotsPerEpoch) && fork.Epoch > largest.Epoch { - largest = fork - } - } - - if largest.Epoch == 0 { - return ForkEpoch{}, errors.New("no active fork") - } - - return largest, nil -} diff --git a/pkg/exporter/consensus/beacon/state/publisher.go b/pkg/exporter/consensus/beacon/state/publisher.go deleted file mode 100644 index ec65aa5..0000000 --- a/pkg/exporter/consensus/beacon/state/publisher.go +++ /dev/null @@ -1,43 +0,0 @@ -package state - -import ( - "context" - - "github.com/attestantio/go-eth2-client/spec/phase0" -) - -func (c *Container) handleCallbackError(err error, topic string) { - if err != nil { - c.log.WithError(err).WithField("topic", topic).Error("Receieved error from subscriber callback") - } -} - -func (c *Container) publishEpochChanged(ctx context.Context, epoch phase0.Epoch) { - for _, cb := range c.callbacksEpochChanged { - c.handleCallbackError(cb(ctx, epoch), "epochs_changed") - } -} - -func (c *Container) publishSlotChanged(ctx context.Context, slot phase0.Slot) { - for _, cb := range c.callbacksSlotChanged { - c.handleCallbackError(cb(ctx, slot), "slots_changed") - } -} - -func (c *Container) publishEpochSlotChanged(ctx context.Context, epoch phase0.Epoch, slot phase0.Slot) { - for _, cb := range c.callbacksEpochSlotChanged { - c.handleCallbackError(cb(ctx, epoch, slot), "epoch_slots_changed") - } -} - -func (c *Container) publishBlockInserted(ctx context.Context, epoch phase0.Epoch, slot Slot) { - for _, cb := range c.callbacksBlockInserted { - c.handleCallbackError(cb(ctx, epoch, slot), "block_inserted") - } -} - -func (c *Container) publishEmptySlot(ctx context.Context, epoch phase0.Epoch, slot Slot) { - for _, cb := range c.callbacksEmptySlot { - c.handleCallbackError(cb(ctx, epoch, slot), "empty_slot") - } -} diff --git a/pkg/exporter/consensus/beacon/state/slot.go b/pkg/exporter/consensus/beacon/state/slot.go deleted file mode 100644 index 7622b6a..0000000 --- a/pkg/exporter/consensus/beacon/state/slot.go +++ /dev/null @@ -1,111 +0,0 @@ -package state - -import ( - "errors" - "sync" - "time" - - v1 "github.com/attestantio/go-eth2-client/api/v1" - "github.com/attestantio/go-eth2-client/spec/phase0" -) - -// Slot is a slot in the beacon chain. -type Slot struct { - block *TimedBlock - proposerDuty *v1.ProposerDuty - number phase0.Slot - bundle BlockTimeCalculatorBundle - mu *sync.Mutex -} - -// NewSlot returns a new slot. -func NewSlot(number phase0.Slot, bundle BlockTimeCalculatorBundle) Slot { - return Slot{ - block: nil, - proposerDuty: nil, - number: number, - mu: &sync.Mutex{}, - bundle: bundle, - } -} - -// Number returns the slot number. -func (m *Slot) Number() phase0.Slot { - return m.number -} - -// Block returns the block for the slot (if it exists). -func (m *Slot) Block() (*TimedBlock, error) { - m.mu.Lock() - defer m.mu.Unlock() - - if m.block == nil { - return nil, errors.New("block does not exist") - } - - return m.block, nil -} - -// AddBlock adds a block to the slot. -func (m *Slot) AddBlock(timedBlock *TimedBlock) error { - m.mu.Lock() - defer m.mu.Unlock() - - if timedBlock == nil { - return errors.New("timed_block is nil") - } - - if timedBlock.Block == nil { - return errors.New("block is nil") - } - - slot, err := timedBlock.Block.Slot() - if err != nil { - return err - } - - if slot != m.number { - return errors.New("block slot does not match slot") - } - - m.block = timedBlock - - return nil -} - -// ProposerDelay calculates the amount of time it took for the proposer to publish the block. -func (m *Slot) ProposerDelay() (time.Duration, error) { - if m.block == nil { - return 0, errors.New("block does not exist") - } - - // Calculate the proposer delay for the block. - expected := m.bundle.Genesis.GenesisTime.Add(time.Duration(uint64(m.number)) * m.bundle.SecondsPerSlot) - delay := m.block.SeenAt.Sub(expected) - - return delay, nil -} - -// ProposerDuty returns the proposer duty for the slot (if it exists). -func (m *Slot) ProposerDuty() (*v1.ProposerDuty, error) { - if m.proposerDuty == nil { - return nil, errors.New("proposer duty does not exist") - } - - return m.proposerDuty, nil -} - -// SetProposerDuty sets the proposer duty for the slot. -func (m *Slot) SetProposerDuty(proposerDuty *v1.ProposerDuty) error { - if proposerDuty.Slot != m.number { - return errors.New("proposer duty slot does not match slot") - } - - m.proposerDuty = proposerDuty - - return nil -} - -func (m *Slot) MissingBlock() bool { - return m.block == nil -} diff --git a/pkg/exporter/consensus/beacon/state/slots.go b/pkg/exporter/consensus/beacon/state/slots.go deleted file mode 100644 index 6eb0a90..0000000 --- a/pkg/exporter/consensus/beacon/state/slots.go +++ /dev/null @@ -1,60 +0,0 @@ -package state - -import ( - "errors" - "sync" - - "github.com/attestantio/go-eth2-client/spec/phase0" -) - -// Slots is a collection of slots. -type Slots struct { - state map[phase0.Slot]*Slot - bundle BlockTimeCalculatorBundle - mu *sync.Mutex -} - -// NewSlots returns a new slots instance. -func NewSlots(bundle BlockTimeCalculatorBundle) Slots { - return Slots{ - state: make(map[phase0.Slot]*Slot), - mu: &sync.Mutex{}, - bundle: bundle, - } -} - -// Add adds a slot to the collection. -func (m *Slots) Add(slot *Slot) error { - m.mu.Lock() - defer m.mu.Unlock() - - if slot == nil { - return errors.New("slot is nil") - } - - m.state[slot.Number()] = slot - - return nil -} - -// Get returns a slot from the collection. -func (m *Slots) Get(slot phase0.Slot) (*Slot, error) { - m.mu.Lock() - defer m.mu.Unlock() - - if m.state[slot] == nil { - return nil, errors.New("slot does not exist") - } - - return m.state[slot], nil -} - -// Delete deletes a slot from the collection. -func (m *Slots) Delete(slot phase0.Slot) error { - m.mu.Lock() - defer m.mu.Unlock() - - delete(m.state, slot) - - return nil -} diff --git a/pkg/exporter/consensus/beacon/state/spec.go b/pkg/exporter/consensus/beacon/state/spec.go deleted file mode 100644 index 4cfbc0a..0000000 --- a/pkg/exporter/consensus/beacon/state/spec.go +++ /dev/null @@ -1,166 +0,0 @@ -package state - -import ( - "fmt" - "math/big" - "strings" - "time" - - "github.com/attestantio/go-eth2-client/spec/phase0" - "github.com/spf13/cast" -) - -// Spec represents the state of the spec. -type Spec struct { - PresetBase string - ConfigName string - - DepositChainID uint64 - - SafeSlotsToUpdateJustified phase0.Slot - SlotsPerEpoch phase0.Slot - - EpochsPerSyncCommitteePeriod phase0.Epoch - MinSyncCommitteeParticipants uint64 - TargetCommitteeSize uint64 - SyncCommitteeSize uint64 - - TerminalBlockHashActivationEpoch phase0.Epoch - TerminalTotalDifficulty big.Int - - MaxValidatorsPerCommittee uint64 - BaseRewardFactor uint64 - EffectiveBalanceIncrement phase0.Gwei - MaxEffectiveBalance phase0.Gwei - MinDepositAmount phase0.Gwei - MaxAttestations uint64 - - SecondsPerEth1Block time.Duration - GenesisDelay time.Duration - SecondsPerSlot time.Duration - MaxDeposits uint64 - MinGenesisActiveValidatorCount uint64 - Eth1FollowDistance uint64 - - ForkEpochs ForkEpochs -} - -// NewSpec creates a new spec instance. -func NewSpec(data map[string]interface{}) Spec { - spec := Spec{ - ForkEpochs: ForkEpochs{}, - } - - if safeSlotsToUpdateJustified, exists := data["SAFE_SLOTS_TO_UPDATE_JUSTIFIED"]; exists { - spec.SafeSlotsToUpdateJustified = phase0.Slot(cast.ToUint64(safeSlotsToUpdateJustified)) - } - - if depositChainID, exists := data["DEPOSIT_CHAIN_ID"]; exists { - spec.DepositChainID = cast.ToUint64(depositChainID) - } - - if configName, exists := data["CONFIG_NAME"]; exists { - spec.ConfigName = cast.ToString(configName) - } - - if maxValidatorsPerCommittee, exists := data["MAX_VALIDATORS_PER_COMMITTEE"]; exists { - spec.MaxValidatorsPerCommittee = cast.ToUint64(maxValidatorsPerCommittee) - } - - if secondsPerEth1Block, exists := data["SECONDS_PER_ETH1_BLOCK"]; exists { - spec.SecondsPerEth1Block = cast.ToDuration(secondsPerEth1Block) - } - - if baseRewardFactor, exists := data["BASE_REWARD_FACTOR"]; exists { - spec.BaseRewardFactor = cast.ToUint64(baseRewardFactor) - } - - if epochsPerSyncComitteePeriod, exists := data["EPOCHS_PER_SYNC_COMMITTEE_PERIOD"]; exists { - spec.EpochsPerSyncCommitteePeriod = phase0.Epoch(cast.ToUint64(epochsPerSyncComitteePeriod)) - } - - if effectiveBalanceIncrement, exists := data["EFFECTIVE_BALANCE_INCREMENT"]; exists { - spec.EffectiveBalanceIncrement = phase0.Gwei(cast.ToUint64(effectiveBalanceIncrement)) - } - - if maxAttestations, exists := data["MAX_ATTESTATIONS"]; exists { - spec.MaxAttestations = cast.ToUint64(maxAttestations) - } - - if minSyncCommitteeParticipants, exists := data["MIN_SYNC_COMMITTEE_PARTICIPANTS"]; exists { - spec.MinSyncCommitteeParticipants = cast.ToUint64(minSyncCommitteeParticipants) - } - - if genesisDelay, exists := data["GENESIS_DELAY"]; exists { - spec.GenesisDelay = cast.ToDuration(genesisDelay) - } - - if secondsPerSlot, exists := data["SECONDS_PER_SLOT"]; exists { - spec.SecondsPerSlot = cast.ToDuration(secondsPerSlot) - } - - if maxEffectiveBalance, exists := data["MAX_EFFECTIVE_BALANCE"]; exists { - spec.MaxEffectiveBalance = phase0.Gwei(cast.ToUint64(maxEffectiveBalance)) - } - - if terminalTotalDifficulty, exists := data["TERMINAL_TOTAL_DIFFICULTY"]; exists { - ttd := cast.ToString(fmt.Sprintf("%v", terminalTotalDifficulty)) - - casted, _ := (*big.NewInt(0)).SetString(ttd, 10) - spec.TerminalTotalDifficulty = *casted - } - - if maxDeposits, exists := data["MAX_DEPOSITS"]; exists { - spec.MaxDeposits = cast.ToUint64(maxDeposits) - } - - if minGenesisActiveValidatorCount, exists := data["MIN_GENESIS_ACTIVE_VALIDATOR_COUNT"]; exists { - spec.MinGenesisActiveValidatorCount = cast.ToUint64(minGenesisActiveValidatorCount) - } - - if targetCommitteeSize, exists := data["TARGET_COMMITTEE_SIZE"]; exists { - spec.TargetCommitteeSize = cast.ToUint64(targetCommitteeSize) - } - - if syncCommitteeSize, exists := data["SYNC_COMMITTEE_SIZE"]; exists { - spec.SyncCommitteeSize = cast.ToUint64(syncCommitteeSize) - } - - if eth1FollowDistance, exists := data["ETH1_FOLLOW_DISTANCE"]; exists { - spec.Eth1FollowDistance = cast.ToUint64(eth1FollowDistance) - } - - if terminalBlockHashActivationEpoch, exists := data["TERMINAL_BLOCK_HASH_ACTIVATION_EPOCH"]; exists { - spec.TerminalBlockHashActivationEpoch = phase0.Epoch(cast.ToUint64(terminalBlockHashActivationEpoch)) - } - - if minDepositAmount, exists := data["MIN_DEPOSIT_AMOUNT"]; exists { - spec.MinDepositAmount = phase0.Gwei(cast.ToUint64(minDepositAmount)) - } - - if slotsPerEpoch, exists := data["SLOTS_PER_EPOCH"]; exists { - spec.SlotsPerEpoch = phase0.Slot(cast.ToUint64(slotsPerEpoch)) - } - - if presetBase, exists := data["PRESET_BASE"]; exists { - spec.PresetBase = cast.ToString(presetBase) - } - - for k, v := range data { - if strings.Contains(k, "_FORK_EPOCH") { - forkName := strings.ReplaceAll(k, "_FORK_EPOCH", "") - - spec.ForkEpochs = append(spec.ForkEpochs, ForkEpoch{ - Epoch: phase0.Epoch(cast.ToUint64(v)), - Name: forkName, - }) - } - } - - return spec -} - -// Validate performs basic validation of the spec. -func (s *Spec) Validate() error { - return nil -} diff --git a/pkg/exporter/consensus/beacon/state/state.go b/pkg/exporter/consensus/beacon/state/state.go deleted file mode 100644 index 6588144..0000000 --- a/pkg/exporter/consensus/beacon/state/state.go +++ /dev/null @@ -1,335 +0,0 @@ -package state - -import ( - "context" - "errors" - "fmt" - "time" - - v1 "github.com/attestantio/go-eth2-client/api/v1" - "github.com/attestantio/go-eth2-client/spec" - "github.com/attestantio/go-eth2-client/spec/phase0" - "github.com/sirupsen/logrus" -) - -// Container is the state container. -type Container struct { - log logrus.FieldLogger - spec *Spec - genesis *v1.Genesis - epochs Epochs - - currentEpoch phase0.Epoch - currentSlot phase0.Slot - - startedAt time.Time - - callbacksEpochChanged []func(ctx context.Context, epoch phase0.Epoch) error - callbacksSlotChanged []func(ctx context.Context, slot phase0.Slot) error - callbacksEpochSlotChanged []func(ctx context.Context, epoch phase0.Epoch, slot phase0.Slot) error - callbacksBlockInserted []func(ctx context.Context, epoch phase0.Epoch, slot Slot) error - callbacksEmptySlot []func(ctx context.Context, epoch phase0.Epoch, slot Slot) error -} - -const ( - // SurroundingEpochDistance is the number of epochs to create around the current epoch. - SurroundingEpochDistance = 1 -) - -// NewContainer creates a new state container instance -func NewContainer(ctx context.Context, log logrus.FieldLogger, sp *Spec, genesis *v1.Genesis) Container { - return Container{ - log: log.WithField("sub_module", "state"), - spec: sp, - - genesis: genesis, - - currentEpoch: 0, - currentSlot: 0, - - startedAt: time.Now(), - - epochs: NewEpochs(sp, genesis), - } -} - -var ( - ErrSpecNotInitialized = errors.New("spec not initialized") - ErrGenesisNotFetched = errors.New("genesis not fetched") -) - -// Init initializes the state container. -func (c *Container) Init(ctx context.Context) error { - if err := c.hydrateEpochs(ctx); err != nil { - return err - } - - go c.ticker(ctx) - - //nolint:errcheck // dont care about an error here. - go c.currentSlotLoop(ctx) - - return nil -} - -// Spec returns the spec for the state container. -func (c *Container) Spec() *Spec { - return c.spec -} - -func (c *Container) ticker(ctx context.Context) { - c.tick(ctx) - - for { - select { - case <-ctx.Done(): - return - case <-time.After(time.Second * 5): - c.tick(ctx) - } - } -} - -func (c *Container) currentSlotLoop(ctx context.Context) error { - for { - currentSlot := c.currentSlot - - nextSlotStartsAt := c.genesis.GenesisTime.Add(c.spec.SecondsPerSlot * time.Duration(currentSlot+1)) - - select { - case <-ctx.Done(): - return nil - case <-time.After(time.Until(nextSlotStartsAt)): - if err := c.checkForNewCurrentEpochAndSlot(ctx); err != nil { - return err - } - } - } -} - -func (c *Container) tick(ctx context.Context) { - if err := c.hydrateEpochs(ctx); err != nil { - c.log.WithError(err).Error("Failed to hydrate epochs") - } -} - -// AddBeaconBlock adds a beacon block to the state container. -func (c *Container) AddBeaconBlock(ctx context.Context, beaconBlock *spec.VersionedSignedBeaconBlock, seenAt time.Time) error { - if beaconBlock == nil { - return errors.New("beacon block is nil") - } - - // Calculate the epoch - slotNumber, err := beaconBlock.Slot() - if err != nil { - return err - } - - epochNumber := c.calculateEpochFromSlot(slotNumber) - - if exists := c.epochs.Exists(epochNumber); !exists { - return fmt.Errorf("epoch %d does not exist", epochNumber) - } - - // Get the epoch - epoch, err := c.epochs.GetEpoch(epochNumber) - if err != nil { - return err - } - - // Insert the block - //nolint:gocritic // false positive - if err = epoch.AddBlock(beaconBlock, seenAt); err != nil { - return err - } - - slot, err := epoch.GetSlot(slotNumber) - if err != nil { - return err - } - - delay, err := slot.ProposerDelay() - if err != nil { - return err - } - - proposer := "unknown" - - proposerDuty, err := slot.ProposerDuty() - if err == nil { - proposer = fmt.Sprintf("%v", proposerDuty.ValidatorIndex) - } else { - c.log.WithError(err).WithField("slot", slot).Warn("Failed to get slot proposer") - } - - c.log.WithFields(logrus.Fields{ - "epoch": epochNumber, - "slot": slotNumber, - "proposer_delay": delay.String(), - "proposer_index": proposer, - }).Debug("Inserted beacon block") - - c.publishBlockInserted(ctx, epochNumber, *slot) - - return nil -} - -func (c *Container) hydrateEpochs(ctx context.Context) error { - epoch := c.currentEpoch - - // Ensure the state has +-SurroundingEpochDistance epochs created. - for i := epoch - SurroundingEpochDistance; i <= epoch+SurroundingEpochDistance; i++ { - if _, err := c.epochs.GetEpoch(i); err != nil { - if _, err := c.createEpoch(ctx, i); err != nil { - return err - } - } - } - - return nil -} - -func (c *Container) getCurrentEpochAndSlot() (phase0.Epoch, phase0.Slot, error) { - if c.spec == nil { - return 0, 0, ErrSpecNotInitialized - } - - if c.genesis == nil { - return 0, 0, ErrGenesisNotFetched - } - - if err := c.spec.Validate(); err != nil { - return 0, 0, err - } - - // Calculate the current epoch based on genesis time. - genesis := c.genesis.GenesisTime - - currentSlot := phase0.Slot(time.Since(genesis).Seconds() / c.spec.SecondsPerSlot.Seconds()) - currentEpoch := phase0.Epoch(currentSlot / c.spec.SlotsPerEpoch) - - return currentEpoch, currentSlot, nil -} - -func (c *Container) SetProposerDuties(ctx context.Context, epochNumber phase0.Epoch, duties []*v1.ProposerDuty) error { - epoch, err := c.epochs.GetEpoch(epochNumber) - if err != nil { - return err - } - - if err := epoch.SetProposerDuties(duties); err != nil { - return err - } - - return nil -} - -func (c *Container) createEpoch(ctx context.Context, epochNumber phase0.Epoch) (*Epoch, error) { - if _, err := c.epochs.GetEpoch(epochNumber); err == nil { - return nil, fmt.Errorf("epoch %d already exists", epochNumber) - } - - epoch, err := c.epochs.NewInitializedEpoch(epochNumber) - if err != nil { - return nil, err - } - - c.log.WithField("epoch", epochNumber).Debug("Created new epoch") - - return epoch, nil -} - -func (c *Container) checkForNewCurrentEpochAndSlot(ctx context.Context) error { - epoch, slot, err := c.getCurrentEpochAndSlot() - if err != nil { - return err - } - - epochChanged := false - - if epoch != c.currentEpoch { - c.currentEpoch = epoch - - epochChanged = true - - if err := c.hydrateEpochs(ctx); err != nil { - return err - } - - // Notify the listeners of the new epoch. - go c.publishEpochChanged(ctx, epoch) - - // // Delete old epochs - previousEpoch := epoch - 5 - if err := c.DeleteEpoch(ctx, previousEpoch); err != nil { - return err - } - } - - slotChanged := false - - if slot != c.currentSlot { - previousSlot := c.currentSlot - - c.currentSlot = slot - - slotChanged = true - - // Notify the listeners of the new slot. - go c.publishSlotChanged(ctx, slot) - - // We can't safely check if the previous slot was missed if - // we potentially started up _after_ the slot had started. - // So we'll just not bother checking in that case. - if time.Since(c.startedAt) > (c.spec.SecondsPerSlot * 3) { - if err := c.checkForEmptySlot(ctx, previousSlot); err != nil { - c.log.WithError(err).Error("Failed to check for empty slot") - } - } - } - - if epochChanged || slotChanged { - // Notify the listeners of the new epoch and slot. - go c.publishEpochSlotChanged(ctx, epoch, slot) - } - - return nil -} - -func (c *Container) checkForEmptySlot(ctx context.Context, slotNumber phase0.Slot) error { - slot, err := c.GetSlot(ctx, slotNumber) - if err != nil { - return err - } - - epoch := c.calculateEpochFromSlot(slotNumber) - - if slot.MissingBlock() { - go c.publishEmptySlot(ctx, epoch, *slot) - } - - return nil -} - -// GetSlot returns the slot for the given slot number. -func (c *Container) GetSlot(ctx context.Context, slotNumber phase0.Slot) (*Slot, error) { - epoch, err := c.epochs.GetEpoch(c.calculateEpochFromSlot(slotNumber)) - if err != nil { - return nil, err - } - - return epoch.GetSlot(slotNumber) -} - -func (c *Container) calculateEpochFromSlot(slotNumber phase0.Slot) phase0.Epoch { - return phase0.Epoch(slotNumber / c.spec.SlotsPerEpoch) -} - -// GetEpoch returns the epoch for the given epoch number. -func (c *Container) GetEpoch(ctx context.Context, epochNumber phase0.Epoch) (*Epoch, error) { - return c.epochs.GetEpoch(epochNumber) -} - -func (c *Container) DeleteEpoch(ctx context.Context, epochNumber phase0.Epoch) error { - return c.epochs.RemoveEpoch(epochNumber) -} diff --git a/pkg/exporter/consensus/beacon/state/subscriber.go b/pkg/exporter/consensus/beacon/state/subscriber.go deleted file mode 100644 index d06c630..0000000 --- a/pkg/exporter/consensus/beacon/state/subscriber.go +++ /dev/null @@ -1,42 +0,0 @@ -package state - -import ( - "context" - - "github.com/attestantio/go-eth2-client/spec/phase0" -) - -// OnEpochChanged is called when the current epoch changes. -func (c *Container) OnEpochChanged(ctx context.Context, cb func(ctx context.Context, epoch phase0.Epoch) error) error { - c.callbacksEpochChanged = append(c.callbacksEpochChanged, cb) - - return nil -} - -// OnSlotChanged is called when the current slot changes. -func (c *Container) OnSlotChanged(ctx context.Context, cb func(ctx context.Context, slot phase0.Slot) error) error { - c.callbacksSlotChanged = append(c.callbacksSlotChanged, cb) - - return nil -} - -// OnEpochSlotChanged is called when the current epoch or slot changes. -func (c *Container) OnEpochSlotChanged(ctx context.Context, cb func(ctx context.Context, epoch phase0.Epoch, slot phase0.Slot) error) error { - c.callbacksEpochSlotChanged = append(c.callbacksEpochSlotChanged, cb) - - return nil -} - -// OnBlockInserted is called when a block is inserted in to a slot. -func (c *Container) OnBlockInserted(ctx context.Context, cb func(ctx context.Context, epoch phase0.Epoch, slot Slot) error) error { - c.callbacksBlockInserted = append(c.callbacksBlockInserted, cb) - - return nil -} - -// OnEmptySlot is called when a slot expires without an associated block. -func (c *Container) OnEmptySlot(ctx context.Context, cb func(ctx context.Context, epoch phase0.Epoch, slot Slot) error) error { - c.callbacksEmptySlot = append(c.callbacksEmptySlot, cb) - - return nil -} diff --git a/pkg/exporter/consensus/beacon/state/types.go b/pkg/exporter/consensus/beacon/state/types.go deleted file mode 100644 index 0a9f4c2..0000000 --- a/pkg/exporter/consensus/beacon/state/types.go +++ /dev/null @@ -1,13 +0,0 @@ -package state - -import ( - "time" - - v1 "github.com/attestantio/go-eth2-client/api/v1" -) - -// BlockTimeCalculatorBundle is a bundle of data to help with calculating proposer delay. -type BlockTimeCalculatorBundle struct { - Genesis *v1.Genesis - SecondsPerSlot time.Duration -} diff --git a/pkg/exporter/consensus/beacon/subscriber.go b/pkg/exporter/consensus/beacon/subscriber.go deleted file mode 100644 index cd97e7a..0000000 --- a/pkg/exporter/consensus/beacon/subscriber.go +++ /dev/null @@ -1,119 +0,0 @@ -package beacon - -import ( - "context" - - v1 "github.com/attestantio/go-eth2-client/api/v1" - "github.com/attestantio/go-eth2-client/spec/phase0" - "github.com/nats-io/nats.go" -) - -func (n *node) handleSubscriberError(err error, topic string) { - if err != nil { - n.log.WithError(err).WithField("topic", topic).Error("Subscriber error") - } -} - -// Official Beacon events -func (n *node) OnBlock(ctx context.Context, handler func(ctx context.Context, event *v1.BlockEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicBlock, func(event *v1.BlockEvent) { - n.handleSubscriberError(handler(ctx, event), topicBlock) - }) -} - -func (n *node) OnAttestation(ctx context.Context, handler func(ctx context.Context, event *phase0.Attestation) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicAttestation, func(event *phase0.Attestation) { - n.handleSubscriberError(handler(ctx, event), topicAttestation) - }) -} - -func (n *node) OnChainReOrg(ctx context.Context, handler func(ctx context.Context, event *v1.ChainReorgEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicChainReorg, func(event *v1.ChainReorgEvent) { - n.handleSubscriberError(handler(ctx, event), topicChainReorg) - }) -} - -func (n *node) OnFinalizedCheckpoint(ctx context.Context, handler func(ctx context.Context, event *v1.FinalizedCheckpointEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicFinalizedCheckpoint, func(event *v1.FinalizedCheckpointEvent) { - n.handleSubscriberError(handler(ctx, event), topicFinalizedCheckpoint) - }) -} - -func (n *node) OnHead(ctx context.Context, handler func(ctx context.Context, event *v1.HeadEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicHead, func(event *v1.HeadEvent) { - n.handleSubscriberError(handler(ctx, event), topicHead) - }) -} - -func (n *node) OnVoluntaryExit(ctx context.Context, handler func(ctx context.Context, event *phase0.VoluntaryExit) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicVoluntaryExit, func(event *phase0.VoluntaryExit) { - n.handleSubscriberError(handler(ctx, event), topicVoluntaryExit) - }) -} - -func (n *node) OnEvent(ctx context.Context, handler func(ctx context.Context, event *v1.Event) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicEvent, func(event *v1.Event) { - n.handleSubscriberError(handler(ctx, event), topicEvent) - }) -} - -// Custom Events -func (n *node) OnEpochChanged(ctx context.Context, handler func(ctx context.Context, event *EpochChangedEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicEpochChanged, func(event *EpochChangedEvent) { - n.handleSubscriberError(handler(ctx, event), topicEpochChanged) - }) -} - -func (n *node) OnSlotChanged(ctx context.Context, handler func(ctx context.Context, event *SlotChangedEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicSlotChanged, func(event *SlotChangedEvent) { - n.handleSubscriberError(handler(ctx, event), topicSlotChanged) - }) -} - -func (n *node) OnEpochSlotChanged(ctx context.Context, handler func(ctx context.Context, event *EpochSlotChangedEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicEpochSlotChanged, func(event *EpochSlotChangedEvent) { - n.handleSubscriberError(handler(ctx, event), topicEpochSlotChanged) - }) -} - -func (n *node) OnBlockInserted(ctx context.Context, handler func(ctx context.Context, event *BlockInsertedEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicBlockInserted, func(event *BlockInsertedEvent) { - n.handleSubscriberError(handler(ctx, event), topicBlockInserted) - }) -} - -func (n *node) OnReady(ctx context.Context, handler func(ctx context.Context, event *ReadyEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicReady, func(event *ReadyEvent) { - n.handleSubscriberError(handler(ctx, event), topicReady) - }) -} - -func (n *node) OnSyncStatus(ctx context.Context, handler func(ctx context.Context, event *SyncStatusEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicSyncStatus, func(event *SyncStatusEvent) { - n.handleSubscriberError(handler(ctx, event), topicSyncStatus) - }) -} - -func (n *node) OnNodeVersionUpdated(ctx context.Context, handler func(ctx context.Context, event *NodeVersionUpdatedEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicNodeVersionUpdated, func(event *NodeVersionUpdatedEvent) { - n.handleSubscriberError(handler(ctx, event), topicNodeVersionUpdated) - }) -} - -func (n *node) OnPeersUpdated(ctx context.Context, handler func(ctx context.Context, event *PeersUpdatedEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicPeersUpdated, func(event *PeersUpdatedEvent) { - n.handleSubscriberError(handler(ctx, event), topicPeersUpdated) - }) -} - -func (n *node) OnSpecUpdated(ctx context.Context, handler func(ctx context.Context, event *SpecUpdatedEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicSpecUpdated, func(event *SpecUpdatedEvent) { - n.handleSubscriberError(handler(ctx, event), topicSpecUpdated) - }) -} - -func (n *node) OnEmptySlot(ctx context.Context, handler func(ctx context.Context, event *EmptySlotEvent) error) (*nats.Subscription, error) { - return n.broker.Subscribe(topicEmptySlot, func(event *EmptySlotEvent) { - n.handleSubscriberError(handler(ctx, event), topicEmptySlot) - }) -} diff --git a/pkg/exporter/consensus/beacon/subscriptions.go b/pkg/exporter/consensus/beacon/subscriptions.go deleted file mode 100644 index 3b4e0b3..0000000 --- a/pkg/exporter/consensus/beacon/subscriptions.go +++ /dev/null @@ -1,201 +0,0 @@ -package beacon - -import ( - "context" - "errors" - "fmt" - "time" - - eth2client "github.com/attestantio/go-eth2-client" - v1 "github.com/attestantio/go-eth2-client/api/v1" - "github.com/attestantio/go-eth2-client/spec/phase0" -) - -func (n *node) ensureBeaconSubscription(ctx context.Context) error { - for { - select { - case <-ctx.Done(): - return ctx.Err() - case <-time.After(time.Second * 5): - if n.client == nil { - continue - } - - // Only resubscribe if we haven't received an event after 5 minutes. - if time.Since(n.lastEventTime) < (5 * time.Minute) { - continue - } - - // Don't resubscribe if we are pre-genesis. - if n.genesis == nil { - continue - } - - timeTillGenesis := time.Until(n.genesis.GenesisTime) - if timeTillGenesis > 0 { - n.log.WithField("time_until_genesis", timeTillGenesis.String()).Info("We are pre-genesis, not subscribing upstream yet...") - - time.Sleep(timeTillGenesis) - } - - n.log. - WithField("last_event_time", n.lastEventTime.Local().String()). - Info("Haven't received any events for 5 minutes, re-subscribing") - - if time.Since(n.lastEventTime) > time.Minute*5 { - if err := n.subscribeToBeaconEvents(ctx); err != nil { - n.log.WithError(err).Error("Failed to subscribe to beacon") - } - - time.Sleep(time.Minute * 15) - } - } - } -} - -func (n *node) subscribeToBeaconEvents(ctx context.Context) error { - provider, isProvider := n.client.(eth2client.EventsProvider) - if !isProvider { - return errors.New("client does not implement eth2client.Subscriptions") - } - - topics := []string{} - - for key, supported := range v1.SupportedEventTopics { - if key == "contribution_and_proof" { - continue - } - - if supported { - topics = append(topics, key) - } - } - - if err := provider.Events(ctx, topics, func(event *v1.Event) { - n.lastEventTime = time.Now() - - if err := n.handleEvent(ctx, event); err != nil { - n.log.Errorf("Failed to handle event: %v", err) - } - }); err != nil { - return err - } - - return nil -} - -func (n *node) handleEvent(ctx context.Context, event *v1.Event) error { - if err := n.publishEvent(ctx, event); err != nil { - n.log.WithError(err).Error("Failed to publish raw event") - } - - // If we are syncing, only forward on "head" and "block" events - if n.syncing.IsSyncing { - if event.Topic != topicBlock && event.Topic != topicHead { - return nil - } - } - - switch event.Topic { - case topicAttestation: - return n.handleAttestation(ctx, event) - case topicBlock: - return n.handleBlock(ctx, event) - case topicChainReorg: - return n.handleChainReorg(ctx, event) - case topicFinalizedCheckpoint: - return n.handleFinalizedCheckpoint(ctx, event) - case topicHead: - return n.handleHead(ctx, event) - case topicVoluntaryExit: - return n.handleVoluntaryExit(ctx, event) - case topicContributionAndProof: - return n.handleContributionAndProof(ctx, event) - - default: - return fmt.Errorf("unknown event topic %s", event.Topic) - } -} - -func (n *node) handleAttestation(ctx context.Context, event *v1.Event) error { - attestation, valid := event.Data.(*phase0.Attestation) - if !valid { - return errors.New("invalid attestation event") - } - - if err := n.publishAttestation(ctx, attestation); err != nil { - return err - } - - return nil -} - -func (n *node) handleBlock(ctx context.Context, event *v1.Event) error { - block, valid := event.Data.(*v1.BlockEvent) - if !valid { - return errors.New("invalid block event") - } - - if err := n.publishBlock(ctx, block); err != nil { - return err - } - - return nil -} - -func (n *node) handleChainReorg(ctx context.Context, event *v1.Event) error { - chainReorg, valid := event.Data.(*v1.ChainReorgEvent) - if !valid { - return errors.New("invalid chain reorg event") - } - - if err := n.publishChainReOrg(ctx, chainReorg); err != nil { - return err - } - - return nil -} - -func (n *node) handleFinalizedCheckpoint(ctx context.Context, event *v1.Event) error { - checkpoint, valid := event.Data.(*v1.FinalizedCheckpointEvent) - if !valid { - return errors.New("invalid checkpoint event") - } - - if err := n.publishFinalizedCheckpoint(ctx, checkpoint); err != nil { - return err - } - - return nil -} - -func (n *node) handleHead(ctx context.Context, event *v1.Event) error { - head, valid := event.Data.(*v1.HeadEvent) - if !valid { - return errors.New("invalid head event") - } - - if err := n.publishHead(ctx, head); err != nil { - return err - } - - return nil -} - -func (n *node) handleVoluntaryExit(ctx context.Context, event *v1.Event) error { - exit, valid := event.Data.(*phase0.VoluntaryExit) - if !valid { - return errors.New("invalid voluntary exit event") - } - - if err := n.publishVoluntaryExit(ctx, exit); err != nil { - return err - } - - return nil -} - -func (n *node) handleContributionAndProof(ctx context.Context, event *v1.Event) error { - // Do nothing for now - return nil -} diff --git a/pkg/exporter/consensus/jobs/beacon.go b/pkg/exporter/consensus/jobs/beacon.go index 1f5e103..32c24b6 100644 --- a/pkg/exporter/consensus/jobs/beacon.go +++ b/pkg/exporter/consensus/jobs/beacon.go @@ -9,9 +9,9 @@ import ( eth2client "github.com/attestantio/go-eth2-client" v1 "github.com/attestantio/go-eth2-client/api/v1" "github.com/attestantio/go-eth2-client/spec" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/api" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon" "github.com/prometheus/client_golang/prometheus" + "github.com/samcm/beacon" + "github.com/samcm/beacon/api" "github.com/sirupsen/logrus" ) @@ -221,28 +221,20 @@ func (b *Beacon) tick(ctx context.Context) { } func (b *Beacon) setupSubscriptions(ctx context.Context) error { - if _, err := b.beaconNode.OnBlockInserted(ctx, b.handleBlockInserted); err != nil { - return err - } + b.beaconNode.OnBlockInserted(ctx, b.handleBlockInserted) - if _, err := b.beaconNode.OnChainReOrg(ctx, b.handleChainReorg); err != nil { - return err - } + b.beaconNode.OnChainReOrg(ctx, b.handleChainReorg) - if _, err := b.beaconNode.OnEmptySlot(ctx, b.handleEmptySlot); err != nil { - return err - } + b.beaconNode.OnEmptySlot(ctx, b.handleEmptySlot) - if _, err := b.beaconNode.OnFinalizedCheckpoint(ctx, func(ctx context.Context, ev *v1.FinalizedCheckpointEvent) error { + b.beaconNode.OnFinalizedCheckpoint(ctx, func(ctx context.Context, ev *v1.FinalizedCheckpointEvent) error { // Sleep for 3 seconds to allow the beacon node to process the finalized checkpoint. time.Sleep(3 * time.Second) b.updateFinalizedCheckpoint(ctx) return nil - }); err != nil { - return err - } + }) return nil } diff --git a/pkg/exporter/consensus/jobs/event.go b/pkg/exporter/consensus/jobs/event.go index 61707ee..df626cd 100644 --- a/pkg/exporter/consensus/jobs/event.go +++ b/pkg/exporter/consensus/jobs/event.go @@ -6,8 +6,8 @@ import ( eth2client "github.com/attestantio/go-eth2-client" v1 "github.com/attestantio/go-eth2-client/api/v1" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon" "github.com/prometheus/client_golang/prometheus" + "github.com/samcm/beacon" "github.com/sirupsen/logrus" ) @@ -62,9 +62,7 @@ func (e *Event) Name() string { } func (e *Event) Start(ctx context.Context) error { - if _, err := e.beacon.OnEvent(ctx, e.HandleEvent); err != nil { - return err - } + e.beacon.OnEvent(ctx, e.HandleEvent) for { select { diff --git a/pkg/exporter/consensus/jobs/forks.go b/pkg/exporter/consensus/jobs/forks.go index f03edbe..cc1621b 100644 --- a/pkg/exporter/consensus/jobs/forks.go +++ b/pkg/exporter/consensus/jobs/forks.go @@ -3,8 +3,8 @@ package jobs import ( "context" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon" "github.com/prometheus/client_golang/prometheus" + "github.com/samcm/beacon" "github.com/sirupsen/logrus" "github.com/attestantio/go-eth2-client/spec/phase0" @@ -73,11 +73,9 @@ func (f *Forks) Name() string { } func (f *Forks) Start(ctx context.Context) error { - if _, err := f.beacon.OnBlockInserted(ctx, func(ctx context.Context, event *beacon.BlockInsertedEvent) error { + f.beacon.OnBlockInserted(ctx, func(ctx context.Context, event *beacon.BlockInsertedEvent) error { return f.calculateCurrent(ctx, event.Slot) - }); err != nil { - return err - } + }) return nil } diff --git a/pkg/exporter/consensus/jobs/general.go b/pkg/exporter/consensus/jobs/general.go index 91059dd..4f654da 100644 --- a/pkg/exporter/consensus/jobs/general.go +++ b/pkg/exporter/consensus/jobs/general.go @@ -3,9 +3,9 @@ package jobs import ( "context" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/api/types" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon" "github.com/prometheus/client_golang/prometheus" + "github.com/samcm/beacon" + "github.com/samcm/beacon/api/types" "github.com/sirupsen/logrus" ) @@ -72,14 +72,12 @@ func (g *General) Name() string { } func (g *General) Start(ctx context.Context) error { - if _, err := g.beacon.OnNodeVersionUpdated(ctx, func(ctx context.Context, event *beacon.NodeVersionUpdatedEvent) error { + g.beacon.OnNodeVersionUpdated(ctx, func(ctx context.Context, event *beacon.NodeVersionUpdatedEvent) error { g.observeNodeVersion(ctx, event.Version) return nil - }); err != nil { - return err - } + }) - if _, err := g.beacon.OnPeersUpdated(ctx, func(ctx context.Context, event *beacon.PeersUpdatedEvent) error { + g.beacon.OnPeersUpdated(ctx, func(ctx context.Context, event *beacon.PeersUpdatedEvent) error { g.Peers.Reset() for _, state := range types.PeerStates { @@ -95,9 +93,7 @@ func (g *General) Start(ctx context.Context) error { } return nil - }); err != nil { - return err - } + }) if err := g.initialFetch(ctx); err != nil { return err diff --git a/pkg/exporter/consensus/jobs/spec.go b/pkg/exporter/consensus/jobs/spec.go index 44786cd..09bbf62 100644 --- a/pkg/exporter/consensus/jobs/spec.go +++ b/pkg/exporter/consensus/jobs/spec.go @@ -5,9 +5,9 @@ import ( "math/big" "time" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon/state" "github.com/prometheus/client_golang/prometheus" + "github.com/samcm/beacon" + "github.com/samcm/beacon/state" "github.com/sirupsen/logrus" ) @@ -256,11 +256,9 @@ func (s *Spec) Name() string { } func (s *Spec) Start(ctx context.Context) error { - if _, err := s.beacon.OnSpecUpdated(ctx, func(ctx context.Context, event *beacon.SpecUpdatedEvent) error { + s.beacon.OnSpecUpdated(ctx, func(ctx context.Context, event *beacon.SpecUpdatedEvent) error { return s.observeSpec(ctx, event.Spec) - }); err != nil { - return err - } + }) s.tick(ctx) @@ -291,16 +289,16 @@ func (s *Spec) observeSpec(ctx context.Context, spec *state.Spec) error { s.DepositChainID.Set(float64(spec.DepositChainID)) s.MaxValidatorsPerCommittee.Set(float64(spec.MaxValidatorsPerCommittee)) //nolint:unconvert // false positive - s.SecondsPerEth1Block.Set(float64(spec.SecondsPerEth1Block.Seconds())) + s.SecondsPerEth1Block.Set(float64(spec.SecondsPerEth1Block.AsDuration().Seconds())) s.BaseRewardFactor.Set(float64(spec.BaseRewardFactor)) s.EpochsPerSyncCommitteePeriod.Set(float64(spec.EpochsPerSyncCommitteePeriod)) s.EffectiveBalanceIncrement.Set(float64(spec.EffectiveBalanceIncrement)) s.MaxAttestations.Set(float64(spec.MaxAttestations)) s.MinSyncCommitteeParticipants.Set(float64(spec.MinSyncCommitteeParticipants)) //nolint:unconvert // false positive - s.GenesisDelay.Set(float64(spec.GenesisDelay.Seconds())) + s.GenesisDelay.Set(float64(spec.GenesisDelay.AsDuration().Seconds())) //nolint:unconvert // false positive - s.SecondsPerSlot.Set(float64(spec.SecondsPerSlot.Seconds())) + s.SecondsPerSlot.Set(float64(spec.SecondsPerSlot.AsDuration().Seconds())) s.MaxEffectiveBalance.Set(float64(spec.MaxEffectiveBalance)) s.MaxDeposits.Set(float64(spec.MaxDeposits)) s.MinGenesisActiveValidatorCount.Set(float64(spec.MinGenesisActiveValidatorCount)) diff --git a/pkg/exporter/consensus/jobs/syncstatus.go b/pkg/exporter/consensus/jobs/syncstatus.go index 6d58b45..1147a90 100644 --- a/pkg/exporter/consensus/jobs/syncstatus.go +++ b/pkg/exporter/consensus/jobs/syncstatus.go @@ -3,8 +3,8 @@ package jobs import ( "context" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon" "github.com/prometheus/client_golang/prometheus" + "github.com/samcm/beacon" "github.com/sirupsen/logrus" ) @@ -80,7 +80,7 @@ func (s *Sync) Name() string { } func (s *Sync) Start(ctx context.Context) error { - if _, err := s.beacon.OnSyncStatus(ctx, func(ctx context.Context, event *beacon.SyncStatusEvent) error { + s.beacon.OnSyncStatus(ctx, func(ctx context.Context, event *beacon.SyncStatusEvent) error { status := event.State s.Distance.Set(float64(status.SyncDistance)) @@ -98,9 +98,7 @@ func (s *Sync) Start(ctx context.Context) error { s.Percentage.Set(percent) return nil - }); err != nil { - return err - } + }) return nil } diff --git a/pkg/exporter/consensus/jobs/topics.go b/pkg/exporter/consensus/jobs/topics.go deleted file mode 100644 index c50710f..0000000 --- a/pkg/exporter/consensus/jobs/topics.go +++ /dev/null @@ -1,13 +0,0 @@ -package jobs - -type EventTopic string - -const ( - EventTopicBlock = "block" - EventTopicHead = "head" - EventTopicAttestation = "attestation" - EventTopicChainReorg = "chain_reorg" - EventTopicFinalizedCheckpoint = "finalized_checkpoint" - EventTopicVoluntaryExit = "voluntary_exit" - EventTopicContributionAndProof = "contribution_and_proof" -) diff --git a/pkg/exporter/consensus/metrics.go b/pkg/exporter/consensus/metrics.go index 3270774..4470905 100644 --- a/pkg/exporter/consensus/metrics.go +++ b/pkg/exporter/consensus/metrics.go @@ -4,10 +4,10 @@ import ( "context" eth2client "github.com/attestantio/go-eth2-client" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/api" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon" "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/jobs" "github.com/prometheus/client_golang/prometheus" + "github.com/samcm/beacon" + "github.com/samcm/beacon/api" "github.com/sirupsen/logrus" ) diff --git a/pkg/exporter/exporter.go b/pkg/exporter/exporter.go index b9e0476..7bc5ddf 100644 --- a/pkg/exporter/exporter.go +++ b/pkg/exporter/exporter.go @@ -11,8 +11,6 @@ import ( eth2client "github.com/attestantio/go-eth2-client" ehttp "github.com/attestantio/go-eth2-client/http" "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/api" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon" "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/disk" "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/execution" "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/pair" @@ -20,6 +18,8 @@ import ( "github.com/nats-io/nats.go" "github.com/prometheus/client_golang/prometheus/promhttp" "github.com/rs/zerolog" + "github.com/samcm/beacon" + "github.com/samcm/beacon/api" "github.com/sirupsen/logrus" ) @@ -163,12 +163,10 @@ func (e *exporter) Serve(ctx context.Context, port int) error { e.log.Fatal(err) } - if _, err := e.beacon.OnReady(ctx, func(ctx context.Context, event *beacon.ReadyEvent) error { + e.beacon.OnReady(ctx, func(ctx context.Context, event *beacon.ReadyEvent) error { e.pairMetrics.StartAsync(ctx) return nil - }); err != nil { - e.log.WithError(err).Error("Failed to subscribe to beacon node ready event") - } + }) if err := e.startPairExporter(ctx); err != nil { e.log.WithError(err).Error("failed to start pair metrics") @@ -188,13 +186,11 @@ func (e *exporter) Serve(ctx context.Context, port int) error { e.log.Fatal(err) } - if _, err := e.beacon.OnReady(ctx, func(ctx context.Context, event *beacon.ReadyEvent) error { + e.beacon.OnReady(ctx, func(ctx context.Context, event *beacon.ReadyEvent) error { e.consensus.StartAsync(ctx) return nil - }); err != nil { - e.log.WithError(err).Error("Failed to subscribe to beacon node ready event") - } + }) e.beacon.StartAsync(ctx) } @@ -212,8 +208,16 @@ func (e *exporter) bootstrapConsensusClients(ctx context.Context) error { } e.client = client - e.api = api.NewConsensusClient(ctx, e.log, e.config.Consensus.URL) - e.beacon = beacon.NewNode(ctx, e.log, e.api, e.client, e.brokerConn) + e.api = api.NewConsensusClient(ctx, e.log, e.config.Consensus.URL, *http.DefaultClient) + + opts := *beacon.DefaultOptions(). + EnableDefaultBeaconSubscription(). + DisablePrometheusMetrics() // We can derive our own metrics + + e.beacon = beacon.NewNode(e.log, &beacon.Config{ + Addr: e.config.Consensus.URL, + Name: e.config.Consensus.Name, + }, "beacon", opts) return nil } diff --git a/pkg/exporter/pair/pair.go b/pkg/exporter/pair/pair.go index 6549c55..ccb707a 100644 --- a/pkg/exporter/pair/pair.go +++ b/pkg/exporter/pair/pair.go @@ -7,9 +7,9 @@ import ( "time" "github.com/ethereum/go-ethereum/ethclient" - "github.com/ethpandaops/ethereum-metrics-exporter/pkg/exporter/consensus/beacon" "github.com/onrik/ethrpc" "github.com/prometheus/client_golang/prometheus" + "github.com/samcm/beacon" "github.com/sirupsen/logrus" )