diff --git a/apps/evm/single/cmd/run.go b/apps/evm/single/cmd/run.go index 53725e8777..a82114d4e3 100644 --- a/apps/evm/single/cmd/run.go +++ b/apps/evm/single/cmd/run.go @@ -19,7 +19,6 @@ import ( rollcmd "github.com/evstack/ev-node/pkg/cmd" "github.com/evstack/ev-node/pkg/config" genesispkg "github.com/evstack/ev-node/pkg/genesis" - "github.com/evstack/ev-node/pkg/p2p" "github.com/evstack/ev-node/pkg/p2p/key" "github.com/evstack/ev-node/pkg/store" ) @@ -95,12 +94,7 @@ var RunCmd = &cobra.Command{ return err } - p2pClient, err := p2p.NewClient(nodeConfig.P2P, nodeKey.PrivKey, datastore, genesis.ChainID, logger, nil) - if err != nil { - return err - } - - return rollcmd.StartNode(logger, cmd, executor, sequencer, &daJrpc.DA, p2pClient, datastore, nodeConfig, genesis, node.NodeOptions{}) + return rollcmd.StartNode(logger, cmd, executor, sequencer, &daJrpc.DA, nodeKey, datastore, nodeConfig, genesis, node.NodeOptions{}) }, } diff --git a/apps/evm/single/go.mod b/apps/evm/single/go.mod index d81344ce7d..5571199bd9 100644 --- a/apps/evm/single/go.mod +++ b/apps/evm/single/go.mod @@ -28,9 +28,11 @@ require ( connectrpc.com/grpcreflect v1.3.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/StackExchange/wmi v1.2.1 // indirect + github.com/armon/go-metrics v0.4.1 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.20.0 // indirect + github.com/boltdb/bolt v1.3.1 // indirect github.com/celestiaorg/go-libp2p-messenger v0.2.2 // indirect github.com/celestiaorg/go-square/v3 v3.0.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -47,6 +49,7 @@ require ( github.com/emicklei/dot v1.6.2 // indirect github.com/ethereum/c-kzg-4844/v2 v2.1.3 // indirect github.com/ethereum/go-verkle v0.2.2 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/ferranbt/fastssz v0.1.4 // indirect github.com/filecoin-project/go-clock v0.1.0 // indirect github.com/filecoin-project/go-jsonrpc v0.8.0 // indirect @@ -68,8 +71,14 @@ require ( github.com/google/gopacket v1.1.19 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect + github.com/hashicorp/go-hclog v1.6.2 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-msgpack v0.5.5 // indirect + github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/hashicorp/raft v1.7.1 // indirect + github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e // indirect github.com/holiman/uint256 v1.3.2 // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect diff --git a/apps/evm/single/go.sum b/apps/evm/single/go.sum index d5b71b651f..4a99d3add7 100644 --- a/apps/evm/single/go.sum +++ b/apps/evm/single/go.sum @@ -12,6 +12,8 @@ dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1 dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= @@ -22,14 +24,25 @@ github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjC github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-metrics v0.3.8/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/celestiaorg/go-libp2p-messenger v0.2.2 h1:osoUfqjss7vWTIZrrDSy953RjQz+ps/vBFE7bychLEc= @@ -39,8 +52,11 @@ github.com/celestiaorg/go-square/v3 v3.0.2/go.mod h1:oFReMLsSDMRs82ICFEeFQFCqNvw github.com/celestiaorg/utils v0.1.0 h1:WsP3O8jF7jKRgLNFmlDCwdThwOFMFxg0MnqhkLFVxPo= github.com/celestiaorg/utils v0.1.0/go.mod h1:vQTh7MHnvpIeCQZ2/Ph+w7K1R2UerDheZbgJEJD2hSU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= @@ -105,6 +121,9 @@ github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cn github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/evstack/ev-node/core v1.0.0-beta.3 h1:01K2Ygm3puX4m2OBxvg/HDxu+he54jeNv+KDmpgujFc= github.com/evstack/ev-node/core v1.0.0-beta.3/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg= github.com/filecoin-project/go-clock v0.1.0 h1:SFbYIM75M8NnFm1yMHhN9Ahy3W5bEZV9gd6MPfXbKVU= @@ -126,8 +145,12 @@ github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +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/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= +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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -136,6 +159,7 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -183,6 +207,7 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -201,10 +226,30 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= 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/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I= +github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0= +github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= +github.com/hashicorp/raft v1.7.1 h1:ytxsNx4baHsRZrhUcbt3+79zc4ly8qm7pi0393pSchY= +github.com/hashicorp/raft v1.7.1/go.mod h1:hUeiEwQQR/Nk2iKDD0dkEhklSsu3jcAcqvPzPoZSAEM= +github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e h1:SK4y8oR4ZMHPvwVHryKI88kJPJda4UyWYvG5A6iEQxc= +github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e/go.mod h1:EMz/UIuG93P0MBeHh6CbXQAEe8ckVJLZjhD17lBzK5Q= github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db h1:IZUYC/xb3giYwBLMnr8d0TGTzPKFGNTCGgGLoyeX330= github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db/go.mod h1:xTEYN9KCHxuYHs+NmrmzFcnvHMzLLNiGFafCb1n3Mfg= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= @@ -239,19 +284,23 @@ github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABo github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienrbrt/go-header v0.0.0-20251008134330-747c8c192fa8 h1:F+gOiipBxG43s+Ho+ri9T8IwumjWjp1XUon4DLWjxfQ= github.com/julienrbrt/go-header v0.0.0-20251008134330-747c8c192fa8/go.mod h1:eX9iTSPthVEAlEDLux40ZT/olXPGhpxHd+mEzJeDhd0= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.6 h1:Jb0h04599eq/CY7rB5YEqPS83HmRfHP2azkxMN2rFtU= github.com/koron/go-ssdp v0.0.6/go.mod h1:0R9LfRJGek1zWTjN3JUNlm5INCDYGpRDfAptnct63fI= +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.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -299,9 +348,13 @@ github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -327,7 +380,9 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/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= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -356,11 +411,14 @@ github.com/multiformats/go-varint v0.1.0 h1:i2wqFp4sdl3IcIxfAonHQV9qU5OsZ4Ts9IOo github.com/multiformats/go-varint v0.1.0/go.mod h1:5KVAVXegtfmNQQm/lCY+ATvDzvJJhSkUlGQV9wgObdI= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= 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/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= @@ -409,6 +467,7 @@ github.com/pion/turn/v4 v4.0.2 h1:ZqgQ3+MjP32ug30xAbD6Mn+/K4Sxi3SdNOTFf+7mpps= github.com/pion/turn/v4 v4.0.2/go.mod h1:pMMKP/ieNAG/fN5cZiN4SDuyKsXtNTr0ccN7IToA1zs= github.com/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54= github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZsGN+8U= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -418,16 +477,29 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.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= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= github.com/prysmaticlabs/gohashtree v0.0.4-beta h1:H/EbCuXPeTV3lpKeXGPpEV9gsUpkqOOVnWapUyeWro4= @@ -480,6 +552,8 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go. github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= +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/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= @@ -502,13 +576,16 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= github.com/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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -526,6 +603,7 @@ github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFA github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/urfave/cli v1.22.10 h1:p8Fspmz3iTctJstry1PYS3HVdllxnEzTEsgIgtxTrCk= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w= @@ -573,6 +651,7 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -607,11 +686,14 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -644,16 +726,25 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 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= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/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-20220503163025-988cb79eb6c6/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -747,7 +838,9 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +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= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= @@ -755,6 +848,8 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/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= diff --git a/apps/grpc/single/cmd/run.go b/apps/grpc/single/cmd/run.go index b99e3b2fcd..80348ae116 100644 --- a/apps/grpc/single/cmd/run.go +++ b/apps/grpc/single/cmd/run.go @@ -14,7 +14,6 @@ import ( rollcmd "github.com/evstack/ev-node/pkg/cmd" "github.com/evstack/ev-node/pkg/config" rollgenesis "github.com/evstack/ev-node/pkg/genesis" - "github.com/evstack/ev-node/pkg/p2p" "github.com/evstack/ev-node/pkg/p2p/key" "github.com/evstack/ev-node/pkg/store" "github.com/evstack/ev-node/sequencers/single" @@ -100,14 +99,8 @@ The execution client must implement the Evolve execution gRPC interface.`, return err } - // Create P2P client - p2pClient, err := p2p.NewClient(nodeConfig.P2P, nodeKey.PrivKey, datastore, genesis.ChainID, logger, nil) - if err != nil { - return err - } - // Start the node - return rollcmd.StartNode(logger, cmd, executor, sequencer, &daJrpc.DA, p2pClient, datastore, nodeConfig, genesis, node.NodeOptions{}) + return rollcmd.StartNode(logger, cmd, executor, sequencer, &daJrpc.DA, nodeKey, datastore, nodeConfig, genesis, node.NodeOptions{}) }, } diff --git a/apps/grpc/single/go.mod b/apps/grpc/single/go.mod index 09e2d2ae43..7bd66b6d31 100644 --- a/apps/grpc/single/go.mod +++ b/apps/grpc/single/go.mod @@ -14,8 +14,10 @@ require ( require ( connectrpc.com/connect v1.19.0 // indirect connectrpc.com/grpcreflect v1.3.0 // indirect + github.com/armon/go-metrics v0.4.1 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/boltdb/bolt v1.3.1 // indirect github.com/celestiaorg/go-header v0.7.3 // indirect github.com/celestiaorg/go-libp2p-messenger v0.2.2 // indirect github.com/celestiaorg/go-square/v3 v3.0.2 // indirect @@ -26,6 +28,7 @@ require ( github.com/dgraph-io/badger/v4 v4.5.1 // indirect github.com/dgraph-io/ristretto/v2 v2.1.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/fatih/color v1.13.0 // indirect github.com/filecoin-project/go-clock v0.1.0 // indirect github.com/filecoin-project/go-jsonrpc v0.8.0 // indirect github.com/flynn/noise v1.1.0 // indirect @@ -42,8 +45,14 @@ require ( github.com/google/gopacket v1.1.19 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect + github.com/hashicorp/go-hclog v1.6.2 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-msgpack v0.5.5 // indirect + github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/hashicorp/raft v1.7.1 // indirect + github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/boxo v0.35.0 // indirect diff --git a/apps/grpc/single/go.sum b/apps/grpc/single/go.sum index 339fc124ca..0fafd1d092 100644 --- a/apps/grpc/single/go.sum +++ b/apps/grpc/single/go.sum @@ -12,14 +12,27 @@ dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1 dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-metrics v0.3.8/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/celestiaorg/go-header v0.7.3 h1:3+kIa+YXT789gPGRh3a55qmdYq3yTTBIqTyum26AvN0= @@ -31,8 +44,11 @@ github.com/celestiaorg/go-square/v3 v3.0.2/go.mod h1:oFReMLsSDMRs82ICFEeFQFCqNvw github.com/celestiaorg/utils v0.1.0 h1:WsP3O8jF7jKRgLNFmlDCwdThwOFMFxg0MnqhkLFVxPo= github.com/celestiaorg/utils v0.1.0/go.mod h1:vQTh7MHnvpIeCQZ2/Ph+w7K1R2UerDheZbgJEJD2hSU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -64,6 +80,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evstack/ev-node/core v1.0.0-beta.3 h1:01K2Ygm3puX4m2OBxvg/HDxu+he54jeNv+KDmpgujFc= github.com/evstack/ev-node/core v1.0.0-beta.3/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/filecoin-project/go-clock v0.1.0 h1:SFbYIM75M8NnFm1yMHhN9Ahy3W5bEZV9gd6MPfXbKVU= github.com/filecoin-project/go-clock v0.1.0/go.mod h1:4uB/O4PvOjlx1VCMdZ9MyDZXRm//gkj1ELEbxfI1AZs= github.com/filecoin-project/go-jsonrpc v0.8.0 h1:2yqlN3Vd8Gx5UtA3fib7tQu2aW1cSOJt253LEBWExo4= @@ -81,13 +99,18 @@ github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +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/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= +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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -127,6 +150,7 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -143,10 +167,30 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I= +github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0= +github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= +github.com/hashicorp/raft v1.7.1 h1:ytxsNx4baHsRZrhUcbt3+79zc4ly8qm7pi0393pSchY= +github.com/hashicorp/raft v1.7.1/go.mod h1:hUeiEwQQR/Nk2iKDD0dkEhklSsu3jcAcqvPzPoZSAEM= +github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e h1:SK4y8oR4ZMHPvwVHryKI88kJPJda4UyWYvG5A6iEQxc= +github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e/go.mod h1:EMz/UIuG93P0MBeHh6CbXQAEe8ckVJLZjhD17lBzK5Q= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -175,17 +219,21 @@ github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABo github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.6 h1:Jb0h04599eq/CY7rB5YEqPS83HmRfHP2azkxMN2rFtU= github.com/koron/go-ssdp v0.0.6/go.mod h1:0R9LfRJGek1zWTjN3JUNlm5INCDYGpRDfAptnct63fI= +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.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -231,8 +279,12 @@ github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -253,7 +305,9 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/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= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -282,9 +336,12 @@ github.com/multiformats/go-varint v0.1.0 h1:i2wqFp4sdl3IcIxfAonHQV9qU5OsZ4Ts9IOo github.com/multiformats/go-varint v0.1.0/go.mod h1:5KVAVXegtfmNQQm/lCY+ATvDzvJJhSkUlGQV9wgObdI= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= @@ -331,6 +388,7 @@ github.com/pion/turn/v4 v4.0.2 h1:ZqgQ3+MjP32ug30xAbD6Mn+/K4Sxi3SdNOTFf+7mpps= github.com/pion/turn/v4 v4.0.2/go.mod h1:pMMKP/ieNAG/fN5cZiN4SDuyKsXtNTr0ccN7IToA1zs= github.com/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54= github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZsGN+8U= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -340,16 +398,29 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.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= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= @@ -392,6 +463,8 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go. github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= +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/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= @@ -414,13 +487,16 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= github.com/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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -430,6 +506,7 @@ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= @@ -472,6 +549,7 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -506,11 +584,14 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -543,15 +624,24 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 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= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/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-20220503163025-988cb79eb6c6/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -644,12 +734,16 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +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= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/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= diff --git a/apps/testapp/cmd/run.go b/apps/testapp/cmd/run.go index 061b8075ca..505fdd5c05 100644 --- a/apps/testapp/cmd/run.go +++ b/apps/testapp/cmd/run.go @@ -13,7 +13,6 @@ import ( "github.com/evstack/ev-node/node" rollcmd "github.com/evstack/ev-node/pkg/cmd" genesispkg "github.com/evstack/ev-node/pkg/genesis" - "github.com/evstack/ev-node/pkg/p2p" "github.com/evstack/ev-node/pkg/p2p/key" "github.com/evstack/ev-node/pkg/store" "github.com/evstack/ev-node/sequencers/single" @@ -106,11 +105,6 @@ var RunCmd = &cobra.Command{ return err } - p2pClient, err := p2p.NewClient(nodeConfig.P2P, nodeKey.PrivKey, datastore, genesis.ChainID, logger, p2p.NopMetrics()) - if err != nil { - return err - } - - return rollcmd.StartNode(logger, cmd, executor, sequencer, &daJrpc.DA, p2pClient, datastore, nodeConfig, genesis, node.NodeOptions{}) + return rollcmd.StartNode(logger, cmd, executor, sequencer, &daJrpc.DA, nodeKey, datastore, nodeConfig, genesis, node.NodeOptions{}) }, } diff --git a/apps/testapp/go.mod b/apps/testapp/go.mod index 7b7b48fb12..045a732e89 100644 --- a/apps/testapp/go.mod +++ b/apps/testapp/go.mod @@ -24,8 +24,10 @@ require ( require ( connectrpc.com/connect v1.19.0 // indirect connectrpc.com/grpcreflect v1.3.0 // indirect + github.com/armon/go-metrics v0.4.1 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/boltdb/bolt v1.3.1 // indirect github.com/celestiaorg/go-libp2p-messenger v0.2.2 // indirect github.com/celestiaorg/go-square/v3 v3.0.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect @@ -35,6 +37,7 @@ require ( github.com/dgraph-io/badger/v4 v4.5.1 // indirect github.com/dgraph-io/ristretto/v2 v2.1.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/fatih/color v1.13.0 // indirect github.com/filecoin-project/go-clock v0.1.0 // indirect github.com/filecoin-project/go-jsonrpc v0.8.0 // indirect github.com/flynn/noise v1.1.0 // indirect @@ -51,8 +54,14 @@ require ( github.com/google/gopacket v1.1.19 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect + github.com/hashicorp/go-hclog v1.6.2 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-msgpack v0.5.5 // indirect + github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect + github.com/hashicorp/raft v1.7.1 // indirect + github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e // indirect github.com/huin/goupnp v1.3.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/ipfs/boxo v0.35.0 // indirect diff --git a/apps/testapp/go.sum b/apps/testapp/go.sum index 6b2c55b66b..93b1810034 100644 --- a/apps/testapp/go.sum +++ b/apps/testapp/go.sum @@ -12,14 +12,27 @@ dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1 dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-metrics v0.3.8/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/celestiaorg/go-libp2p-messenger v0.2.2 h1:osoUfqjss7vWTIZrrDSy953RjQz+ps/vBFE7bychLEc= @@ -29,8 +42,11 @@ github.com/celestiaorg/go-square/v3 v3.0.2/go.mod h1:oFReMLsSDMRs82ICFEeFQFCqNvw github.com/celestiaorg/utils v0.1.0 h1:WsP3O8jF7jKRgLNFmlDCwdThwOFMFxg0MnqhkLFVxPo= github.com/celestiaorg/utils v0.1.0/go.mod h1:vQTh7MHnvpIeCQZ2/Ph+w7K1R2UerDheZbgJEJD2hSU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -62,6 +78,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evstack/ev-node/core v1.0.0-beta.3 h1:01K2Ygm3puX4m2OBxvg/HDxu+he54jeNv+KDmpgujFc= github.com/evstack/ev-node/core v1.0.0-beta.3/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/filecoin-project/go-clock v0.1.0 h1:SFbYIM75M8NnFm1yMHhN9Ahy3W5bEZV9gd6MPfXbKVU= github.com/filecoin-project/go-clock v0.1.0/go.mod h1:4uB/O4PvOjlx1VCMdZ9MyDZXRm//gkj1ELEbxfI1AZs= github.com/filecoin-project/go-jsonrpc v0.8.0 h1:2yqlN3Vd8Gx5UtA3fib7tQu2aW1cSOJt253LEBWExo4= @@ -79,13 +97,18 @@ github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +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/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= +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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -125,6 +148,7 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -141,10 +165,30 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I= +github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0= +github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= +github.com/hashicorp/raft v1.7.1 h1:ytxsNx4baHsRZrhUcbt3+79zc4ly8qm7pi0393pSchY= +github.com/hashicorp/raft v1.7.1/go.mod h1:hUeiEwQQR/Nk2iKDD0dkEhklSsu3jcAcqvPzPoZSAEM= +github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e h1:SK4y8oR4ZMHPvwVHryKI88kJPJda4UyWYvG5A6iEQxc= +github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e/go.mod h1:EMz/UIuG93P0MBeHh6CbXQAEe8ckVJLZjhD17lBzK5Q= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -173,19 +217,23 @@ github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABo github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienrbrt/go-header v0.0.0-20251008134330-747c8c192fa8 h1:F+gOiipBxG43s+Ho+ri9T8IwumjWjp1XUon4DLWjxfQ= github.com/julienrbrt/go-header v0.0.0-20251008134330-747c8c192fa8/go.mod h1:eX9iTSPthVEAlEDLux40ZT/olXPGhpxHd+mEzJeDhd0= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.6 h1:Jb0h04599eq/CY7rB5YEqPS83HmRfHP2azkxMN2rFtU= github.com/koron/go-ssdp v0.0.6/go.mod h1:0R9LfRJGek1zWTjN3JUNlm5INCDYGpRDfAptnct63fI= +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.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -231,8 +279,12 @@ github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -253,7 +305,9 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/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= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -282,9 +336,12 @@ github.com/multiformats/go-varint v0.1.0 h1:i2wqFp4sdl3IcIxfAonHQV9qU5OsZ4Ts9IOo github.com/multiformats/go-varint v0.1.0/go.mod h1:5KVAVXegtfmNQQm/lCY+ATvDzvJJhSkUlGQV9wgObdI= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= @@ -331,6 +388,7 @@ github.com/pion/turn/v4 v4.0.2 h1:ZqgQ3+MjP32ug30xAbD6Mn+/K4Sxi3SdNOTFf+7mpps= github.com/pion/turn/v4 v4.0.2/go.mod h1:pMMKP/ieNAG/fN5cZiN4SDuyKsXtNTr0ccN7IToA1zs= github.com/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54= github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZsGN+8U= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -340,16 +398,29 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.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= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= @@ -392,6 +463,8 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go. github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= +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/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= @@ -414,13 +487,16 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= github.com/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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -430,6 +506,7 @@ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= @@ -472,6 +549,7 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -506,11 +584,14 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -543,15 +624,24 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 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= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/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-20220503163025-988cb79eb6c6/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -644,12 +734,16 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +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= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/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= diff --git a/block/components.go b/block/components.go index a157817703..0bae7da970 100644 --- a/block/components.go +++ b/block/components.go @@ -9,6 +9,7 @@ import ( "github.com/rs/zerolog" "github.com/evstack/ev-node/block/internal/cache" + "github.com/evstack/ev-node/block/internal/common" "github.com/evstack/ev-node/block/internal/executing" "github.com/evstack/ev-node/block/internal/reaping" "github.com/evstack/ev-node/block/internal/submitting" @@ -141,6 +142,7 @@ func NewSyncComponents( logger zerolog.Logger, metrics *Metrics, blockOpts BlockOptions, + raftNode common.RaftNode, ) (*Components, error) { cacheManager, err := cache.NewManager(config, store, logger) if err != nil { @@ -163,6 +165,7 @@ func NewSyncComponents( logger, blockOpts, errorCh, + raftNode, ) // Create DA submitter for sync nodes (no signer, only DA inclusion processing) @@ -204,6 +207,7 @@ func NewAggregatorComponents( logger zerolog.Logger, metrics *Metrics, blockOpts BlockOptions, + raftNode common.RaftNode, ) (*Components, error) { cacheManager, err := cache.NewManager(config, store, logger) if err != nil { @@ -227,6 +231,7 @@ func NewAggregatorComponents( logger, blockOpts, errorCh, + raftNode, ) if err != nil { return nil, fmt.Errorf("failed to create executor: %w", err) diff --git a/block/components_test.go b/block/components_test.go index c70b0e027c..d9c9b347ed 100644 --- a/block/components_test.go +++ b/block/components_test.go @@ -107,6 +107,7 @@ func TestNewSyncComponents_Creation(t *testing.T) { zerolog.Nop(), NopMetrics(), DefaultBlockOptions(), + nil, ) require.NoError(t, err) @@ -158,6 +159,7 @@ func TestNewAggregatorComponents_Creation(t *testing.T) { zerolog.Nop(), NopMetrics(), DefaultBlockOptions(), + nil, ) require.NoError(t, err) @@ -229,6 +231,7 @@ func TestExecutor_RealExecutionClientFailure_StopsNode(t *testing.T) { zerolog.Nop(), NopMetrics(), DefaultBlockOptions(), + nil, ) require.NoError(t, err) diff --git a/block/internal/common/raft.go b/block/internal/common/raft.go new file mode 100644 index 0000000000..30f97f55e7 --- /dev/null +++ b/block/internal/common/raft.go @@ -0,0 +1,22 @@ +package common + +import ( + "context" + + "github.com/evstack/ev-node/pkg/raft" +) + +// RaftNode interface for raft consensus integration +type RaftNode interface { + IsLeader() bool + NodeID() string + GetState() *raft.RaftBlockState + + Broadcast(ctx context.Context, state *raft.RaftBlockState) error + + SetApplyCallback(ch chan<- raft.RaftApplyMsg) + Shutdown() error + + AddPeer(nodeID, addr string) error + RemovePeer(nodeID string) error +} diff --git a/block/internal/executing/executor.go b/block/internal/executing/executor.go index 17e393eeb7..e54d1695a5 100644 --- a/block/internal/executing/executor.go +++ b/block/internal/executing/executor.go @@ -5,6 +5,7 @@ import ( "context" "errors" "fmt" + "reflect" "sync" "sync/atomic" "time" @@ -19,6 +20,7 @@ import ( coresequencer "github.com/evstack/ev-node/core/sequencer" "github.com/evstack/ev-node/pkg/config" "github.com/evstack/ev-node/pkg/genesis" + "github.com/evstack/ev-node/pkg/raft" "github.com/evstack/ev-node/pkg/signer" "github.com/evstack/ev-node/pkg/store" "github.com/evstack/ev-node/types" @@ -50,6 +52,9 @@ type Executor struct { genesis genesis.Genesis options common.BlockOptions + // Raft consensus + raftNode common.RaftNode + // State management lastState *atomic.Pointer[types.State] @@ -86,6 +91,7 @@ func NewExecutor( logger zerolog.Logger, options common.BlockOptions, errorCh chan<- error, + raftNode common.RaftNode, ) (*Executor, error) { if signer == nil { return nil, errors.New("signer cannot be nil") @@ -99,8 +105,11 @@ func NewExecutor( if !bytes.Equal(addr, genesis.ProposerAddress) { return nil, common.ErrNotProposer } + if raftNode != nil && reflect.ValueOf(raftNode).IsNil() { + raftNode = nil + } - return &Executor{ + e := &Executor{ store: store, exec: exec, sequencer: sequencer, @@ -113,10 +122,13 @@ func NewExecutor( dataBroadcaster: dataBroadcaster, options: options, lastState: &atomic.Pointer[types.State]{}, + raftNode: raftNode, txNotifyCh: make(chan struct{}, 1), errorCh: errorCh, logger: logger.With().Str("component", "executor").Logger(), - }, nil + } + + return e, nil } // Start begins the execution component @@ -309,6 +321,11 @@ func (e *Executor) produceBlock() error { } }() + // Check raft leadership if raft is enabled + if e.raftNode != nil && !e.raftNode.IsLeader() { + return errors.New("not raft leader") + } + currentState := e.getLastState() newHeight := currentState.LastBlockHeight + 1 @@ -416,6 +433,30 @@ func (e *Executor) produceBlock() error { e.setLastState(newState) e.metrics.Height.Set(float64(newState.LastBlockHeight)) + // Propose block to raft before p2p broadcast if raft is enabled + if e.raftNode != nil { + headerBytes, err := header.MarshalBinary() + if err != nil { + return fmt.Errorf("failed to marshal header: %w", err) + } + dataBytes, err := data.MarshalBinary() + if err != nil { + return fmt.Errorf("failed to marshal data: %w", err) + } + + raftState := &raft.RaftBlockState{ + Height: newHeight, + Hash: header.Hash(), + Timestamp: header.BaseHeader.Time, + Header: headerBytes, + Data: dataBytes, + } + if err := e.raftNode.Broadcast(e.ctx, raftState); err != nil { + return fmt.Errorf("failed to propose block to raft: %w", err) + } + e.logger.Debug().Uint64("height", newHeight).Msg("proposed block to raft") + } + // broadcast header and data to P2P network g, ctx := errgroup.WithContext(e.ctx) g.Go(func() error { return e.headerBroadcaster.WriteToStoreAndBroadcast(ctx, header) }) diff --git a/block/internal/executing/executor_lazy_test.go b/block/internal/executing/executor_lazy_test.go index 3609f10c55..5ab5461181 100644 --- a/block/internal/executing/executor_lazy_test.go +++ b/block/internal/executing/executor_lazy_test.go @@ -64,6 +64,7 @@ func TestLazyMode_ProduceBlockLogic(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, err) @@ -172,6 +173,7 @@ func TestRegularMode_ProduceBlockLogic(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, err) diff --git a/block/internal/executing/executor_logic_test.go b/block/internal/executing/executor_logic_test.go index 2ddd80996c..69d4cfe1bc 100644 --- a/block/internal/executing/executor_logic_test.go +++ b/block/internal/executing/executor_logic_test.go @@ -85,6 +85,7 @@ func TestProduceBlock_EmptyBatch_SetsEmptyDataHash(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, err) @@ -171,6 +172,7 @@ func TestPendingLimit_SkipsProduction(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, err) diff --git a/block/internal/executing/executor_restart_test.go b/block/internal/executing/executor_restart_test.go index f4b300df4b..948aa2203d 100644 --- a/block/internal/executing/executor_restart_test.go +++ b/block/internal/executing/executor_restart_test.go @@ -64,6 +64,7 @@ func TestExecutor_RestartUsesPendingHeader(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, err) @@ -182,6 +183,7 @@ func TestExecutor_RestartUsesPendingHeader(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, err) @@ -279,6 +281,7 @@ func TestExecutor_RestartNoPendingHeader(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, err) @@ -329,6 +332,7 @@ func TestExecutor_RestartNoPendingHeader(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, err) diff --git a/block/internal/executing/executor_test.go b/block/internal/executing/executor_test.go index b5f9e2f47a..1ecfdefd11 100644 --- a/block/internal/executing/executor_test.go +++ b/block/internal/executing/executor_test.go @@ -70,6 +70,7 @@ func TestExecutor_BroadcasterIntegration(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, err) @@ -120,6 +121,7 @@ func TestExecutor_NilBroadcasters(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, err) diff --git a/block/internal/reaping/reaper_test.go b/block/internal/reaping/reaper_test.go index f35c9618c1..0ed96bfc7e 100644 --- a/block/internal/reaping/reaper_test.go +++ b/block/internal/reaping/reaper_test.go @@ -55,6 +55,7 @@ func newTestExecutor(t *testing.T) *executing.Executor { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), // error channel + nil, ) require.NoError(t, err) diff --git a/block/internal/syncing/assert.go b/block/internal/syncing/assert.go new file mode 100644 index 0000000000..02cf4040a0 --- /dev/null +++ b/block/internal/syncing/assert.go @@ -0,0 +1,43 @@ +package syncing + +import ( + "errors" + "fmt" + + "github.com/evstack/ev-node/pkg/genesis" + "github.com/evstack/ev-node/types" +) + +func assertExpectedProposer(genesis genesis.Genesis, proposerAddr []byte) error { + if string(proposerAddr) != string(genesis.ProposerAddress) { + return fmt.Errorf("unexpected proposer: got %x, expected %x", + proposerAddr, genesis.ProposerAddress) + } + return nil +} + +func assertValidSignedData(signedData *types.SignedData, genesis genesis.Genesis) error { + if signedData == nil || signedData.Txs == nil { + return errors.New("empty signed data") + } + + if err := assertExpectedProposer(genesis, signedData.Signer.Address); err != nil { + return err + } + + dataBytes, err := signedData.Data.MarshalBinary() + if err != nil { + return fmt.Errorf("failed to get signed data payload: %w", err) + } + + valid, err := signedData.Signer.PubKey.Verify(dataBytes, signedData.Signature) + if err != nil { + return fmt.Errorf("failed to verify signature: %w", err) + } + + if !valid { + return fmt.Errorf("invalid signature") + } + + return nil +} diff --git a/block/internal/syncing/da_retriever.go b/block/internal/syncing/da_retriever.go index 40248019a4..0846d1a04f 100644 --- a/block/internal/syncing/da_retriever.go +++ b/block/internal/syncing/da_retriever.go @@ -290,38 +290,12 @@ func (r *DARetriever) tryDecodeData(bz []byte, daHeight uint64) *types.Data { // assertExpectedProposer validates the proposer address func (r *DARetriever) assertExpectedProposer(proposerAddr []byte) error { - if string(proposerAddr) != string(r.genesis.ProposerAddress) { - return fmt.Errorf("unexpected proposer: got %x, expected %x", - proposerAddr, r.genesis.ProposerAddress) - } - return nil + return assertExpectedProposer(r.genesis, proposerAddr) } // assertValidSignedData validates signed data using the configured signature provider func (r *DARetriever) assertValidSignedData(signedData *types.SignedData) error { - if signedData == nil || signedData.Txs == nil { - return errors.New("empty signed data") - } - - if err := r.assertExpectedProposer(signedData.Signer.Address); err != nil { - return err - } - - dataBytes, err := signedData.Data.MarshalBinary() - if err != nil { - return fmt.Errorf("failed to get signed data payload: %w", err) - } - - valid, err := signedData.Signer.PubKey.Verify(dataBytes, signedData.Signature) - if err != nil { - return fmt.Errorf("failed to verify signature: %w", err) - } - - if !valid { - return fmt.Errorf("invalid signature") - } - - return nil + return assertValidSignedData(signedData, r.genesis) } // isEmptyDataExpected checks if empty data is expected for a header diff --git a/block/internal/syncing/raft_retriever.go b/block/internal/syncing/raft_retriever.go new file mode 100644 index 0000000000..2f64486754 --- /dev/null +++ b/block/internal/syncing/raft_retriever.go @@ -0,0 +1,134 @@ +package syncing + +import ( + "context" + "errors" + "fmt" + "sync" + + "github.com/evstack/ev-node/block/internal/common" + "github.com/evstack/ev-node/pkg/genesis" + "github.com/evstack/ev-node/pkg/raft" + "github.com/evstack/ev-node/types" + "github.com/rs/zerolog" +) + +type eventProcessor interface { + handle(ctx context.Context, event common.DAHeightEvent) error +} +type eventProcessorFn func(ctx context.Context, event common.DAHeightEvent) error + +func (e eventProcessorFn) handle(ctx context.Context, event common.DAHeightEvent) error { + return e(ctx, event) +} + +type raftRetriever struct { + // Raft consensus + raftNode common.RaftNode + wg sync.WaitGroup + logger zerolog.Logger + genesis genesis.Genesis + eventProcessor eventProcessor + + mtx sync.Mutex + cancel context.CancelFunc +} + +func newRaftRetriever( + raftNode common.RaftNode, + genesis genesis.Genesis, + logger zerolog.Logger, + eventProcessor eventProcessor, +) *raftRetriever { + return &raftRetriever{ + raftNode: raftNode, + genesis: genesis, + logger: logger, + eventProcessor: eventProcessor, + } +} + +// Start begins the syncing component +func (r *raftRetriever) Start(ctx context.Context) error { + r.mtx.Lock() + defer r.mtx.Unlock() + if r.cancel != nil { + return errors.New("syncer already started") + } + ctx, r.cancel = context.WithCancel(ctx) + applyCh := make(chan raft.RaftApplyMsg) + r.raftNode.SetApplyCallback(applyCh) + + r.wg.Add(1) + go func() { + defer r.wg.Done() + r.raftApplyLoop(ctx, applyCh) + }() + return nil +} + +// Stop gracefully shuts down the raft retriever +func (r *raftRetriever) Stop() { + r.mtx.Lock() + if r.cancel != nil { + r.cancel() + r.cancel = nil + } + r.mtx.Unlock() + + r.wg.Wait() +} + +// raftApplyLoop processes blocks received from raft +func (r *raftRetriever) raftApplyLoop(ctx context.Context, applyCh <-chan raft.RaftApplyMsg) { + r.logger.Info().Msg("starting raft apply loop") + defer r.logger.Info().Msg("raft apply loop stopped") + + for { + select { + case <-ctx.Done(): + return + case msg := <-applyCh: + if err := r.consumeRaftBlock(ctx, msg.State); err != nil { + r.logger.Error().Err(err).Uint64("height", msg.State.Height).Msg("failed to apply raft block") + } + } + } +} + +// consumeRaftBlock applies a block received from raft consensus +func (r *raftRetriever) consumeRaftBlock(ctx context.Context, state *raft.RaftBlockState) error { + r.logger.Debug().Uint64("height", state.Height).Msg("applying raft block") + + // Unmarshal header and data + var header types.SignedHeader + if err := header.UnmarshalBinary(state.Header); err != nil { + return fmt.Errorf("unmarshal header: %w", err) + } + + if err := header.Header.ValidateBasic(); err != nil { + r.logger.Debug().Err(err).Msg("invalid header structure") + return nil + } + if err := assertExpectedProposer(r.genesis, header.ProposerAddress); err != nil { + r.logger.Debug().Err(err).Msg("unexpected proposer") + return nil + } + + var data types.Data + if err := data.UnmarshalBinary(state.Data); err != nil { + return fmt.Errorf("unmarshal data: %w", err) + } + + event := common.DAHeightEvent{ + Header: &header, + Data: &data, + DaHeight: 0, // raft events don't have DA height context + } + return r.eventProcessor.handle(ctx, event) +} + +// Height returns the current height of the raft node's state. +func (r *raftRetriever) Height() uint64 { + return r.raftNode.GetState().Height +} diff --git a/block/internal/syncing/syncer.go b/block/internal/syncing/syncer.go index d1dc7253a5..61f27baf62 100644 --- a/block/internal/syncing/syncer.go +++ b/block/internal/syncing/syncer.go @@ -5,6 +5,7 @@ import ( "context" "errors" "fmt" + "reflect" "sync" "sync/atomic" "time" @@ -62,8 +63,9 @@ type Syncer struct { errorCh chan<- error // Channel to report critical execution client failures // Handlers - daRetriever daRetriever - p2pHandler p2pHandler + daRetriever daRetriever + p2pHandler p2pHandler + raftRetriever *raftRetriever // Logging logger zerolog.Logger @@ -88,8 +90,9 @@ func NewSyncer( logger zerolog.Logger, options common.BlockOptions, errorCh chan<- error, + raftNode common.RaftNode, ) *Syncer { - return &Syncer{ + s := &Syncer{ store: store, exec: exec, da: da, @@ -106,6 +109,10 @@ func NewSyncer( errorCh: errorCh, logger: logger.With().Str("component", "syncer").Logger(), } + if raftNode != nil && !reflect.ValueOf(raftNode).IsNil() { + s.raftRetriever = newRaftRetriever(raftNode, genesis, logger, eventProcessorFn(s.pipeEvent)) + } + return s } // Start begins the syncing component @@ -121,6 +128,12 @@ func (s *Syncer) Start(ctx context.Context) error { s.daRetriever = NewDARetriever(s.da, s.cache, s.config, s.genesis, s.logger) s.p2pHandler = NewP2PHandler(s.headerStore, s.dataStore, s.cache, s.genesis, s.logger) + if s.raftRetriever != nil { + if err := s.raftRetriever.Start(s.ctx); err != nil { + return fmt.Errorf("start raftRetriever: %w", err) + } + } + // Start main processing loop s.wg.Add(1) go func() { @@ -141,14 +154,30 @@ func (s *Syncer) Start(ctx context.Context) error { // Stop shuts down the syncing component func (s *Syncer) Stop() error { - if s.cancel != nil { - s.cancel() + if s.cancel == nil { + return nil } + s.cancel() s.wg.Wait() s.logger.Info().Msg("syncer stopped") + close(s.heightInCh) + s.cancel = nil return nil } +func (s *Syncer) HasUnprocessedEvents() bool { + return len(s.heightInCh) != 0 || func() bool { + currentHeight, err := s.store.Height(s.ctx) + if err != nil { + s.logger.Error().Err(err).Msg("failed to get current height") + return false + } + return s.headerStore.Height() > currentHeight || + s.dataStore.Height() > currentHeight || + s.raftRetriever != nil && s.raftRetriever.Height() > currentHeight + }() +} + // GetLastState returns the current state func (s *Syncer) GetLastState() types.State { state := s.lastState.Load() @@ -217,8 +246,10 @@ func (s *Syncer) processLoop() { select { case <-s.ctx.Done(): return - case heightEvent := <-s.heightInCh: - s.processHeightEvent(&heightEvent) + case heightEvent, ok := <-s.heightInCh: + if ok { + s.processHeightEvent(&heightEvent) + } } } } @@ -301,10 +332,8 @@ func (s *Syncer) tryFetchFromDA(nextDARequestAt *time.Time) { // Process DA events for _, event := range events { - select { - case s.heightInCh <- event: - default: - s.cache.SetPendingEvent(event.Header.Height(), &event) + if err := s.pipeEvent(s.ctx, event); err != nil { + return } } @@ -335,6 +364,19 @@ func (s *Syncer) tryFetchFromP2P() { } } +func (s *Syncer) pipeEvent(ctx context.Context, event common.DAHeightEvent) error { + select { + case s.heightInCh <- event: + return nil + case <-ctx.Done(): + s.cache.SetPendingEvent(event.Header.Height(), &event) + return ctx.Err() + default: + s.cache.SetPendingEvent(event.Header.Height(), &event) + } + return nil +} + func (s *Syncer) processHeightEvent(event *common.DAHeightEvent) { height := event.Header.Height() headerHash := event.Header.Hash().String() diff --git a/block/internal/syncing/syncer_backoff_test.go b/block/internal/syncing/syncer_backoff_test.go index 2dc2bd804f..79535eb97a 100644 --- a/block/internal/syncing/syncer_backoff_test.go +++ b/block/internal/syncing/syncer_backoff_test.go @@ -340,6 +340,7 @@ func setupTestSyncer(t *testing.T, daBlockTime time.Duration) *Syncer { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, syncer.initializeState()) diff --git a/block/internal/syncing/syncer_benchmark_test.go b/block/internal/syncing/syncer_benchmark_test.go index 28cf2af22d..9a6533b394 100644 --- a/block/internal/syncing/syncer_benchmark_test.go +++ b/block/internal/syncing/syncer_benchmark_test.go @@ -113,6 +113,7 @@ func newBenchFixture(b *testing.B, totalHeights uint64, shuffledTx bool, daDelay zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(b, s.initializeState()) s.ctx, s.cancel = ctx, cancel diff --git a/block/internal/syncing/syncer_test.go b/block/internal/syncing/syncer_test.go index 3e4fe3af62..f632ad5048 100644 --- a/block/internal/syncing/syncer_test.go +++ b/block/internal/syncing/syncer_test.go @@ -113,6 +113,7 @@ func TestSyncer_validateBlock_DataHashMismatch(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) // Create header and data with correct hash @@ -161,6 +162,7 @@ func TestProcessHeightEvent_SyncsAndUpdatesState(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, s.initializeState()) @@ -211,6 +213,7 @@ func TestSequentialBlockSync(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, s.initializeState()) s.ctx = context.Background() @@ -345,6 +348,7 @@ func TestSyncLoopPersistState(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, syncerInst1.initializeState()) @@ -424,6 +428,7 @@ func TestSyncLoopPersistState(t *testing.T) { zerolog.Nop(), common.DefaultBlockOptions(), make(chan error, 1), + nil, ) require.NoError(t, syncerInst2.initializeState()) require.Equal(t, myFutureDAHeight-1, syncerInst2.GetDAHeight()) diff --git a/block/public.go b/block/public.go index 8bfc4c1674..24f6cde581 100644 --- a/block/public.go +++ b/block/public.go @@ -1,6 +1,8 @@ package block -import "github.com/evstack/ev-node/block/internal/common" +import ( + "github.com/evstack/ev-node/block/internal/common" +) // BlockOptions defines the options for creating block components type BlockOptions = common.BlockOptions @@ -22,3 +24,6 @@ func PrometheusMetrics(namespace string, labelsAndValues ...string) *Metrics { func NopMetrics() *Metrics { return common.NopMetrics() } + +// Expose Raft types for consensus integration +type RaftNode = common.RaftNode diff --git a/go.mod b/go.mod index 2421b6b163..c5f8ff335b 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,8 @@ require ( github.com/evstack/ev-node/core v1.0.0-beta.3 github.com/go-kit/kit v0.13.0 github.com/goccy/go-yaml v1.18.0 + github.com/hashicorp/raft v1.7.1 + github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e github.com/ipfs/go-datastore v0.9.0 github.com/ipfs/go-ds-badger4 v0.1.8 github.com/libp2p/go-libp2p v0.43.0 @@ -33,8 +35,10 @@ require ( ) require ( + github.com/armon/go-metrics v0.4.1 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect + github.com/boltdb/bolt v1.3.1 // indirect github.com/celestiaorg/go-libp2p-messenger v0.2.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -43,6 +47,7 @@ require ( github.com/dgraph-io/badger/v4 v4.5.1 // indirect github.com/dgraph-io/ristretto/v2 v2.1.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/fatih/color v1.13.0 // indirect github.com/filecoin-project/go-clock v0.1.0 // indirect github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect @@ -57,6 +62,10 @@ require ( github.com/google/uuid v1.6.0 // indirect github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect github.com/gorilla/websocket v1.5.3 // indirect + github.com/hashicorp/go-hclog v1.6.2 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-msgpack v0.5.5 // indirect + github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/huin/goupnp v1.3.0 // indirect diff --git a/go.sum b/go.sum index 26ad829bdf..289ec5bb3d 100644 --- a/go.sum +++ b/go.sum @@ -12,14 +12,27 @@ dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1 dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU= git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878/go.mod h1:3AMJUQhVx52RsWOnlkpikZr01T/yAVN2gn0861vByNg= +github.com/armon/go-metrics v0.3.8/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= +github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= +github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/celestiaorg/go-header v0.7.3 h1:3+kIa+YXT789gPGRh3a55qmdYq3yTTBIqTyum26AvN0= @@ -31,8 +44,11 @@ github.com/celestiaorg/go-square/v3 v3.0.2/go.mod h1:oFReMLsSDMRs82ICFEeFQFCqNvw github.com/celestiaorg/utils v0.1.0 h1:WsP3O8jF7jKRgLNFmlDCwdThwOFMFxg0MnqhkLFVxPo= github.com/celestiaorg/utils v0.1.0/go.mod h1:vQTh7MHnvpIeCQZ2/Ph+w7K1R2UerDheZbgJEJD2hSU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -64,6 +80,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evstack/ev-node/core v1.0.0-beta.3 h1:01K2Ygm3puX4m2OBxvg/HDxu+he54jeNv+KDmpgujFc= github.com/evstack/ev-node/core v1.0.0-beta.3/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/filecoin-project/go-clock v0.1.0 h1:SFbYIM75M8NnFm1yMHhN9Ahy3W5bEZV9gd6MPfXbKVU= github.com/filecoin-project/go-clock v0.1.0/go.mod h1:4uB/O4PvOjlx1VCMdZ9MyDZXRm//gkj1ELEbxfI1AZs= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= @@ -79,13 +97,18 @@ github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +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/kit v0.13.0 h1:OoneCcHKHQ03LfBpoQCUfCluwd2Vt3ohz+kvbJneZAU= github.com/go-kit/kit v0.13.0/go.mod h1:phqEHMMUbyrCFCTgH48JueqrM3md2HcAZ8N3XE4FKDg= +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-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs= github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= @@ -125,6 +148,7 @@ github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -141,10 +165,30 @@ github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aN github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I= +github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= +github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0= +github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-uuid v1.0.0 h1:RS8zrF7PhGwyNPOtxSClXXj9HA8feRnJzgnI1RJCSnM= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= +github.com/hashicorp/raft v1.1.0/go.mod h1:4Ak7FSPnuvmb0GV6vgIAJ4vYT4bek9bb6Q+7HVbyzqM= +github.com/hashicorp/raft v1.7.1 h1:ytxsNx4baHsRZrhUcbt3+79zc4ly8qm7pi0393pSchY= +github.com/hashicorp/raft v1.7.1/go.mod h1:hUeiEwQQR/Nk2iKDD0dkEhklSsu3jcAcqvPzPoZSAEM= +github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e h1:SK4y8oR4ZMHPvwVHryKI88kJPJda4UyWYvG5A6iEQxc= +github.com/hashicorp/raft-boltdb v0.0.0-20231211162105-6c830fa4535e/go.mod h1:EMz/UIuG93P0MBeHh6CbXQAEe8ckVJLZjhD17lBzK5Q= github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -173,17 +217,21 @@ github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABo github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/koron/go-ssdp v0.0.6 h1:Jb0h04599eq/CY7rB5YEqPS83HmRfHP2azkxMN2rFtU= github.com/koron/go-ssdp v0.0.6/go.mod h1:0R9LfRJGek1zWTjN3JUNlm5INCDYGpRDfAptnct63fI= +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.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -229,8 +277,12 @@ github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd h1:br0buuQ854V8u83wA0rVZ8ttrq5CpaPZdvrK0LP2lOk= github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd/go.mod h1:QuCEs1Nt24+FYQEqAAncTDPJIuGs+LxK1MCiFL25pMU= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -251,7 +303,9 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/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= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -280,9 +334,12 @@ github.com/multiformats/go-varint v0.1.0 h1:i2wqFp4sdl3IcIxfAonHQV9qU5OsZ4Ts9IOo github.com/multiformats/go-varint v0.1.0/go.mod h1:5KVAVXegtfmNQQm/lCY+ATvDzvJJhSkUlGQV9wgObdI= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8= +github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2DcNVpwGmV9E1BkGknEliJkfwQj0= github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= @@ -329,6 +386,7 @@ github.com/pion/turn/v4 v4.0.2 h1:ZqgQ3+MjP32ug30xAbD6Mn+/K4Sxi3SdNOTFf+7mpps= github.com/pion/turn/v4 v4.0.2/go.mod h1:pMMKP/ieNAG/fN5cZiN4SDuyKsXtNTr0ccN7IToA1zs= github.com/pion/webrtc/v4 v4.1.2 h1:mpuUo/EJ1zMNKGE79fAdYNFZBX790KE7kQQpLMjjR54= github.com/pion/webrtc/v4 v4.1.2/go.mod h1:xsCXiNAmMEjIdFxAYU0MbB3RwRieJsegSB2JZsGN+8U= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -338,16 +396,29 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= github.com/prometheus/client_model v0.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= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.17.0 h1:FuLQ+05u4ZI+SS/w9+BWEM2TXiHKsUQ9TADiRH7DuK0= github.com/prometheus/procfs v0.17.0/go.mod h1:oPQLaDAMRbA+u8H5Pbfq+dl3VDAvHxMUOVhe0wYB2zw= github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= @@ -390,6 +461,8 @@ github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go. github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/users v0.0.0-20180125191416-49c67e49c537/go.mod h1:QJTqeLYEDaXHZDBsXlPCDqdhQuJkuw4NOtaxYe3xii4= github.com/shurcooL/webdavfs v0.0.0-20170829043945-18c3829fa133/go.mod h1:hKmq5kWdCj2z2KEozexVbfEZIWiTjhE0+UjmZgPqehw= +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/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= @@ -412,13 +485,16 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= github.com/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/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= 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.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -428,6 +504,7 @@ github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/urfave/cli v1.22.10/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU= github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM= @@ -470,6 +547,7 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= golang.org/x/build v0.0.0-20190111050920-041ab4dc3f9d/go.mod h1:OWs+y06UdEOHN4y+MfF/py+xQ/tYqIWW03b70/CG9Rw= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190313024323-a1f597ede03a/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -504,11 +582,14 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -541,15 +622,24 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= 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= golang.org/x/sys v0.0.0-20181029174526-d69651ed3497/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190316082340-a2f829d7f35f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/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-20220503163025-988cb79eb6c6/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-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -640,12 +730,16 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +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= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/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= diff --git a/node/failover.go b/node/failover.go new file mode 100644 index 0000000000..63a13d4224 --- /dev/null +++ b/node/failover.go @@ -0,0 +1,262 @@ +package node + +import ( + "context" + "errors" + "fmt" + "net/http" + "time" + + "github.com/evstack/ev-node/block" + coreda "github.com/evstack/ev-node/core/da" + coreexecutor "github.com/evstack/ev-node/core/execution" + coresequencer "github.com/evstack/ev-node/core/sequencer" + "github.com/evstack/ev-node/pkg/config" + genesispkg "github.com/evstack/ev-node/pkg/genesis" + "github.com/evstack/ev-node/pkg/p2p" + "github.com/evstack/ev-node/pkg/p2p/key" + "github.com/evstack/ev-node/pkg/raft" + rpcserver "github.com/evstack/ev-node/pkg/rpc/server" + "github.com/evstack/ev-node/pkg/signer" + "github.com/evstack/ev-node/pkg/store" + evsync "github.com/evstack/ev-node/pkg/sync" + ds "github.com/ipfs/go-datastore" + "github.com/rs/zerolog" +) + +// failoverState collect the components to reset when switching modes. +type failoverState struct { + logger zerolog.Logger + + p2pClient *p2p.Client + headerSyncService *evsync.HeaderSyncService + dataSyncService *evsync.DataSyncService + rpcServer *http.Server + bc *block.Components +} + +func newSyncMode( + nodeConfig config.Config, + nodeKey *key.NodeKey, + genesis genesispkg.Genesis, + database ds.Batching, + exec coreexecutor.Executor, + da coreda.DA, + logger zerolog.Logger, + rktStore store.Store, + mainKV ds.Batching, + blockMetrics *block.Metrics, + nodeOpts NodeOptions, + raftNode *raft.Node, +) (*failoverState, error) { + blockComponentsFn := func(headerSyncService *evsync.HeaderSyncService, dataSyncService *evsync.DataSyncService) (*block.Components, error) { + return block.NewSyncComponents( + nodeConfig, + genesis, + rktStore, + exec, + da, + headerSyncService.Store(), + dataSyncService.Store(), + logger, + blockMetrics, + nodeOpts.BlockOptions, + raftNode, + ) + } + return setupFailoverState(nodeConfig, nodeKey, database, genesis, logger, mainKV, rktStore, blockComponentsFn, raftNode) +} +func newAggregatorMode( + nodeConfig config.Config, + nodeKey *key.NodeKey, + signer signer.Signer, + genesis genesispkg.Genesis, + database ds.Batching, + exec coreexecutor.Executor, + sequencer coresequencer.Sequencer, + da coreda.DA, + logger zerolog.Logger, + rktStore store.Store, + mainKV ds.Batching, + blockMetrics *block.Metrics, + nodeOpts NodeOptions, + raftNode *raft.Node, +) (*failoverState, error) { + + blockComponentsFn := func(headerSyncService *evsync.HeaderSyncService, dataSyncService *evsync.DataSyncService) (*block.Components, error) { + return block.NewAggregatorComponents( + nodeConfig, + genesis, + rktStore, + exec, + sequencer, + da, + signer, + headerSyncService, + dataSyncService, + logger, + blockMetrics, + nodeOpts.BlockOptions, + raftNode, + ) + } + + return setupFailoverState(nodeConfig, nodeKey, database, genesis, logger, mainKV, rktStore, blockComponentsFn, raftNode) +} + +func setupFailoverState( + nodeConfig config.Config, + nodeKey *key.NodeKey, + database ds.Batching, + genesis genesispkg.Genesis, + logger zerolog.Logger, + mainKV ds.Batching, + rktStore store.Store, + buildComponentsFn func(headerSyncService *evsync.HeaderSyncService, dataSyncService *evsync.DataSyncService) (*block.Components, error), + raftNode *raft.Node, +) (*failoverState, error) { + p2pClient, err := p2p.NewClient(nodeConfig.P2P, nodeKey.PrivKey, database, genesis.ChainID, logger, nil) + if err != nil { + return nil, err + } + + headerSyncService, err := evsync.NewHeaderSyncService(mainKV, nodeConfig, genesis, p2pClient, logger.With().Str("component", "HeaderSyncService").Logger()) + if err != nil { + return nil, fmt.Errorf("error while initializing HeaderSyncService: %w", err) + } + + dataSyncService, err := evsync.NewDataSyncService(mainKV, nodeConfig, genesis, p2pClient, logger.With().Str("component", "DataSyncService").Logger()) + if err != nil { + return nil, fmt.Errorf("error while initializing DataSyncService: %w", err) + } + + bestKnownHeightProvider := func() uint64 { + hHeight := headerSyncService.Store().Height() + dHeight := dataSyncService.Store().Height() + return min(hHeight, dHeight) + } + handler, err := rpcserver.NewServiceHandler(rktStore, p2pClient, genesis.ProposerAddress, logger, nodeConfig, bestKnownHeightProvider, raftNode) + if err != nil { + return nil, fmt.Errorf("error creating RPC handler: %w", err) + } + + rpcServer := &http.Server{ + Addr: nodeConfig.RPC.Address, + Handler: handler, + ReadTimeout: 10 * time.Second, + WriteTimeout: 10 * time.Second, + IdleTimeout: 120 * time.Second, + } + bc, err := buildComponentsFn(headerSyncService, dataSyncService) + if err != nil { + return nil, fmt.Errorf("build follower components: %w", err) + } + + return &failoverState{ + logger: logger, + p2pClient: p2pClient, + headerSyncService: headerSyncService, + dataSyncService: dataSyncService, + rpcServer: rpcServer, + bc: bc, + }, nil +} + +func (f *failoverState) Run(ctx context.Context) (multiErr error) { + errChan := make(chan error) + go func() { + f.logger.Info().Str("addr", f.rpcServer.Addr).Msg("Started RPC server") + if err := f.rpcServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { + select { + case errChan <- fmt.Errorf("RPC server error: %w", err): + default: + f.logger.Error().Err(err).Msg("RPC server error") + } + } + }() + defer f.rpcServer.Shutdown(context.Background()) // nolint: errcheck + + if err := f.p2pClient.Start(ctx); err != nil { + return err + } + defer f.p2pClient.Close() // nolint: errcheck + + if err := f.headerSyncService.Start(ctx); err != nil { + return fmt.Errorf("error while starting header sync service: %w", err) + } + defer func() { + if err := f.headerSyncService.Stop(context.Background()); err != nil && !errors.Is(err, context.Canceled) { + multiErr = errors.Join(multiErr, fmt.Errorf("stopping header sync: %w", err)) + } + }() + + if err := f.dataSyncService.Start(ctx); err != nil { + return fmt.Errorf("error while starting data sync service: %w", err) + } + defer func() { + if err := f.dataSyncService.Stop(context.Background()); err != nil && !errors.Is(err, context.Canceled) { + multiErr = errors.Join(multiErr, fmt.Errorf("stopping data sync: %w", err)) + } + }() + + defer func() { + if f.bc.Syncer != nil { + for f.bc.Syncer.HasUnprocessedEvents() { + // give it some time to gracefully complete + time.Sleep(100 * time.Millisecond) + } + } + if err := f.bc.Stop(); err != nil && !errors.Is(err, context.Canceled) { + multiErr = errors.Join(multiErr, fmt.Errorf("stopping block components: %w", err)) + } + }() + + go func() { + if err := f.bc.Start(ctx); err != nil && !errors.Is(err, context.Canceled) { + select { + case errChan <- fmt.Errorf("components started with error: %w", err): + default: + f.logger.Error().Err(err).Msg("Components start error") + } + return + } + select { + case errChan <- nil: + default: + } + }() + + return <-errChan +} + +var _ leaderElection = AlwaysLeader{} + +type AlwaysLeader struct{} + +func (a AlwaysLeader) RunWithElection(ctx context.Context, leaderFunc, _ func(leaderCtx context.Context) error) error { + return leaderFunc(ctx) +} + +func (a AlwaysLeader) Start(ctx context.Context) error { + return nil +} + +func (a AlwaysLeader) Stop() error { + return nil +} + +var _ leaderElection = AlwaysFollower{} + +type AlwaysFollower struct{} + +func (a AlwaysFollower) RunWithElection(ctx context.Context, _, followerFunc func(leaderCtx context.Context) error) error { + return followerFunc(ctx) +} + +func (a AlwaysFollower) Start(ctx context.Context) error { + return nil +} + +func (a AlwaysFollower) Stop() error { + return nil +} diff --git a/node/full.go b/node/full.go index caa769c643..c57f29368b 100644 --- a/node/full.go +++ b/node/full.go @@ -8,30 +8,30 @@ import ( "fmt" "net/http" "net/http/pprof" + "path/filepath" + "strings" "time" - ds "github.com/ipfs/go-datastore" - ktds "github.com/ipfs/go-datastore/keytransform" - "github.com/prometheus/client_golang/prometheus" - "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/rs/zerolog" - "github.com/evstack/ev-node/block" - coreda "github.com/evstack/ev-node/core/da" coreexecutor "github.com/evstack/ev-node/core/execution" coresequencer "github.com/evstack/ev-node/core/sequencer" "github.com/evstack/ev-node/pkg/config" genesispkg "github.com/evstack/ev-node/pkg/genesis" - "github.com/evstack/ev-node/pkg/p2p" - rpcserver "github.com/evstack/ev-node/pkg/rpc/server" + "github.com/evstack/ev-node/pkg/p2p/key" + raftpkg "github.com/evstack/ev-node/pkg/raft" + rpcclient "github.com/evstack/ev-node/pkg/rpc/client" "github.com/evstack/ev-node/pkg/service" "github.com/evstack/ev-node/pkg/signer" "github.com/evstack/ev-node/pkg/store" - evsync "github.com/evstack/ev-node/pkg/sync" + ds "github.com/ipfs/go-datastore" + ktds "github.com/ipfs/go-datastore/keytransform" + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/rs/zerolog" ) -// prefixes used in KV store to separate rollkit data from execution environment data (if the same data base is reused) +// EvPrefix used in KV store to separate rollkit data from execution environment data (if the same data base is reused) var EvPrefix = "0" const ( @@ -42,6 +42,12 @@ const ( var _ Node = &FullNode{} +type leaderElection interface { + RunWithElection(ctx context.Context, leaderFunc, followerFunc func(leaderCtx context.Context) error) error + Start(ctx context.Context) error + Stop() error +} + // FullNode represents a client node in Rollkit network. // It connects all the components and orchestrates their work. type FullNode struct { @@ -55,21 +61,20 @@ type FullNode struct { da coreda.DA - p2pClient *p2p.Client - hSyncService *evsync.HeaderSyncService - dSyncService *evsync.DataSyncService - Store store.Store - blockComponents *block.Components + Store store.Store + blockComponents *block.Components + syncComponentFunc func(c context.Context) error + aggregatorComponentFunc func(c context.Context) error - prometheusSrv *http.Server - pprofSrv *http.Server - rpcServer *http.Server + prometheusSrv *http.Server + pprofSrv *http.Server + leaderElection leaderElection } // newFullNode creates a new Rollkit full node. func newFullNode( nodeConfig config.Config, - p2pClient *p2p.Client, + nodeKey *key.NodeKey, signer signer.Signer, genesis genesispkg.Genesis, database ds.Batching, @@ -87,59 +92,50 @@ func newFullNode( mainKV := newPrefixKV(database, EvPrefix) rktStore := store.New(mainKV) - headerSyncService, err := initHeaderSyncService(mainKV, nodeConfig, genesis, p2pClient, logger) - if err != nil { - return nil, err - } - - dataSyncService, err := initDataSyncService(mainKV, nodeConfig, genesis, p2pClient, logger) - if err != nil { - return nil, err - } - - var blockComponents *block.Components - if nodeConfig.Node.Aggregator { - blockComponents, err = block.NewAggregatorComponents( - nodeConfig, - genesis, - rktStore, - exec, - sequencer, - da, - signer, - headerSyncService, - dataSyncService, - logger, - blockMetrics, - nodeOpts.BlockOptions, - ) - } else { - blockComponents, err = block.NewSyncComponents( - nodeConfig, - genesis, - rktStore, - exec, - da, - headerSyncService.Store(), - dataSyncService.Store(), - logger, - blockMetrics, - nodeOpts.BlockOptions, - ) - } - if err != nil { - return nil, err + // Initialize raft node if enabled (for both aggregator and sync nodes) + var raftNode *raftpkg.Node + var leaderElection leaderElection + switch { + case nodeConfig.Node.Aggregator && nodeConfig.Raft.Enable: + raftNode, err = initRaftNode(nodeConfig, logger) + if err != nil { + return nil, fmt.Errorf("failed to initialize raft node: %w", err) + } + leaderElection = raftNode + nodeConfig.P2P.Peers = "" // raft cluster provides most up to date blocks. No need for p2p peers. + case nodeConfig.Node.Aggregator && !nodeConfig.Raft.Enable: + leaderElection = AlwaysLeader{} + case !nodeConfig.Node.Aggregator: + leaderElection = AlwaysFollower{} + default: + return nil, fmt.Errorf("raft config must be used in sequencer setup only") } node := &FullNode{ - genesis: genesis, - nodeConfig: nodeConfig, - p2pClient: p2pClient, - blockComponents: blockComponents, - da: da, - Store: rktStore, - hSyncService: headerSyncService, - dSyncService: dataSyncService, + genesis: genesis, + nodeConfig: nodeConfig, + da: da, + Store: rktStore, + leaderElection: leaderElection, + aggregatorComponentFunc: func(ctx context.Context) error { + logger.Info().Msg("Starting aggregator-MODE") + nodeConfig.Node.Aggregator = true + nodeConfig.P2P.Peers = "" + m, err := newAggregatorMode(nodeConfig, nodeKey, signer, genesis, database, exec, sequencer, da, logger, rktStore, mainKV, blockMetrics, nodeOpts, raftNode) + if err != nil { + return err + } + return m.Run(ctx) + }, + syncComponentFunc: func(ctx context.Context) error { + logger.Info().Msg("Starting sync-MODE") + nodeConfig.Node.Aggregator = false + m, err := newSyncMode(nodeConfig, nodeKey, genesis, database, exec, da, logger, rktStore, mainKV, blockMetrics, nodeOpts, raftNode) + if err != nil { + return err + } + return m.Run(ctx) + }, } node.BaseService = *service.NewBaseService(logger, "Node", node) @@ -147,32 +143,41 @@ func newFullNode( return node, nil } -func initHeaderSyncService( - mainKV ds.Batching, - nodeConfig config.Config, - genesis genesispkg.Genesis, - p2pClient *p2p.Client, - logger zerolog.Logger, -) (*evsync.HeaderSyncService, error) { - headerSyncService, err := evsync.NewHeaderSyncService(mainKV, nodeConfig, genesis, p2pClient, logger.With().Str("component", "HeaderSyncService").Logger()) - if err != nil { - return nil, fmt.Errorf("error while initializing HeaderSyncService: %w", err) +func initRaftNode(nodeConfig config.Config, logger zerolog.Logger) (*raftpkg.Node, error) { + raftDir := nodeConfig.Raft.RaftDir + if raftDir == "" { + raftDir = filepath.Join(nodeConfig.RootDir, "raft") } - return headerSyncService, nil -} -func initDataSyncService( - mainKV ds.Batching, - nodeConfig config.Config, - genesis genesispkg.Genesis, - p2pClient *p2p.Client, - logger zerolog.Logger, -) (*evsync.DataSyncService, error) { - dataSyncService, err := evsync.NewDataSyncService(mainKV, nodeConfig, genesis, p2pClient, logger.With().Str("component", "DataSyncService").Logger()) + raftCfg := &raftpkg.Config{ + NodeID: nodeConfig.Raft.NodeID, + RaftAddr: nodeConfig.Raft.RaftAddr, + RaftDir: raftDir, + Bootstrap: nodeConfig.Raft.Bootstrap, + SnapCount: nodeConfig.Raft.SnapCount, + SendTimeout: nodeConfig.Raft.SendTimeout, + HeartbeatTimeout: nodeConfig.Raft.HeartbeatTimeout, + } + + if nodeConfig.Raft.Peers != "" { + raftCfg.Peers = strings.Split(nodeConfig.Raft.Peers, ",") + } + clusterClient, err := rpcclient.NewRaftClusterClient(raftCfg.Peers...) + if err != nil { + return nil, fmt.Errorf("create raft cluster client: %w", err) + } + raftNode, err := raftpkg.NewNode(raftCfg, clusterClient, logger) if err != nil { - return nil, fmt.Errorf("error while initializing DataSyncService: %w", err) + return nil, fmt.Errorf("create raft node: %w", err) } - return dataSyncService, nil + + logger.Info(). + Str("node_id", nodeConfig.Raft.NodeID). + Str("addr", nodeConfig.Raft.RaftAddr). + Bool("bootstrap", nodeConfig.Raft.Bootstrap). + Msg("initialized raft node") + + return raftNode, nil } // initGenesisChunks creates a chunked format of the genesis document to make it easier to @@ -279,55 +284,13 @@ func (n *FullNode) Run(parentCtx context.Context) error { (n.nodeConfig.Instrumentation.IsPrometheusEnabled() || n.nodeConfig.Instrumentation.IsPprofEnabled()) { n.prometheusSrv, n.pprofSrv = n.startInstrumentationServer() } - - // Start RPC server - bestKnownHeightProvider := func() uint64 { - hHeight := n.hSyncService.Store().Height() - dHeight := n.dSyncService.Store().Height() - return min(hHeight, dHeight) - } - - handler, err := rpcserver.NewServiceHandler(n.Store, n.p2pClient, n.genesis.ProposerAddress, n.Logger, n.nodeConfig, bestKnownHeightProvider) - if err != nil { - return fmt.Errorf("error creating RPC handler: %w", err) + // Start leader election if enabled + if err := n.leaderElection.Start(ctx); err != nil { + return fmt.Errorf("error while starting leader election: %w", err) } - n.rpcServer = &http.Server{ - Addr: n.nodeConfig.RPC.Address, - Handler: handler, - ReadTimeout: 10 * time.Second, - WriteTimeout: 10 * time.Second, - IdleTimeout: 120 * time.Second, - } - - go func() { - n.Logger.Info().Str("addr", n.nodeConfig.RPC.Address).Msg("started RPC server") - if err := n.rpcServer.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { - n.Logger.Error().Err(err).Msg("RPC server error") - } - }() - - n.Logger.Info().Msg("starting P2P client") - err = n.p2pClient.Start(ctx) - if err != nil { - return fmt.Errorf("error while starting P2P client: %w", err) - } - - if err = n.hSyncService.Start(ctx); err != nil { - return fmt.Errorf("error while starting header sync service: %w", err) - } - - if err = n.dSyncService.Start(ctx); err != nil { - return fmt.Errorf("error while starting data sync service: %w", err) - } - - // Start the block components (blocking) - if err := n.blockComponents.Start(ctx); err != nil { - if !errors.Is(err, context.Canceled) { - n.Logger.Error().Err(err).Msg("unrecoverable error in block components") - } else { - n.Logger.Info().Msg("context canceled, stopping node") - } + if err := n.leaderElection.RunWithElection(ctx, n.aggregatorComponentFunc, n.syncComponentFunc); err != nil && !errors.Is(err, context.Canceled) { + n.Logger.Warn().Err(err).Msg("leadership change detected, restarting components") } // blocking components start exited, propagate shutdown to all other processes @@ -340,45 +303,16 @@ func (n *FullNode) Run(parentCtx context.Context) error { var multiErr error // Use a multierror variable - // Stop block components - if err := n.blockComponents.Stop(); err != nil { - n.Logger.Error().Err(err).Msg("error stopping block components") - multiErr = errors.Join(multiErr, fmt.Errorf("stopping block components: %w", err)) - } - - // Stop Header Sync Service - err = n.hSyncService.Stop(shutdownCtx) - if err != nil { - // Log context canceled errors at a lower level if desired, or handle specific non-cancel errors - if !errors.Is(err, context.Canceled) && !errors.Is(err, context.DeadlineExceeded) { - n.Logger.Error().Err(err).Msg("error stopping header sync service") - multiErr = errors.Join(multiErr, fmt.Errorf("stopping header sync service: %w", err)) - } else { - n.Logger.Debug().Err(err).Msg("header sync service stop context ended") // Log cancellation as debug - } - } - - // Stop Data Sync Service - err = n.dSyncService.Stop(shutdownCtx) - if err != nil { - // Log context canceled errors at a lower level if desired, or handle specific non-cancel errors - if !errors.Is(err, context.Canceled) && !errors.Is(err, context.DeadlineExceeded) { - n.Logger.Error().Err(err).Msg("error stopping data sync service") - multiErr = errors.Join(multiErr, fmt.Errorf("stopping data sync service: %w", err)) - } else { - n.Logger.Debug().Err(err).Msg("data sync service stop context ended") // Log cancellation as debug - } - } - - // Stop P2P Client - err = n.p2pClient.Close() - if err != nil { - multiErr = errors.Join(multiErr, fmt.Errorf("closing P2P client: %w", err)) + // Stop leader election + if err := n.leaderElection.Stop(); err != nil && !errors.Is(err, context.Canceled) { + multiErr = errors.Join(multiErr, fmt.Errorf("stopping leader election: %w", err)) + } else { + n.Logger.Debug().Msg("leader election stopped") } // Shutdown Prometheus Server if n.prometheusSrv != nil { - err = n.prometheusSrv.Shutdown(shutdownCtx) + err := n.prometheusSrv.Shutdown(shutdownCtx) // http.ErrServerClosed is expected on graceful shutdown if err != nil && !errors.Is(err, http.ErrServerClosed) { multiErr = errors.Join(multiErr, fmt.Errorf("shutting down Prometheus server: %w", err)) @@ -389,7 +323,7 @@ func (n *FullNode) Run(parentCtx context.Context) error { // Shutdown Pprof Server if n.pprofSrv != nil { - err = n.pprofSrv.Shutdown(shutdownCtx) + err := n.pprofSrv.Shutdown(shutdownCtx) if err != nil && !errors.Is(err, http.ErrServerClosed) { multiErr = errors.Join(multiErr, fmt.Errorf("shutting down pprof server: %w", err)) } else { @@ -397,32 +331,13 @@ func (n *FullNode) Run(parentCtx context.Context) error { } } - // Shutdown RPC Server - if n.rpcServer != nil { - err = n.rpcServer.Shutdown(shutdownCtx) - if err != nil && !errors.Is(err, http.ErrServerClosed) { - multiErr = errors.Join(multiErr, fmt.Errorf("shutting down RPC server: %w", err)) - } else { - n.Logger.Debug().Err(err).Msg("RPC server shutdown context ended") - } - } - // Ensure Store.Close is called last to maximize chance of data flushing - if err = n.Store.Close(); err != nil { + if err := n.Store.Close(); err != nil { multiErr = errors.Join(multiErr, fmt.Errorf("closing store: %w", err)) } else { n.Logger.Debug().Msg("store closed") } - // Save caches if needed - if n.blockComponents != nil && n.blockComponents.Cache != nil { - if err := n.blockComponents.Cache.SaveToDisk(); err != nil { - multiErr = errors.Join(multiErr, fmt.Errorf("saving caches: %w", err)) - } else { - n.Logger.Debug().Msg("caches saved") - } - } - // Log final status if multiErr != nil { for _, err := range multiErr.(interface{ Unwrap() []error }).Unwrap() { diff --git a/node/helpers.go b/node/helpers.go index 0dc1a20cc3..9e0d7e62f0 100644 --- a/node/helpers.go +++ b/node/helpers.go @@ -58,19 +58,26 @@ func getNodeHeight(node Node, source Source) (uint64, error) { } func getNodeHeightFromHeader(node Node) (uint64, error) { - if fn, ok := node.(*FullNode); ok { - return fn.hSyncService.Store().Height(), nil - } - if ln, ok := node.(*LightNode); ok { - return ln.hSyncService.Store().Height(), nil + if true { + panic("not implemented") } + //if fn, ok := node.(*FullNode); ok { + // return fn.hSyncService.Store().Height(), nil + //} + //if ln, ok := node.(*LightNode); ok { + // return ln.hSyncService.Store().Height(), nil + //} return 0, errors.New("not a full or light node") } func getNodeHeightFromData(node Node) (uint64, error) { - if fn, ok := node.(*FullNode); ok { - return fn.dSyncService.Store().Height(), nil + if true { + panic("not implemented") } + + //if fn, ok := node.(*FullNode); ok { + // return fn.dSyncService.Store().Height(), nil + //} return 0, errors.New("not a full node") } diff --git a/node/helpers_test.go b/node/helpers_test.go index b90dd8f1ef..f04f7edfc4 100644 --- a/node/helpers_test.go +++ b/node/helpers_test.go @@ -22,7 +22,6 @@ import ( coresequencer "github.com/evstack/ev-node/core/sequencer" evconfig "github.com/evstack/ev-node/pkg/config" - "github.com/evstack/ev-node/pkg/p2p" "github.com/evstack/ev-node/pkg/p2p/key" remote_signer "github.com/evstack/ev-node/pkg/signer/noop" "github.com/evstack/ev-node/types" @@ -43,7 +42,7 @@ const ( ) // createTestComponents creates test components for node initialization -func createTestComponents(t *testing.T, config evconfig.Config) (coreexecutor.Executor, coresequencer.Sequencer, coreda.DA, *p2p.Client, datastore.Batching, *key.NodeKey, func()) { +func createTestComponents(t *testing.T, config evconfig.Config) (coreexecutor.Executor, coresequencer.Sequencer, coreda.DA, datastore.Batching, *key.NodeKey, func()) { executor := coreexecutor.NewDummyExecutor() sequencer := coresequencer.NewDummySequencer() dummyDA := coreda.NewDummyDA(100_000, 0, 0, config.DA.BlockTime.Duration) @@ -59,13 +58,9 @@ func createTestComponents(t *testing.T, config evconfig.Config) (coreexecutor.Ex PrivKey: genesisValidatorKey, PubKey: genesisValidatorKey.GetPublic(), } - logger := zerolog.Nop() - p2pClient, err := p2p.NewClient(config.P2P, p2pKey.PrivKey, dssync.MutexWrap(datastore.NewMapDatastore()), "test-chain", logger, p2p.NopMetrics()) - require.NoError(t, err) - require.NotNil(t, p2pClient) ds := dssync.MutexWrap(datastore.NewMapDatastore()) - return executor, sequencer, dummyDA, p2pClient, ds, p2pKey, stopDAHeightTicker + return executor, sequencer, dummyDA, ds, p2pKey, stopDAHeightTicker } func getTestConfig(t *testing.T, n int) evconfig.Config { @@ -102,7 +97,7 @@ func newTestNode( executor coreexecutor.Executor, sequencer coresequencer.Sequencer, dac coreda.DA, - p2pClient *p2p.Client, + nodeKey *key.NodeKey, ds datastore.Batching, stopDAHeightTicker func(), ) (*FullNode, func()) { @@ -117,7 +112,7 @@ func newTestNode( sequencer, dac, remoteSigner, - p2pClient, + nodeKey, genesis, ds, DefaultMetricsProvider(evconfig.DefaultInstrumentationConfig()), @@ -136,8 +131,8 @@ func newTestNode( } func createNodeWithCleanup(t *testing.T, config evconfig.Config) (*FullNode, func()) { - executor, sequencer, dac, p2pClient, ds, _, stopDAHeightTicker := createTestComponents(t, config) - return newTestNode(t, config, executor, sequencer, dac, p2pClient, ds, stopDAHeightTicker) + executor, sequencer, dac, ds, nodeKey, stopDAHeightTicker := createTestComponents(t, config) + return newTestNode(t, config, executor, sequencer, dac, nodeKey, ds, stopDAHeightTicker) } func createNodeWithCustomComponents( @@ -146,11 +141,11 @@ func createNodeWithCustomComponents( executor coreexecutor.Executor, sequencer coresequencer.Sequencer, dac coreda.DA, - p2pClient *p2p.Client, + nodeKey *key.NodeKey, ds datastore.Batching, stopDAHeightTicker func(), ) (*FullNode, func()) { - return newTestNode(t, config, executor, sequencer, dac, p2pClient, ds, stopDAHeightTicker) + return newTestNode(t, config, executor, sequencer, dac, nodeKey, ds, stopDAHeightTicker) } // Creates the given number of nodes the given nodes using the given wait group to synchronize them @@ -168,7 +163,7 @@ func createNodesWithCleanup(t *testing.T, num int, config evconfig.Config) ([]*F aggListenAddress := config.P2P.ListenAddress aggPeers := config.P2P.Peers - executor, sequencer, dac, p2pClient, ds, aggP2PKey, stopDAHeightTicker := createTestComponents(t, config) + executor, sequencer, dac, ds, aggP2PKey, stopDAHeightTicker := createTestComponents(t, config) aggPeerID, err := peer.IDFromPrivateKey(aggP2PKey.PrivKey) require.NoError(err) @@ -178,7 +173,7 @@ func createNodesWithCleanup(t *testing.T, num int, config evconfig.Config) ([]*F sequencer, dac, remoteSigner, - p2pClient, + aggP2PKey, genesis, ds, DefaultMetricsProvider(evconfig.DefaultInstrumentationConfig()), @@ -205,14 +200,14 @@ func createNodesWithCleanup(t *testing.T, num int, config evconfig.Config) ([]*F } config.P2P.ListenAddress = fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 40001+i) config.RPC.Address = fmt.Sprintf("127.0.0.1:%d", 8001+i) - executor, sequencer, _, p2pClient, _, nodeP2PKey, stopDAHeightTicker := createTestComponents(t, config) + executor, sequencer, _, _, nodeP2PKey, stopDAHeightTicker := createTestComponents(t, config) node, err := NewNode( config, executor, sequencer, dac, nil, - p2pClient, + aggP2PKey, genesis, dssync.MutexWrap(datastore.NewMapDatastore()), DefaultMetricsProvider(evconfig.DefaultInstrumentationConfig()), diff --git a/node/light.go b/node/light.go index be8b0ac4dd..e423a2d80f 100644 --- a/node/light.go +++ b/node/light.go @@ -7,6 +7,7 @@ import ( "net/http" "time" + "github.com/evstack/ev-node/pkg/p2p/key" ds "github.com/ipfs/go-datastore" "github.com/rs/zerolog" @@ -38,10 +39,15 @@ type LightNode struct { func newLightNode( conf config.Config, genesis genesis.Genesis, - p2pClient *p2p.Client, + nodeKey *key.NodeKey, database ds.Batching, logger zerolog.Logger, ) (ln *LightNode, err error) { + p2pClient, err := p2p.NewClient(conf.P2P, nodeKey.PrivKey, database, genesis.ChainID, logger, nil) + if err != nil { + return nil, err + } + headerSyncService, err := sync.NewHeaderSyncService(database, conf, genesis, p2pClient, logger.With().Str("component", "HeaderSyncService").Logger()) if err != nil { return nil, fmt.Errorf("error while initializing HeaderSyncService: %w", err) @@ -83,7 +89,7 @@ func (ln *LightNode) Run(parentCtx context.Context) error { return ln.hSyncService.Store().Height() } - handler, err := rpcserver.NewServiceHandler(ln.Store, ln.P2P, nil, ln.Logger, ln.nodeConfig, bestKnown) + handler, err := rpcserver.NewServiceHandler(ln.Store, ln.P2P, nil, ln.Logger, ln.nodeConfig, bestKnown, nil) if err != nil { return fmt.Errorf("error creating RPC handler: %w", err) } diff --git a/node/light_test.go b/node/light_test.go index c6def936e6..f459ad54b0 100644 --- a/node/light_test.go +++ b/node/light_test.go @@ -13,7 +13,6 @@ import ( "github.com/evstack/ev-node/pkg/config" "github.com/evstack/ev-node/pkg/genesis" - "github.com/evstack/ev-node/pkg/p2p" p2p_key "github.com/evstack/ev-node/pkg/p2p/key" ) @@ -38,14 +37,9 @@ func TestLightNodeLifecycle(t *testing.T) { require.NoError(err) logger := zerolog.Nop() - p2pMetrics := p2p.NopMetrics() - db := ds_sync.MutexWrap(ds.NewMapDatastore()) - p2pClient, err := p2p.NewClient(conf.P2P, p2pKey.PrivKey, db, gen.ChainID, logger, p2pMetrics) - require.NoError(err) - - ln, err := newLightNode(conf, gen, p2pClient, db, logger) + ln, err := newLightNode(conf, gen, p2pKey, db, logger) require.NoError(err) require.NotNil(ln) diff --git a/node/node.go b/node/node.go index 4d780035aa..f0c2038df9 100644 --- a/node/node.go +++ b/node/node.go @@ -10,7 +10,7 @@ import ( coresequencer "github.com/evstack/ev-node/core/sequencer" "github.com/evstack/ev-node/pkg/config" "github.com/evstack/ev-node/pkg/genesis" - "github.com/evstack/ev-node/pkg/p2p" + "github.com/evstack/ev-node/pkg/p2p/key" "github.com/evstack/ev-node/pkg/service" "github.com/evstack/ev-node/pkg/signer" ) @@ -35,7 +35,7 @@ func NewNode( sequencer coresequencer.Sequencer, da coreda.DA, signer signer.Signer, - p2pClient *p2p.Client, + nodeKey *key.NodeKey, genesis genesis.Genesis, database ds.Batching, metricsProvider MetricsProvider, @@ -43,7 +43,7 @@ func NewNode( nodeOptions NodeOptions, ) (Node, error) { if conf.Node.Light { - return newLightNode(conf, genesis, p2pClient, database, logger) + return newLightNode(conf, genesis, nodeKey, database, logger) } if err := nodeOptions.BlockOptions.Validate(); err != nil { @@ -52,7 +52,7 @@ func NewNode( return newFullNode( conf, - p2pClient, + nodeKey, signer, genesis, database, diff --git a/node/single_sequencer_integration_test.go b/node/single_sequencer_integration_test.go index 4e9716bdfa..f8cf75798a 100644 --- a/node/single_sequencer_integration_test.go +++ b/node/single_sequencer_integration_test.go @@ -230,7 +230,7 @@ func TestStateRecovery(t *testing.T) { // Set up one sequencer config := getTestConfig(t, 1) - executor, sequencer, dac, p2pClient, ds, _, stopDAHeightTicker := createTestComponents(t, config) + executor, sequencer, dac, ds, _, stopDAHeightTicker := createTestComponents(t, config) node, cleanup := createNodeWithCustomComponents(t, config, executor, sequencer, dac, p2pClient, ds, stopDAHeightTicker) defer cleanup() @@ -255,7 +255,7 @@ func TestStateRecovery(t *testing.T) { shutdownAndWait(t, []context.CancelFunc{cancel}, &runningWg, 60*time.Second) // Create a new node instance using the same components - executor, sequencer, dac, p2pClient, _, _, stopDAHeightTicker = createTestComponents(t, config) + executor, sequencer, dac, _, _, stopDAHeightTicker = createTestComponents(t, config) node, cleanup = createNodeWithCustomComponents(t, config, executor, sequencer, dac, p2pClient, ds, stopDAHeightTicker) defer cleanup() @@ -312,7 +312,7 @@ func TestBatchQueueThrottlingWithDAFailure(t *testing.T) { config.DA.BlockTime = evconfig.DurationWrapper{Duration: 100 * time.Millisecond} // Longer DA time to ensure blocks are produced first // Create test components - executor, sequencer, dummyDA, p2pClient, ds, _, stopDAHeightTicker := createTestComponents(t, config) + executor, sequencer, dummyDA, ds, _, stopDAHeightTicker := createTestComponents(t, config) defer stopDAHeightTicker() // Cast executor to DummyExecutor so we can inject transactions diff --git a/pkg/cmd/run_node.go b/pkg/cmd/run_node.go index 73b2889655..341672bf9d 100644 --- a/pkg/cmd/run_node.go +++ b/pkg/cmd/run_node.go @@ -7,6 +7,7 @@ import ( "os" "os/signal" "path/filepath" + "runtime" "strings" "syscall" "time" @@ -21,7 +22,7 @@ import ( "github.com/evstack/ev-node/node" rollconf "github.com/evstack/ev-node/pkg/config" genesispkg "github.com/evstack/ev-node/pkg/genesis" - "github.com/evstack/ev-node/pkg/p2p" + "github.com/evstack/ev-node/pkg/p2p/key" "github.com/evstack/ev-node/pkg/signer" "github.com/evstack/ev-node/pkg/signer/file" ) @@ -82,7 +83,7 @@ func StartNode( executor coreexecutor.Executor, sequencer coresequencer.Sequencer, da coreda.DA, - p2pClient *p2p.Client, + nodeKey *key.NodeKey, datastore datastore.Batching, nodeConfig rollconf.Config, genesis genesispkg.Genesis, @@ -122,7 +123,7 @@ func StartNode( sequencer, da, signer, - p2pClient, + nodeKey, genesis, datastore, metrics, @@ -139,8 +140,10 @@ func StartNode( go func() { defer func() { if r := recover(); r != nil { - err := fmt.Errorf("node panicked: %v", r) - logger.Error().Interface("panic", r).Msg("Recovered from panic in node") + buf := make([]byte, 1024) + n := runtime.Stack(buf, false) + err := fmt.Errorf("node panicked: %v\nstack trace:\n%s", r, buf[:n]) + logger.Error().Interface("panic", r).Str("stacktrace", string(buf[:n])).Msg("Recovered from panic in node") select { case errCh <- err: default: diff --git a/pkg/cmd/run_node_test.go b/pkg/cmd/run_node_test.go index 895200509a..cffc92bf21 100644 --- a/pkg/cmd/run_node_test.go +++ b/pkg/cmd/run_node_test.go @@ -8,6 +8,7 @@ import ( "testing" "time" + "github.com/evstack/ev-node/pkg/p2p/key" "github.com/ipfs/go-datastore" "github.com/rs/zerolog" "github.com/spf13/cobra" @@ -19,14 +20,13 @@ import ( "github.com/evstack/ev-node/node" rollconf "github.com/evstack/ev-node/pkg/config" genesis "github.com/evstack/ev-node/pkg/genesis" - "github.com/evstack/ev-node/pkg/p2p" "github.com/evstack/ev-node/pkg/signer" filesigner "github.com/evstack/ev-node/pkg/signer/file" ) const MockDANamespace = "test" -func createTestComponents(_ context.Context, t *testing.T) (coreexecutor.Executor, coresequencer.Sequencer, coreda.DA, signer.Signer, *p2p.Client, datastore.Batching, func()) { +func createTestComponents(_ context.Context, t *testing.T) (coreexecutor.Executor, coresequencer.Sequencer, coreda.DA, signer.Signer, *key.NodeKey, datastore.Batching, func()) { executor := coreexecutor.NewDummyExecutor() sequencer := coresequencer.NewDummySequencer() dummyDA := coreda.NewDummyDA(100_000, 0, 0, 10*time.Second) @@ -40,10 +40,9 @@ func createTestComponents(_ context.Context, t *testing.T) (coreexecutor.Executo panic(err) } // Create a dummy P2P client and datastore for testing - p2pClient := &p2p.Client{} ds := datastore.NewMapDatastore() - return executor, sequencer, dummyDA, keyProvider, p2pClient, ds, stopDAHeightTicker + return executor, sequencer, dummyDA, keyProvider, nil, ds, stopDAHeightTicker } func TestParseFlags(t *testing.T) { @@ -81,13 +80,13 @@ func TestParseFlags(t *testing.T) { args := append([]string{"start"}, flags...) - executor, sequencer, dac, keyProvider, p2pClient, ds, stopDAHeightTicker := createTestComponents(context.Background(), t) + executor, sequencer, dac, keyProvider, nodeKey, ds, stopDAHeightTicker := createTestComponents(context.Background(), t) defer stopDAHeightTicker() nodeConfig := rollconf.DefaultConfig() nodeConfig.RootDir = t.TempDir() - newRunNodeCmd := newRunNodeCmd(t.Context(), executor, sequencer, dac, keyProvider, p2pClient, ds, nodeConfig) + newRunNodeCmd := newRunNodeCmd(t.Context(), executor, sequencer, dac, keyProvider, nodeKey, ds, nodeConfig) _ = newRunNodeCmd.Flags().Set(rollconf.FlagRootDir, "custom/root/dir") if err := newRunNodeCmd.ParseFlags(args); err != nil { t.Errorf("Error: %v", err) @@ -159,13 +158,13 @@ func TestAggregatorFlagInvariants(t *testing.T) { for i, flags := range flagVariants { args := append([]string{"start"}, flags...) - executor, sequencer, dac, keyProvider, p2pClient, ds, stopDAHeightTicker := createTestComponents(context.Background(), t) + executor, sequencer, dac, keyProvider, nodeKey, ds, stopDAHeightTicker := createTestComponents(context.Background(), t) defer stopDAHeightTicker() nodeConfig := rollconf.DefaultConfig() nodeConfig.RootDir = t.TempDir() - newRunNodeCmd := newRunNodeCmd(t.Context(), executor, sequencer, dac, keyProvider, p2pClient, ds, nodeConfig) + newRunNodeCmd := newRunNodeCmd(t.Context(), executor, sequencer, dac, keyProvider, nodeKey, ds, nodeConfig) _ = newRunNodeCmd.Flags().Set(rollconf.FlagRootDir, "custom/root/dir") if err := newRunNodeCmd.ParseFlags(args); err != nil { @@ -195,13 +194,13 @@ func TestDefaultAggregatorValue(t *testing.T) { } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - executor, sequencer, dac, keyProvider, p2pClient, ds, stopDAHeightTicker := createTestComponents(context.Background(), t) + executor, sequencer, dac, keyProvider, nodeKey, ds, stopDAHeightTicker := createTestComponents(context.Background(), t) defer stopDAHeightTicker() nodeConfig := rollconf.DefaultConfig() nodeConfig.RootDir = t.TempDir() - newRunNodeCmd := newRunNodeCmd(t.Context(), executor, sequencer, dac, keyProvider, p2pClient, ds, nodeConfig) + newRunNodeCmd := newRunNodeCmd(t.Context(), executor, sequencer, dac, keyProvider, nodeKey, ds, nodeConfig) _ = newRunNodeCmd.Flags().Set(rollconf.FlagRootDir, "custom/root/dir") // Create a new command without specifying any flags @@ -277,10 +276,10 @@ func TestCentralizedAddresses(t *testing.T) { "--rollkit.da.address=http://central-da:26657", } - executor, sequencer, dac, keyProvider, p2pClient, ds, stopDAHeightTicker := createTestComponents(context.Background(), t) + executor, sequencer, dac, keyProvider, nodeKey, ds, stopDAHeightTicker := createTestComponents(context.Background(), t) defer stopDAHeightTicker() - cmd := newRunNodeCmd(t.Context(), executor, sequencer, dac, keyProvider, p2pClient, ds, nodeConfig) + cmd := newRunNodeCmd(t.Context(), executor, sequencer, dac, keyProvider, nodeKey, ds, nodeConfig) _ = cmd.Flags().Set(rollconf.FlagRootDir, "custom/root/dir") if err := cmd.ParseFlags(args); err != nil { t.Fatalf("ParseFlags error: %v", err) @@ -543,7 +542,7 @@ func TestStartNodeSignerPathResolution(t *testing.T) { func TestStartNodeErrors(t *testing.T) { baseCtx := context.Background() - executor, sequencer, dac, _, p2pClient, ds, stopDAHeightTicker := createTestComponents(baseCtx, t) + executor, sequencer, dac, _, nodeKey, ds, stopDAHeightTicker := createTestComponents(baseCtx, t) defer stopDAHeightTicker() tmpDir := t.TempDir() @@ -636,7 +635,7 @@ func TestStartNodeErrors(t *testing.T) { dummySigner, _ := filesigner.CreateFileSystemSigner(dummySignerPath, []byte("password")) - cmd := newRunNodeCmd(baseCtx, executor, sequencer, dac, dummySigner, p2pClient, ds, nodeConfig) + cmd := newRunNodeCmd(baseCtx, executor, sequencer, dac, dummySigner, nodeKey, ds, nodeConfig) cmd.SetContext(baseCtx) @@ -647,7 +646,7 @@ func TestStartNodeErrors(t *testing.T) { runFunc := func() { currentTestLogger := zerolog.Nop() - err := StartNode(currentTestLogger, cmd, executor, sequencer, dac, p2pClient, ds, nodeConfig, testGenesis, node.NodeOptions{}) + err := StartNode(currentTestLogger, cmd, executor, sequencer, dac, nodeKey, ds, nodeConfig, testGenesis, node.NodeOptions{}) if tc.expectedError != "" { assert.ErrorContains(t, err, tc.expectedError) } else { @@ -664,7 +663,7 @@ func TestStartNodeErrors(t *testing.T) { } else { assert.NotPanics(t, runFunc) checkLogger := zerolog.Nop() - err := StartNode(checkLogger, cmd, executor, sequencer, dac, p2pClient, ds, nodeConfig, testGenesis, node.NodeOptions{}) + err := StartNode(checkLogger, cmd, executor, sequencer, dac, nodeKey, ds, nodeConfig, testGenesis, node.NodeOptions{}) if tc.expectedError != "" { assert.ErrorContains(t, err, tc.expectedError) } @@ -680,7 +679,7 @@ func newRunNodeCmd( sequencer coresequencer.Sequencer, dac coreda.DA, remoteSigner signer.Signer, - p2pClient *p2p.Client, + nodeKey *key.NodeKey, datastore datastore.Batching, nodeConfig rollconf.Config, ) *cobra.Command { @@ -702,7 +701,7 @@ func newRunNodeCmd( Aliases: []string{"node", "run"}, Short: "Run the rollkit node", RunE: func(cmd *cobra.Command, args []string) error { - return StartNode(zerolog.Nop(), cmd, executor, sequencer, dac, p2pClient, datastore, nodeConfig, testGenesis, node.NodeOptions{}) + return StartNode(zerolog.Nop(), cmd, executor, sequencer, dac, nodeKey, datastore, nodeConfig, testGenesis, node.NodeOptions{}) }, } diff --git a/pkg/config/config.go b/pkg/config/config.go index d7309d7c3a..a04ff3741f 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -123,6 +123,27 @@ const ( FlagRPCAddress = FlagPrefixEvnode + "rpc.address" // FlagRPCEnableDAVisualization is a flag for enabling DA visualization endpoints FlagRPCEnableDAVisualization = FlagPrefixEvnode + "rpc.enable_da_visualization" + + // Raft configuration flags + + // FlagRaftEnable is a flag for enabling Raft consensus + FlagRaftEnable = FlagPrefixEvnode + "raft.enable" + // FlagRaftNodeID is a flag for specifying the Raft node ID + FlagRaftNodeID = FlagPrefixEvnode + "raft.node_id" + // FlagRaftAddr is a flag for specifying the Raft communication address + FlagRaftAddr = FlagPrefixEvnode + "raft.raft_addr" + // FlagRaftDir is a flag for specifying the Raft data directory + FlagRaftDir = FlagPrefixEvnode + "raft.raft_dir" + // FlagRaftBootstrap is a flag for bootstrapping a new Raft cluster + FlagRaftBootstrap = FlagPrefixEvnode + "raft.bootstrap" + // FlagRaftPeers is a flag for specifying Raft peer addresses + FlagRaftPeers = FlagPrefixEvnode + "raft.peers" + // FlagRaftSnapCount is a flag for specifying snapshot frequency + FlagRaftSnapCount = FlagPrefixEvnode + "raft.snap_count" + // FlagRaftSendTimeout max time to wait for a message to be sent to a peer + FlagRaftSendTimeout = FlagPrefixEvnode + "raft.send_timeout" + // FlagRaftHeartbeatTimeout is a flag for specifying heartbeat timeout + FlagRaftHeartbeatTimeout = FlagPrefixEvnode + "raft.heartbeat_timeout" ) // Config stores Rollkit configuration. @@ -152,6 +173,9 @@ type Config struct { // Remote signer configuration Signer SignerConfig `mapstructure:"signer" yaml:"signer"` + + // Raft consensus configuration + Raft RaftConfig `mapstructure:"raft" yaml:"raft"` } // DAConfig contains all Data Availability configuration parameters @@ -228,6 +252,19 @@ type RPCConfig struct { EnableDAVisualization bool `mapstructure:"enable_da_visualization" yaml:"enable_da_visualization" comment:"Enable DA visualization endpoints for monitoring blob submissions. Default: false"` } +// RaftConfig contains all Raft consensus configuration parameters +type RaftConfig struct { + Enable bool `mapstructure:"enable" yaml:"enable" comment:"Enable Raft consensus for leader election and state replication"` + NodeID string `mapstructure:"node_id" yaml:"node_id" comment:"Unique identifier for this node in the Raft cluster"` + RaftAddr string `mapstructure:"raft_addr" yaml:"raft_addr" comment:"Address for Raft communication (host:port)"` + RaftDir string `mapstructure:"raft_dir" yaml:"raft_dir" comment:"Directory for Raft logs and snapshots"` + Bootstrap bool `mapstructure:"bootstrap" yaml:"bootstrap" comment:"Bootstrap a new Raft cluster (only for the first node)"` + Peers string `mapstructure:"peers" yaml:"peers" comment:"Comma-separated list of peer Raft addresses (nodeID@host:port)"` + SnapCount uint64 `mapstructure:"snap_count" yaml:"snap_count" comment:"Number of log entries between snapshots"` + SendTimeout time.Duration `mapstructure:"send_timeout" yaml:"send_timeout" comment:"Max duration to wait for a message to be sent to a peer"` + HeartbeatTimeout time.Duration `mapstructure:"heartbeat_timeout" yaml:"heartbeat_timeout" comment:"Time between leader heartbeats to followers"` +} + // Validate ensures validates the config and ensure that the root directory exists. // It creates the directory if it does not exist. func (c *Config) Validate() error { @@ -350,6 +387,17 @@ func AddFlags(cmd *cobra.Command) { cmd.Flags().String(FlagSignerType, def.Signer.SignerType, "type of signer to use (file, grpc)") cmd.Flags().String(FlagSignerPath, def.Signer.SignerPath, "path to the signer file or address") cmd.Flags().String(FlagSignerPassphrase, "", "passphrase for the signer (required for file signer and if aggregator is enabled)") + + // Raft configuration flags + cmd.Flags().Bool(FlagRaftEnable, def.Raft.Enable, "enable Raft consensus for leader election and state replication") + cmd.Flags().String(FlagRaftNodeID, def.Raft.NodeID, "unique identifier for this node in the Raft cluster") + cmd.Flags().String(FlagRaftAddr, def.Raft.RaftAddr, "address for Raft communication (host:port)") + cmd.Flags().String(FlagRaftDir, def.Raft.RaftDir, "directory for Raft logs and snapshots") + cmd.Flags().Bool(FlagRaftBootstrap, def.Raft.Bootstrap, "bootstrap a new Raft cluster (only for the first node)") + cmd.Flags().String(FlagRaftPeers, def.Raft.Peers, "comma-separated list of peer Raft addresses (nodeID@host:port)") + cmd.Flags().Uint64(FlagRaftSnapCount, def.Raft.SnapCount, "number of log entries between snapshots") + cmd.Flags().Duration(FlagRaftSendTimeout, def.Raft.SendTimeout, "max duration to wait for a message to be sent to a peer") + cmd.Flags().Duration(FlagRaftHeartbeatTimeout, def.Raft.HeartbeatTimeout, "time between leader heartbeats to followers") } // Load loads the node configuration in the following order of precedence: diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index 3f9b85913a..a82766cded 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -103,7 +103,7 @@ func TestAddFlags(t *testing.T) { assertFlagValue(t, flags, FlagRPCAddress, DefaultConfig().RPC.Address) // Count the number of flags we're explicitly checking - expectedFlagCount := 38 // Update this number if you add more flag checks above + expectedFlagCount := 47 // Update this number if you add more flag checks above // Get the actual number of flags (both regular and persistent) actualFlagCount := 0 diff --git a/pkg/config/defaults.go b/pkg/config/defaults.go index 4f18d96449..01b76b0632 100644 --- a/pkg/config/defaults.go +++ b/pkg/config/defaults.go @@ -77,6 +77,9 @@ func DefaultConfig() Config { Address: "127.0.0.1:7331", EnableDAVisualization: false, }, + Raft: RaftConfig{ + HeartbeatTimeout: 1000 * time.Millisecond, + }, } } diff --git a/pkg/raft/election.go b/pkg/raft/election.go new file mode 100644 index 0000000000..14a3ebbcd3 --- /dev/null +++ b/pkg/raft/election.go @@ -0,0 +1,87 @@ +package raft + +import ( + "context" + "errors" + "fmt" + "sync" + "time" +) + +var ErrLeadershipLost = fmt.Errorf("leader lock lost") + +// RunWithElection manages leader election and runs leader-only operations. +// It's recommended that leaderFunc accepts a context.Context to allow for graceful shutdown. +// This is a blocking operation +func (n *Node) RunWithElection(ctx context.Context, leaderFunc, followerFunc func(leaderCtx context.Context) error) error { + var isStarted, isCurrentlyLeader bool + var workerCancel context.CancelFunc = func() {} // noop + var wg sync.WaitGroup + errCh := make(chan error, 1) + + defer func() { + workerCancel() + wg.Wait() + close(errCh) + }() + + startWorker := func(name string, workerFunc func(ctx context.Context) error) { + workerCtx, cancel := context.WithCancel(ctx) + workerCancel = cancel + wg.Add(1) + + // call workerFunc in a separate goroutine + go func(childCtx context.Context) { + defer wg.Done() + if err := workerFunc(childCtx); err != nil && !errors.Is(err, context.Canceled) { + select { + case errCh <- fmt.Errorf(name+" worker exited unexpectedly: %s", err): + default: // do not block + } + } + }(workerCtx) + } + ticker := time.NewTicker(300 * time.Millisecond) + defer ticker.Stop() + + for { + select { + case isLeader := <-n.raft.LeaderCh(): + n.logger.Info().Msg("Raft leader changed notification") + if isLeader && !isCurrentlyLeader { // new leader + if isStarted { + n.logger.Info().Msg("became leader, stopping follower operations") + workerCancel() + wg.Wait() + } + n.logger.Info().Msg("starting leader operations") + isCurrentlyLeader, isStarted = true, true + startWorker("leader", leaderFunc) + } else if !isLeader && isCurrentlyLeader { // lost leadership + workerCancel() + n.logger.Info().Msg("lost leadership") + return ErrLeadershipLost + } else if !isLeader && !isCurrentlyLeader && !isStarted { // start as follower + n.logger.Info().Msg("starting follower operations") + isStarted = true + startWorker("follower", followerFunc) + } + case <-ticker.C: // LeaderCh fires only when leader changes not on initial election + if isStarted { + ticker.Stop() + continue + } + _, nodeID := n.raft.LeaderWithID() + if nodeID != "" && string(nodeID) != n.config.NodeID { + ticker.Stop() + n.logger.Info().Msg("starting follower operations") + isStarted = true + startWorker("follower", followerFunc) + } + case err := <-errCh: + return err + case <-ctx.Done(): + return ctx.Err() + } + } +} diff --git a/pkg/raft/node.go b/pkg/raft/node.go new file mode 100644 index 0000000000..58d6abb4a4 --- /dev/null +++ b/pkg/raft/node.go @@ -0,0 +1,314 @@ +package raft + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "net" + "os" + "path/filepath" + "strings" + "time" + + "github.com/hashicorp/raft" + raftboltdb "github.com/hashicorp/raft-boltdb" + "github.com/rs/zerolog" +) + +type clusterClient interface { + AddPeer(ctx context.Context, id, addr string) error + RemovePeer(ctx context.Context, id string) error +} + +// Node represents a raft consensus node +type Node struct { + raft *raft.Raft + fsm *FSM + config *Config + clusterClient clusterClient + logger zerolog.Logger +} + +// Config holds raft node configuration +type Config struct { + NodeID string + RaftAddr string + RaftDir string + Bootstrap bool + Peers []string + SnapCount uint64 + SendTimeout time.Duration + HeartbeatTimeout time.Duration +} + +// FSM implements raft.FSM for block state +type FSM struct { + logger zerolog.Logger + state *RaftBlockState + applyCh chan<- RaftApplyMsg +} + +// NewNode creates a new raft node +func NewNode(cfg *Config, clusterClient clusterClient, logger zerolog.Logger) (*Node, error) { + if err := os.MkdirAll(cfg.RaftDir, 0755); err != nil { + return nil, fmt.Errorf("create raft dir: %w", err) + } + + raftConfig := raft.DefaultConfig() + raftConfig.LocalID = raft.ServerID(cfg.NodeID) + raftConfig.LogLevel = "INFO" + raftConfig.HeartbeatTimeout = cfg.HeartbeatTimeout + raftConfig.LeaderLeaseTimeout = cfg.HeartbeatTimeout / 2 + + fsm := &FSM{ + logger: logger.With().Str("component", "raft-fsm").Logger(), + state: &RaftBlockState{}, + } + + logStore, err := raftboltdb.NewBoltStore(filepath.Join(cfg.RaftDir, "raft-log.db")) + if err != nil { + return nil, fmt.Errorf("create log store: %w", err) + } + + stableStore, err := raftboltdb.NewBoltStore(filepath.Join(cfg.RaftDir, "raft-stable.db")) + if err != nil { + return nil, fmt.Errorf("create stable store: %w", err) + } + + snapshotStore, err := raft.NewFileSnapshotStore(cfg.RaftDir, int(cfg.SnapCount), os.Stderr) + if err != nil { + return nil, fmt.Errorf("create snapshot store: %w", err) + } + + addr, err := net.ResolveTCPAddr("tcp", cfg.RaftAddr) + if err != nil { + return nil, fmt.Errorf("resolve raft addr: %w", err) + } + + transport, err := raft.NewTCPTransport(cfg.RaftAddr, addr, 3, 10*time.Second, os.Stderr) + if err != nil { + return nil, fmt.Errorf("create transport: %w", err) + } + + r, err := raft.NewRaft(raftConfig, fsm, logStore, stableStore, snapshotStore, transport) + if err != nil { + return nil, fmt.Errorf("create raft: %w", err) + } + + node := &Node{ + raft: r, + fsm: fsm, + config: cfg, + clusterClient: clusterClient, + logger: logger.With().Str("component", "raft-node").Logger(), + } + + return node, nil +} + +func (n *Node) Start(ctx context.Context) error { + if !n.config.Bootstrap { + n.logger.Info().Msg("Join raft cluster") + return n.clusterClient.AddPeer(ctx, n.config.NodeID, n.config.RaftAddr) + } + + n.logger.Info().Msg("Boostrap raft cluster") + cfg := raft.Configuration{ + Servers: []raft.Server{ + { + ID: raft.ServerID(n.config.NodeID), + Address: raft.ServerAddress(n.config.RaftAddr), + }, + }, + } + for _, peer := range n.config.Peers { + addr, err := splitPeerAddr(peer) + if err != nil { + return err + } + cfg.Servers = append(cfg.Servers, addr) + } + cfg.Servers = deduplicateServers(cfg.Servers) + + if err := n.raft.BootstrapCluster(cfg).Error(); err != nil { + return fmt.Errorf("bootstrap cluster: %w", err) + } + n.logger.Info().Msg("bootstrapped raft cluster") + return nil + +} + +func deduplicateServers(servers []raft.Server) []raft.Server { + seen := make(map[raft.ServerID]struct{}) + unique := make([]raft.Server, 0, len(servers)) + for _, server := range servers { + key := server.ID + if _, exists := seen[key]; !exists { + seen[key] = struct{}{} + unique = append(unique, server) + } + } + return unique +} + +func (n *Node) Stop() error { + return n.raft.Shutdown().Error() +} + +// IsLeader returns true if this node is the raft leader +func (n *Node) IsLeader() bool { + if n == nil || n.raft == nil { + return false + } + return n.raft.State() == raft.Leader +} +func (n *Node) NodeID() string { + return n.config.NodeID +} + +// ProposeBlock proposes a block state to be replicated via raft +func (n *Node) Broadcast(ctx context.Context, state *RaftBlockState) error { + if !n.IsLeader() { + return fmt.Errorf("not leader") + } + + data, err := json.Marshal(state) // todo:use protobuf + if err != nil { + return fmt.Errorf("marshal block state: %w", err) + } + + future := n.raft.Apply(data, n.config.SendTimeout) + if err := future.Error(); err != nil { + return fmt.Errorf("apply log: %w", err) + } + + return nil +} + +// GetState returns the current replicated state +func (n *Node) GetState() *RaftBlockState { + return n.fsm.state +} + +// AddPeer adds a peer to the raft cluster +func (n *Node) AddPeer(nodeID, addr string) error { + n.logger.Debug().Msgf("received join request for remote node %s at %s", nodeID, addr) + + configFuture := n.raft.GetConfiguration() + if err := configFuture.Error(); err != nil { + return err + } + + // remove first when node is already a member of the cluster + for _, srv := range configFuture.Configuration().Servers { + if srv.ID == raft.ServerID(nodeID) || srv.Address == raft.ServerAddress(addr) { + if srv.Address == raft.ServerAddress(addr) && srv.ID == raft.ServerID(nodeID) { + n.logger.Debug().Msgf("node %s at %s already member of cluster, ignoring join request", nodeID, addr) + return nil + } + future := n.raft.RemoveServer(srv.ID, 0, 0) + if err := future.Error(); err != nil { + return fmt.Errorf("removing existing node %s at %s: %w", nodeID, addr, err) + } + } + } + + f := n.raft.AddVoter(raft.ServerID(nodeID), raft.ServerAddress(addr), 0, 0) + if f.Error() != nil { + return f.Error() + } + n.logger.Debug().Msgf("node %s at %s joined successfully", nodeID, addr) + return nil +} + +// RemovePeer removes a peer from the raft cluster +func (n *Node) RemovePeer(nodeID string) error { + future := n.raft.RemoveServer(raft.ServerID(nodeID), 0, 0) + return future.Error() +} + +// Shutdown stops the raft node +func (n *Node) Shutdown() error { + return n.raft.Shutdown().Error() +} + +// SetApplyCallback sets a callback to be called when log entries are applied +func (n *Node) SetApplyCallback(ch chan<- RaftApplyMsg) { + n.fsm.applyCh = ch +} + +// Apply implements raft.FSM +func (f *FSM) Apply(log *raft.Log) interface{} { + var state RaftBlockState + if err := json.Unmarshal(log.Data, &state); err != nil { + f.logger.Error().Err(err).Msg("unmarshal block state") + return err + } + + f.state = &state + f.logger.Debug().Uint64("height", state.Height).Msg("received block state") + + if f.applyCh != nil { + select { + case f.applyCh <- RaftApplyMsg{Index: log.Index, State: &state}: + default: + f.logger.Warn().Msg("apply channel full, dropping message") + } + } + + return nil +} + +// Snapshot implements raft.FSM +func (f *FSM) Snapshot() (raft.FSMSnapshot, error) { + return &fsmSnapshot{state: f.state}, nil +} + +// Restore implements raft.FSM +func (f *FSM) Restore(rc io.ReadCloser) error { + defer rc.Close() + + var state RaftBlockState + if err := json.NewDecoder(rc).Decode(&state); err != nil { + return fmt.Errorf("decode snapshot: %w", err) + } + + f.state = &state + f.logger.Info().Uint64("height", state.Height).Msg("restored from snapshot") + return nil +} + +type fsmSnapshot struct { + state *RaftBlockState +} + +func (s *fsmSnapshot) Persist(sink raft.SnapshotSink) error { + err := func() error { + if err := json.NewEncoder(sink).Encode(s.state); err != nil { + return err + } + return sink.Close() + }() + + if err != nil { + _ = sink.Cancel() + return err + } + + return nil +} + +func (s *fsmSnapshot) Release() {} + +func splitPeerAddr(peer string) (raft.Server, error) { + parts := strings.Split(peer, "@") + if len(parts) != 2 { + return raft.Server{}, errors.New("expecting nodeID@address for peer") + } + return raft.Server{ + ID: raft.ServerID(parts[0]), + Address: raft.ServerAddress(parts[1]), + }, nil +} diff --git a/pkg/raft/types.go b/pkg/raft/types.go new file mode 100644 index 0000000000..8d27fbf3b5 --- /dev/null +++ b/pkg/raft/types.go @@ -0,0 +1,17 @@ +package raft + +// todo: refactor to use proto +// RaftBlockState represents replicated block state +type RaftBlockState struct { + Height uint64 + Hash []byte + Timestamp uint64 + Header []byte + Data []byte +} + +// RaftApplyMsg is sent when raft applies a log entry +type RaftApplyMsg struct { + Index uint64 + State *RaftBlockState +} diff --git a/pkg/rpc/client/raft_cluster.go b/pkg/rpc/client/raft_cluster.go new file mode 100644 index 0000000000..21ba1a8086 --- /dev/null +++ b/pkg/rpc/client/raft_cluster.go @@ -0,0 +1,75 @@ +package client + +import ( + "bytes" + "context" + "encoding/json" + "errors" + "fmt" + "net/http" +) + +// RaftClusterClient is simple http based client for raft cluster management +type RaftClusterClient struct { + peers []string + httpClient *http.Client +} + +func (r RaftClusterClient) AddPeer(ctx context.Context, id, addr string) error { + val := struct { + NodeID string `json:"id"` + Address string `json:"address"` + }{ + NodeID: id, + Address: addr, + } + return r.broadcast(ctx, "/raft/join", val) +} + +func (r RaftClusterClient) RemovePeer(ctx context.Context, id string) error { + val := struct { + NodeID string `json:"id"` + }{ + NodeID: id, + } + return r.broadcast(ctx, "/raft/remove", val) +} + +func (r RaftClusterClient) broadcast(ctx context.Context, path string, obj any) error { + bz, err := json.Marshal(obj) + if err != nil { + return err + } + + var peerErrs []error + for _, peer := range r.peers { + req, err := http.NewRequestWithContext(ctx, http.MethodPost, peer+path, bytes.NewBuffer(bz)) + if err != nil { + peerErrs = append(peerErrs, err) + continue + } + req.Header.Set("Content-Type", "application/json") + + resp, err := r.httpClient.Do(req) + if err != nil { + peerErrs = append(peerErrs, err) + continue + } + _ = resp.Body.Close() + if resp.StatusCode != http.StatusOK { + peerErrs = append(peerErrs, fmt.Errorf("unexpected status: %s", resp.Status)) + continue + } + } + if len(peerErrs) == len(r.peers) { + return errors.Join(peerErrs...) + } + return nil +} + +func NewRaftClusterClient(peers ...string) (RaftClusterClient, error) { + return RaftClusterClient{ + peers: peers, + httpClient: &http.Client{}, + }, nil +} diff --git a/pkg/rpc/example/example.go b/pkg/rpc/example/example.go index a1bc4cd7c0..9be2dc7748 100644 --- a/pkg/rpc/example/example.go +++ b/pkg/rpc/example/example.go @@ -22,7 +22,7 @@ func StartStoreServer(s store.Store, address string, logger zerolog.Logger) { rpcAddr := fmt.Sprintf("%s:%d", "localhost", 8080) cfg := config.DefaultConfig() - handler, err := server.NewServiceHandler(s, nil, nil, logger, cfg, nil) + handler, err := server.NewServiceHandler(s, nil, nil, logger, cfg, nil, nil) if err != nil { panic(err) } @@ -82,7 +82,7 @@ func ExampleServer(s store.Store) { // Start RPC server rpcAddr := fmt.Sprintf("%s:%d", "localhost", 8080) cfg := config.DefaultConfig() - handler, err := server.NewServiceHandler(s, nil, nil, logger, cfg, nil) + handler, err := server.NewServiceHandler(s, nil, nil, logger, cfg, nil, nil) if err != nil { panic(err) } diff --git a/pkg/rpc/server/da_visualization_test.go b/pkg/rpc/server/da_visualization_test.go index 49642bc155..6b1733769e 100644 --- a/pkg/rpc/server/da_visualization_test.go +++ b/pkg/rpc/server/da_visualization_test.go @@ -255,7 +255,7 @@ func TestRegisterCustomHTTPEndpointsDAVisualization(t *testing.T) { // Create mux and register endpoints mux := http.NewServeMux() - RegisterCustomHTTPEndpoints(mux, nil, nil, config.DefaultConfig(), nil) + RegisterCustomHTTPEndpoints(mux, nil, nil, config.DefaultConfig(), nil, nil) // Test /da endpoint req, err := http.NewRequest("GET", "/da", nil) @@ -292,7 +292,7 @@ func TestRegisterCustomHTTPEndpointsWithoutServer(t *testing.T) { SetDAVisualizationServer(nil) mux := http.NewServeMux() - RegisterCustomHTTPEndpoints(mux, nil, nil, config.DefaultConfig(), nil) + RegisterCustomHTTPEndpoints(mux, nil, nil, config.DefaultConfig(), nil, nil) // Test that endpoints return service unavailable when server is not set endpoints := []string{"/da", "/da/submissions", "/da/blob"} diff --git a/pkg/rpc/server/http.go b/pkg/rpc/server/http.go index a8656c1dd5..d930ded56e 100644 --- a/pkg/rpc/server/http.go +++ b/pkg/rpc/server/http.go @@ -1,6 +1,7 @@ package server import ( + "encoding/json" "fmt" "net/http" @@ -15,7 +16,14 @@ type BestKnownHeightProvider func() uint64 // RegisterCustomHTTPEndpoints is the designated place to add new, non-gRPC, plain HTTP handlers. // Additional custom HTTP endpoints can be registered on the mux here. -func RegisterCustomHTTPEndpoints(mux *http.ServeMux, s store.Store, pm p2p.P2PRPC, cfg config.Config, bestKnownHeightProvider BestKnownHeightProvider) { +func RegisterCustomHTTPEndpoints( + mux *http.ServeMux, + s store.Store, + pm p2p.P2PRPC, + cfg config.Config, + bestKnownHeightProvider BestKnownHeightProvider, + raftNode RaftNodeSource, +) { mux.HandleFunc("/health/live", func(w http.ResponseWriter, r *http.Request) { w.Header().Set("Content-Type", "text/plain") w.WriteHeader(http.StatusOK) @@ -80,6 +88,80 @@ func RegisterCustomHTTPEndpoints(mux *http.ServeMux, s store.Store, pm p2p.P2PRP fmt.Fprintln(w, "READY") }) + // optional Raft node details + if raftNode != nil { + mux.HandleFunc("/raft/node", func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodGet { + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + return + } + rsp := struct { + IsLeader bool `json:"is_leader"` + NodeId string `json:"node_id"` + }{ + IsLeader: raftNode.IsLeader(), + NodeId: raftNode.NodeID(), + } + w.Header().Set("Content-Type", "application/json") + if err := json.NewEncoder(w).Encode(rsp); err != nil { + http.Error(w, "Internal Server Error", http.StatusInternalServerError) + } + }) + + mux.HandleFunc("/raft/join", func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + return + } + defer r.Body.Close() + + var rsp struct { + NodeID string `json:"id"` + Address string `json:"address"` + } + if err := json.NewDecoder(r.Body).Decode(&rsp); err != nil { + http.Error(w, "bad request", http.StatusBadRequest) + return + } + if rsp.NodeID == "" || rsp.Address == "" { + http.Error(w, "id and address are required", http.StatusBadRequest) + return + } + //if !raftNode.IsLeader() { + // http.Error(w, "not leader node", http.StatusMethodNotAllowed) + // return + //} + if err := raftNode.AddPeer(rsp.NodeID, rsp.Address); err != nil { + http.Error(w, "failed to join peer", http.StatusInternalServerError) + } + }) + mux.HandleFunc("/raft/remove", func(w http.ResponseWriter, r *http.Request) { + if r.Method != http.MethodPost { + http.Error(w, "method not allowed", http.StatusMethodNotAllowed) + return + } + defer r.Body.Close() + var rsp struct { + NodeID string `json:"id"` + } + if err := json.NewDecoder(r.Body).Decode(&rsp); err != nil { + http.Error(w, "bad request", http.StatusBadRequest) + } + if rsp.NodeID == "" { + http.Error(w, "id is required", http.StatusBadRequest) + return + } + //if !raftNode.IsLeader() { + // http.Error(w, "not leader node", http.StatusMethodNotAllowed) + // return + //} + if err := raftNode.RemovePeer(rsp.NodeID); err != nil { + http.Error(w, "failed to remove peer", http.StatusInternalServerError) + return + } + }) + } + // DA Visualization endpoints mux.HandleFunc("/da", func(w http.ResponseWriter, r *http.Request) { server := GetDAVisualizationServer() diff --git a/pkg/rpc/server/http_test.go b/pkg/rpc/server/http_test.go index 5fe0a3d5f3..e3b32def4b 100644 --- a/pkg/rpc/server/http_test.go +++ b/pkg/rpc/server/http_test.go @@ -15,7 +15,7 @@ func TestRegisterCustomHTTPEndpoints(t *testing.T) { mux := http.NewServeMux() // Register custom HTTP endpoints - RegisterCustomHTTPEndpoints(mux, nil, nil, config.DefaultConfig(), nil) + RegisterCustomHTTPEndpoints(mux, nil, nil, config.DefaultConfig(), nil, nil) // Create a new HTTP test server with the mux testServer := httptest.NewServer(mux) diff --git a/pkg/rpc/server/server.go b/pkg/rpc/server/server.go index 290994be33..bcaa62494a 100644 --- a/pkg/rpc/server/server.go +++ b/pkg/rpc/server/server.go @@ -307,8 +307,23 @@ func (h *HealthServer) Livez( }), nil } +type RaftNodeSource interface { + IsLeader() bool + NodeID() string + AddPeer(nodeID string, address string) error + RemovePeer(nodeID string) error +} + // NewServiceHandler creates a new HTTP handler for Store, P2P and Health services -func NewServiceHandler(store store.Store, peerManager p2p.P2PRPC, proposerAddress []byte, logger zerolog.Logger, config config.Config, bestKnown BestKnownHeightProvider) (http.Handler, error) { +func NewServiceHandler( + store store.Store, + peerManager p2p.P2PRPC, + proposerAddress []byte, + logger zerolog.Logger, + config config.Config, + bestKnown BestKnownHeightProvider, + raftNode RaftNodeSource, +) (http.Handler, error) { storeServer := NewStoreServer(store, logger) p2pServer := NewP2PServer(peerManager) healthServer := NewHealthServer() @@ -342,7 +357,7 @@ func NewServiceHandler(store store.Store, peerManager p2p.P2PRPC, proposerAddres mux.Handle(configPath, configHandler) // Register custom HTTP endpoints - RegisterCustomHTTPEndpoints(mux, store, peerManager, config, bestKnown) + RegisterCustomHTTPEndpoints(mux, store, peerManager, config, bestKnown, raftNode) // Use h2c to support HTTP/2 without TLS return h2c.NewHandler(mux, &http2.Server{ diff --git a/pkg/rpc/server/server_test.go b/pkg/rpc/server/server_test.go index f177a404c4..71a0ae86c0 100644 --- a/pkg/rpc/server/server_test.go +++ b/pkg/rpc/server/server_test.go @@ -377,7 +377,7 @@ func TestHealthLiveEndpoint(t *testing.T) { // Create the service handler logger := zerolog.Nop() testConfig := config.DefaultConfig() - handler, err := NewServiceHandler(mockStore, mockP2PManager, nil, logger, testConfig, nil) + handler, err := NewServiceHandler(mockStore, mockP2PManager, nil, logger, testConfig, nil, nil) assert.NoError(err) assert.NotNil(handler) @@ -438,7 +438,7 @@ func TestHealthReadyEndpoint(t *testing.T) { mockP2P.On("GetPeers").Return(peers, nil) bestKnown := func() uint64 { return tc.bestKnown } - handler, err := NewServiceHandler(mockStore, mockP2P, nil, logger, testConfig, bestKnown) + handler, err := NewServiceHandler(mockStore, mockP2P, nil, logger, testConfig, bestKnown, nil) require.NoError(t, err) server := httptest.NewServer(handler) defer server.Close() diff --git a/test/e2e/.gitignore b/test/e2e/.gitignore new file mode 100644 index 0000000000..7bed7464d4 --- /dev/null +++ b/test/e2e/.gitignore @@ -0,0 +1 @@ +testnet/ diff --git a/test/e2e/evm_test_common.go b/test/e2e/evm_test_common.go index c0f2e1fcba..03ba3c359d 100644 --- a/test/e2e/evm_test_common.go +++ b/test/e2e/evm_test_common.go @@ -57,6 +57,13 @@ func getAvailablePort() (int, error) { return addr.Port, nil } +func mustGetAvailablePort(t *testing.T) int { + t.Helper() + port, err := getAvailablePort() + require.NoError(t, err) + return port +} + // TestEndpoints holds unique port numbers for each test instance type TestEndpoints struct { DAPort string @@ -167,12 +174,6 @@ func generateTestEndpoints() (*TestEndpoints, error) { // Common constants used across EVM tests const ( - // Port configurations - DAPort = "7980" - RollkitRPCPort = "7331" - - DAAddress = "http://127.0.0.1:" + DAPort - RollkitRPCAddress = "http://127.0.0.1:" + RollkitRPCPort // Test configuration DefaultBlockTime = "150ms" @@ -187,6 +188,8 @@ const ( TestPassphrase = "secret" ) +var DefaultDANamespace = DefaultChainID + const ( SlowPollingInterval = 250 * time.Millisecond // Reduced from 500ms @@ -213,6 +216,7 @@ func getNodeP2PAddress(t *testing.T, sut *SystemUnderTest, nodeHome string, rpcP args = append(args, "--rollkit.rpc.address", "127.0.0.1:"+rpcPort[0]) } + t.Log("RUNNING: ", evmSingleBinaryPath, args) // Run net-info command to get node network information output, err := sut.RunCmd(evmSingleBinaryPath, args...) require.NoError(t, err, "failed to get net-info", output) @@ -274,6 +278,7 @@ func setupSequencerNode(t *testing.T, sut *SystemUnderTest, sequencerHome, jwtSe // Use helper methods to get complete URLs args := []string{ "start", + "--evnode.log.format", "json", "--evm.jwt-secret", jwtSecret, "--evm.genesis-hash", genesisHash, "--rollkit.node.block_time", DefaultBlockTime, @@ -309,6 +314,7 @@ func setupSequencerNodeLazy(t *testing.T, sut *SystemUnderTest, sequencerHome, j // Use helper methods to get complete URLs args := []string{ "start", + "--evnode.log.format", "json", "--evm.jwt-secret", jwtSecret, "--evm.genesis-hash", genesisHash, "--rollkit.node.block_time", DefaultBlockTime, @@ -364,6 +370,7 @@ func setupFullNode(t *testing.T, sut *SystemUnderTest, fullNodeHome, sequencerHo // Use helper methods to get complete URLs args := []string{ "start", + "--evnode.log.format", "json", "--home", fullNodeHome, "--evm.jwt-secret", fullNodeJwtSecret, "--evm.genesis-hash", genesisHash, @@ -395,21 +402,25 @@ var globalNonce uint64 = 0 // // This is used in full node sync tests to verify that both nodes // include the same transaction in the same block number. -func submitTransactionAndGetBlockNumber(t *testing.T, sequencerClient *ethclient.Client) (common.Hash, uint64) { +func submitTransactionAndGetBlockNumber(t *testing.T, sequencerClients ...*ethclient.Client) (common.Hash, uint64) { t.Helper() // Submit transaction to sequencer EVM with unique nonce tx := evm.GetRandomTransaction(t, TestPrivateKey, TestToAddress, DefaultChainID, DefaultGasLimit, &globalNonce) - require.NoError(t, sequencerClient.SendTransaction(context.Background(), tx)) + for _, c := range sequencerClients { + require.NoError(t, c.SendTransaction(context.Background(), tx)) + } // Wait for transaction to be included and get block number ctx := context.Background() var txBlockNumber uint64 require.Eventually(t, func() bool { - receipt, err := sequencerClient.TransactionReceipt(ctx, tx.Hash()) - if err == nil && receipt != nil && receipt.Status == 1 { - txBlockNumber = receipt.BlockNumber.Uint64() - return true + for _, c := range sequencerClients { + receipt, err := c.TransactionReceipt(ctx, tx.Hash()) + if err == nil && receipt != nil && receipt.Status == 1 { + txBlockNumber = receipt.BlockNumber.Uint64() + return true + } } return false }, 8*time.Second, SlowPollingInterval) @@ -563,6 +574,7 @@ func restartDAAndSequencer(t *testing.T, sut *SystemUnderTest, sequencerHome, jw // Then restart the sequencer node (without init - node already exists) sut.ExecCmd(evmSingleBinaryPath, "start", + "--evnode.log.format", "json", "--evm.jwt-secret", jwtSecret, "--evm.genesis-hash", genesisHash, "--rollkit.node.block_time", DefaultBlockTime, @@ -607,6 +619,7 @@ func restartDAAndSequencerLazy(t *testing.T, sut *SystemUnderTest, sequencerHome // Then restart the sequencer node in lazy mode (without init - node already exists) sut.ExecCmd(evmSingleBinaryPath, "start", + "--evnode.log.format", "json", "--evm.jwt-secret", jwtSecret, "--evm.genesis-hash", genesisHash, "--rollkit.node.block_time", DefaultBlockTime, @@ -628,35 +641,6 @@ func restartDAAndSequencerLazy(t *testing.T, sut *SystemUnderTest, sequencerHome sut.AwaitNodeUp(t, endpoints.GetRollkitRPCAddress(), NodeStartupTimeout) } -// restartSequencerNode starts an existing sequencer node without initialization. -// This is used for restart scenarios where the node has already been initialized. -// -// Parameters: -// - sut: SystemUnderTest instance for managing test processes -// - sequencerHome: Directory path for sequencer node data -// - jwtSecret: JWT secret for sequencer's EVM engine authentication -// - genesisHash: Hash of the genesis block for chain validation -func restartSequencerNode(t *testing.T, sut *SystemUnderTest, sequencerHome, jwtSecret, genesisHash string) { - t.Helper() - - // Start sequencer node (without init - node already exists) - sut.ExecCmd(evmSingleBinaryPath, - "start", - "--evm.jwt-secret", jwtSecret, - "--evm.genesis-hash", genesisHash, - "--rollkit.node.block_time", DefaultBlockTime, - "--rollkit.node.aggregator=true", - "--rollkit.signer.passphrase", TestPassphrase, - "--home", sequencerHome, - "--rollkit.da.address", DAAddress, - "--rollkit.da.block_time", DefaultDABlockTime, - ) - - time.Sleep(SlowPollingInterval) - - sut.AwaitNodeUp(t, RollkitRPCAddress, NodeStartupTimeout) -} - // verifyNoBlockProduction verifies that no new blocks are being produced over a specified duration. // This is used to test lazy mode behavior where blocks should only be produced when // transactions are submitted. diff --git a/test/e2e/failover_e2e_test.go b/test/e2e/failover_e2e_test.go new file mode 100644 index 0000000000..876b299d14 --- /dev/null +++ b/test/e2e/failover_e2e_test.go @@ -0,0 +1,401 @@ +//go:build e2e + +package e2e + +import ( + "context" + "encoding/json" + "flag" + "fmt" + "maps" + "net/http" + "os" + "path/filepath" + "strconv" + "strings" + "sync" + "sync/atomic" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethclient" + coreda "github.com/evstack/ev-node/core/da" + "github.com/evstack/ev-node/da/jsonrpc" + evmtest "github.com/evstack/ev-node/execution/evm/test" + "github.com/rs/zerolog" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/evstack/ev-node/execution/evm" +) + +// TestLeaseFailoverE2E runs three node binaries configured to use raft consensus. +// It forces a leader shutdown and verifies leadership failover occurs in the raft cluster. +func TestLeaseFailoverE2E(t *testing.T) { + flag.Parse() + sut := NewSystemUnderTest(t) + if testing.Verbose() { + os.Setenv("GOLOG_LOG_LEVEL", "DEBUG") + t.Cleanup(func() { + os.Unsetenv("GOLOG_LOG_LEVEL") + }) + } + + workDir := t.TempDir() + + // Get JWT secrets and setup common components first + jwtSecret, fullNodeJwtSecret, genesisHash, testEndpoints := setupCommonEVMTest(t, sut, true) + rethFn := evmtest.SetupTestRethNode(t) + jwtSecret3 := rethFn.JWTSecretHex() + fnInfo, err := rethFn.GetNetworkInfo(context.Background()) + require.NoError(t, err, "failed to get full node reth network info") + fullNode3EthPort := fnInfo.External.Ports.RPC + fullNode3EnginePort := fnInfo.External.Ports.Engine + + // Allocate raft ports for all nodes + node1RaftPort := mustGetAvailablePort(t) + node2RaftPort := mustGetAvailablePort(t) + node3RaftPort := mustGetAvailablePort(t) + + // Setup raft addresses + node1RaftAddr := fmt.Sprintf("127.0.0.1:%d", node1RaftPort) + node2RaftAddr := fmt.Sprintf("127.0.0.1:%d", node2RaftPort) + node3RaftAddr := fmt.Sprintf("127.0.0.1:%d", node3RaftPort) + raftCluster := []string{"node1@" + node1RaftAddr, "node2@" + node2RaftAddr, "node3@" + node3RaftAddr} + + bootstrapDir := filepath.Join(workDir, "bootstrap") + initChain(t, sut, bootstrapDir) + + clusterNodes := &raftClusterNodes{ + nodes: make(map[string]*nodeDetails), + } + + // Start node1 (bootstrap node) + go func() { + proc := setupRaftSequencerNode(t, sut, workDir, "node1", node1RaftAddr, jwtSecret, genesisHash, testEndpoints.GetDAAddress(), + bootstrapDir, raftCluster, "", testEndpoints.GetRollkitRPCListen(), testEndpoints.GetRollkitP2PAddress(), + testEndpoints.GetSequencerEngineURL(), testEndpoints.GetSequencerEthURL(), true) + t.Log("Node1 is up") + clusterNodes.Set("node1", testEndpoints.GetRollkitRPCAddress(), proc, testEndpoints.GetSequencerEthURL()) + }() + node1P2PAddr := "" + + // Start node2 (follower) + go func() { + t.Log("Starting Node2") + proc := setupRaftSequencerNode(t, sut, workDir, "node2", node2RaftAddr, fullNodeJwtSecret, genesisHash, testEndpoints.GetDAAddress(), + bootstrapDir, raftCluster, node1P2PAddr, testEndpoints.GetFullNodeRPCListen(), testEndpoints.GetFullNodeP2PAddress(), + testEndpoints.GetFullNodeEngineURL(), testEndpoints.GetFullNodeEthURL(), true) + t.Log("Node2 is up") + + clusterNodes.Set("node2", testEndpoints.GetFullNodeRPCAddress(), proc, testEndpoints.GetFullNodeEthURL()) + }() + + // Start node3 (follower) + node3EthAddr := fmt.Sprintf("http://127.0.0.1:%s", fullNode3EthPort) + go func() { + t.Log("Starting Node3") + p2pPeerList := "" + node3RPCListen := fmt.Sprintf("127.0.0.1:%d", mustGetAvailablePort(t)) + node3P2PAddr := fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", mustGetAvailablePort(t)) + proc := setupRaftSequencerNode(t, sut, workDir, "node3", node3RaftAddr, jwtSecret3, genesisHash, testEndpoints.GetDAAddress(), + bootstrapDir, raftCluster, p2pPeerList, + node3RPCListen, node3P2PAddr, + fmt.Sprintf("http://127.0.0.1:%s", fullNode3EnginePort), node3EthAddr, true) + t.Log("Node3 is up") + clusterNodes.Set("node3", "http://"+node3RPCListen, proc, node3EthAddr) + }() + sut.AwaitNodeUp(t, testEndpoints.GetRollkitRPCAddress(), NodeStartupTimeout) + // Wait for at least 2 blocks to be produced + sut.AwaitNBlocks(t, 2, testEndpoints.GetRollkitRPCAddress(), 6*time.Second) + + // Submit a tx and ensure it propagates to all nodes + leaderNode := clusterNodes.Leader(t) + txHash1, blk1 := submitTransactionAndGetBlockNumber(t, clusterNodes.Details(leaderNode).ethClient(t)) + + for node, details := range clusterNodes.Followers(t) { + require.Eventually(t, func() bool { + rec, err := details.ethClient(t).TransactionReceipt(t.Context(), txHash1) + return err == nil && rec != nil && rec.Status == 1 && rec.BlockNumber.Uint64() == blk1 + }, 20*time.Second, SlowPollingInterval, "tx1 not seen on "+node) + } + + oldLeader := leaderNode + t.Logf("+++ Killing current leader (%s)\n", oldLeader) + _ = clusterNodes.Details(oldLeader).Kill() + leaderElectionStart := time.Now() + lastDABlockOldLeader := queryLastDAHeight(t, 1, jwtSecret, testEndpoints.GetDAAddress()) + t.Log("+++ Last DA block by old leader: ", lastDABlockOldLeader) + + // Wait for new leader election - submit tx to node2 + var newLeader string + require.EventuallyWithT(t, func(collect *assert.CollectT) { + newLeader = clusterNodes.Leader(collect) + }, 5*time.Second, 200*time.Millisecond) + leaderFailoverTime := time.Since(leaderElectionStart) + t.Logf("+++ New leader: %s within %s\n", newLeader, leaderFailoverTime) + require.NotEqual(t, oldLeader, newLeader) + + _, blk2 := submitTxToURL(t, clusterNodes.Details(newLeader).ethClient(t)) + require.Greater(t, blk2, blk1, "post-failover block should advance") + + // Verify DA progress + var lastDABlockNewLeader uint64 + require.Eventually(t, func() bool { + lastDABlockNewLeader = queryLastDAHeight(t, lastDABlockOldLeader, jwtSecret, testEndpoints.GetDAAddress()) + return lastDABlockNewLeader > lastDABlockOldLeader + }, 2*must(time.ParseDuration(DefaultDABlockTime)), 100*time.Millisecond) + t.Logf("+++ Last DA block by new leader: %d\n", lastDABlockNewLeader) + + // Restart node1 to rejoin cluster + // todo: re-using peers here and in the server impl is a quick hack. must not be the same config later! + raftClusterRPCs := []string{clusterNodes.Details("node2").rpcAddr, clusterNodes.Details("node3").rpcAddr} + node1Process := setupRaftSequencerNode(t, sut, workDir, "node1", node1RaftAddr, jwtSecret, genesisHash, testEndpoints.GetDAAddress(), + "", raftClusterRPCs, "", + testEndpoints.GetRollkitRPCListen(), testEndpoints.GetRollkitP2PAddress(), + testEndpoints.GetSequencerEngineURL(), testEndpoints.GetSequencerEthURL(), false) + t.Log("Restarted node1 to sync with cluster") + clusterNodes.Set("node1", testEndpoints.GetRollkitRPCAddress(), node1Process, testEndpoints.GetSequencerEthURL()) + + // Wait for several blocks to be produced and propagated + sut.AwaitNBlocks(t, 5, testEndpoints.GetRollkitRPCAddress(), 10*time.Second) + + // Cleanup processes + clusterNodes.killAll() + t.Logf("Completed leader change in: %s", leaderFailoverTime) +} + +func initChain(t *testing.T, sut *SystemUnderTest, workDir string) { + output, err := sut.RunCmd(evmSingleBinaryPath, + "init", + "--chain_id", DefaultChainID, + "--rollkit.node.aggregator=true", + "--rollkit.signer.passphrase", TestPassphrase, + "--home", workDir, + ) + require.NoError(t, err, "failed to init node", output) +} +func setupRaftSequencerNode( + t *testing.T, + sut *SystemUnderTest, + workDir, nodeID, raftAddr, jwtSecret, genesisHash, daAddress string, + bootstrapDir string, + raftPeers []string, + p2pPeers, rpcAddr, p2pAddr, engineURL, ethURL string, + bootstrap bool, +) *os.Process { + t.Helper() + nodeHome := filepath.Join(workDir, nodeID) + raftDir := filepath.Join(nodeHome, "raft") + + if bootstrap { + initChain(t, sut, nodeHome) + + // Copy genesis and signer files for non-genGenesis nodes + MustCopyFile(t, filepath.Join(bootstrapDir, "config", "genesis.json"), + filepath.Join(nodeHome, "config", "genesis.json")) + MustCopyFile(t, filepath.Join(bootstrapDir, "config", "signer.json"), + filepath.Join(nodeHome, "config", "signer.json")) + } + + // Start node with raft configuration + process := sut.ExecCmd(evmSingleBinaryPath, + "start", + "--evnode.log.format", "json", + //"--evnode.log.level", "DEBUG", + "--home", nodeHome, + "--evm.jwt-secret", jwtSecret, + "--evm.genesis-hash", genesisHash, + "--rollkit.da.address", daAddress, + "--rollkit.node.block_time", DefaultBlockTime, + "--rollkit.node.aggregator=true", + "--rollkit.signer.passphrase", TestPassphrase, + "--evnode.signer.signer_path", filepath.Join(nodeHome, "config"), + "--rollkit.da.block_time", (200 * time.Millisecond).String(), + "--rollkit.da.namespace", DefaultDANamespace, + + "--evnode.raft.enable=true", + "--evnode.raft.node_id="+nodeID, + "--evnode.raft.raft_addr="+raftAddr, + "--evnode.raft.raft_dir="+raftDir, + "--evnode.raft.bootstrap="+strconv.FormatBool(bootstrap), + "--evnode.raft.peers="+strings.Join(raftPeers, ","), + "--evnode.raft.snap_count=10", + "--evnode.raft.send_timeout=300ms", + "--evnode.raft.heartbeat_timeout=300ms", + + "--rollkit.p2p.peers", p2pPeers, + "--rollkit.rpc.address", rpcAddr, + "--rollkit.p2p.listen_address", p2pAddr, + "--evm.engine-url", engineURL, + "--evm.eth-url", ethURL, + ) + time.Sleep(SlowPollingInterval) + + //sut.AwaitNodeUp(t, "http://"+rpcAddr, NodeStartupTimeout) + return process +} + +// submitTxToURL submits a tx to the specified EVM endpoint and waits for inclusion. +func submitTxToURL(t *testing.T, client *ethclient.Client) (common.Hash, uint64) { + t.Helper() + ctx, cancel := context.WithTimeout(t.Context(), 10*time.Second) + defer cancel() + + priv, err := crypto.HexToECDSA(TestPrivateKey) + require.NoError(t, err) + from := crypto.PubkeyToAddress(priv.PublicKey) + + nonce, err := client.PendingNonceAt(ctx, from) + require.NoError(t, err) + ln := nonce + + tx := evm.GetRandomTransaction(t, TestPrivateKey, TestToAddress, DefaultChainID, DefaultGasLimit, &ln) + require.NoError(t, client.SendTransaction(ctx, tx)) + + var blk uint64 + require.Eventually(t, func() bool { + rec, err := client.TransactionReceipt(t.Context(), tx.Hash()) + if err == nil && rec != nil && rec.Status == 1 { + blk = rec.BlockNumber.Uint64() + return true + } + return false + }, 20*time.Second, SlowPollingInterval) + + return tx.Hash(), blk +} + +func queryLastDAHeight(t *testing.T, startHeight uint64, jwtSecret string, daAddress string) uint64 { + t.Helper() + logger := zerolog.Nop() + if testing.Verbose() { + logger = zerolog.New(zerolog.NewTestWriter(t)).Level(zerolog.DebugLevel) + } + client, err := jsonrpc.NewClient(t.Context(), logger, daAddress, jwtSecret, 0, 1, 0) + require.NoError(t, err) + defer client.Close() + var lastDABlock = startHeight + for { + res, err := client.DA.GetIDs(t.Context(), lastDABlock, coreda.NamespaceFromString(DefaultDANamespace).Bytes()) + if err != nil { + if strings.Contains(err.Error(), "future") { + break + } + t.Fatal("failed to get IDs:", err) + } + if len(res.IDs) != 0 && testing.Verbose() { + t.Log("+++ DA block: ", lastDABlock, " ids: ", len(res.IDs)) + } + lastDABlock++ + } + return lastDABlock +} + +type nodeDetails struct { + rpcAddr string + process *os.Process + ethAddr string + + ethClientOnce sync.Once + xEthClient atomic.Pointer[ethclient.Client] + running atomic.Bool +} + +func (d *nodeDetails) ethClient(t *testing.T) *ethclient.Client { + t.Helper() + require.NotNil(t, d) + d.ethClientOnce.Do(func() { + client, err := ethclient.Dial(d.ethAddr) + require.NoError(t, err) + d.xEthClient.Store(client) + t.Cleanup(client.Close) + }) + return d.xEthClient.Load() +} + +func (d *nodeDetails) Kill() (err error) { + err = d.process.Kill() + d.running.Store(false) + return +} + +type raftClusterNodes struct { + mx sync.Mutex + nodes map[string]*nodeDetails +} + +func (c *raftClusterNodes) Set(node string, listen string, proc *os.Process, eth string) { + c.mx.Lock() + defer c.mx.Unlock() + d := &nodeDetails{rpcAddr: listen, process: proc, ethAddr: eth} + d.running.Store(true) + c.nodes[node] = d +} + +func (c *raftClusterNodes) Leader(t require.TestingT) string { + c.mx.Lock() + clone := maps.Clone(c.nodes) + c.mx.Unlock() + node, _ := leader(t, clone) + return node +} + +func (c *raftClusterNodes) Details(node string) *nodeDetails { + c.mx.Lock() + defer c.mx.Unlock() + return c.nodes[node] +} + +func (c *raftClusterNodes) Followers(t require.TestingT) map[string]*nodeDetails { + c.mx.Lock() + clone := maps.Clone(c.nodes) + c.mx.Unlock() + leader, _ := leader(t, clone) + delete(clone, leader) + return clone +} + +func (c *raftClusterNodes) killAll() { + c.mx.Lock() + clone := maps.Clone(c.nodes) + c.mx.Unlock() + for _, d := range clone { + _ = d.Kill() + } +} + +// fails when no leader is found +func leader(t require.TestingT, nodes map[string]*nodeDetails) (string, *nodeDetails) { + client := &http.Client{Timeout: 1 * time.Second} + type nodeStatus struct { + IsLeader bool `json:"is_leader"` + } + for node, details := range nodes { + if !details.running.Load() { + continue + } + resp, err := client.Get(details.rpcAddr + "/raft/node") + require.NoError(t, err) + defer resp.Body.Close() + + var status nodeStatus + require.NoError(t, json.NewDecoder(resp.Body).Decode(&status)) + + if status.IsLeader { + return node, details + } + } + + t.Errorf("no leader found") + return "", nil +} + +func must[T any](r T, err error) T { + if err != nil { + panic(err) + } + return r +} diff --git a/test/e2e/go.mod b/test/e2e/go.mod index ad72434f20..33e53f4b4c 100644 --- a/test/e2e/go.mod +++ b/test/e2e/go.mod @@ -8,9 +8,12 @@ require ( github.com/celestiaorg/tastora v0.6.0 github.com/ethereum/go-ethereum v1.16.4 github.com/evstack/ev-node v0.0.0-00010101000000-000000000000 + github.com/evstack/ev-node/core v1.0.0-beta.3 + github.com/evstack/ev-node/da v1.0.0-beta.4 github.com/evstack/ev-node/execution/evm v0.0.0-20250602130019-2a732cf903a5 github.com/evstack/ev-node/execution/evm/test v0.0.0-00010101000000-000000000000 github.com/libp2p/go-libp2p v0.43.0 + github.com/rs/zerolog v1.34.0 github.com/stretchr/testify v1.11.1 ) @@ -81,9 +84,9 @@ require ( github.com/emicklei/dot v1.6.2 // indirect github.com/ethereum/c-kzg-4844/v2 v2.1.3 // indirect github.com/ethereum/go-verkle v0.2.2 // indirect - github.com/evstack/ev-node/core v1.0.0-beta.3 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/ferranbt/fastssz v0.1.4 // indirect + github.com/filecoin-project/go-jsonrpc v0.8.0 // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-kit/kit v0.13.0 // indirect @@ -163,7 +166,6 @@ require ( github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.14.1 // indirect - github.com/rs/zerolog v1.34.0 // indirect github.com/sagikazarmark/locafero v0.11.0 // indirect github.com/sasha-s/go-deadlock v0.3.5 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect @@ -202,6 +204,7 @@ require ( golang.org/x/telemetry v0.0.0-20251001141935-4eae98a72453 // indirect golang.org/x/term v0.35.0 // indirect golang.org/x/text v0.29.0 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/genproto v0.0.0-20240701130421-f6361c86f094 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250825161204-c5933d9347a5 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250825161204-c5933d9347a5 // indirect diff --git a/test/e2e/go.sum b/test/e2e/go.sum index beee325071..f15c8017c2 100644 --- a/test/e2e/go.sum +++ b/test/e2e/go.sum @@ -198,6 +198,8 @@ github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cn github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= github.com/evstack/ev-node/core v1.0.0-beta.3 h1:01K2Ygm3puX4m2OBxvg/HDxu+he54jeNv+KDmpgujFc= github.com/evstack/ev-node/core v1.0.0-beta.3/go.mod h1:n2w/LhYQTPsi48m6lMj16YiIqsaQw6gxwjyJvR+B3sY= +github.com/evstack/ev-node/da v1.0.0-beta.4 h1:6W+UsQrsEdBbAnyy8j+lYNo2VQvJUaoSNkToMFThtVU= +github.com/evstack/ev-node/da v1.0.0-beta.4/go.mod h1:O3Lbx4/WFN0DIUOHdTihmyRnGmQwVXdswH19RW/KyG4= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -206,6 +208,8 @@ github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeD github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg= github.com/filecoin-project/go-clock v0.1.0 h1:SFbYIM75M8NnFm1yMHhN9Ahy3W5bEZV9gd6MPfXbKVU= github.com/filecoin-project/go-clock v0.1.0/go.mod h1:4uB/O4PvOjlx1VCMdZ9MyDZXRm//gkj1ELEbxfI1AZs= +github.com/filecoin-project/go-jsonrpc v0.8.0 h1:2yqlN3Vd8Gx5UtA3fib7tQu2aW1cSOJt253LEBWExo4= +github.com/filecoin-project/go-jsonrpc v0.8.0/go.mod h1:p8WGOwQGYbFugSdK7qKIGhhb1VVcQ2rtBLdEiik1QWI= github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= @@ -332,8 +336,8 @@ github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NM 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/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= -github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.6.2 h1:NOtoftovWkDheyUM/8JW3QMiXyxJK3uHRK7wV04nD2I= +github.com/hashicorp/go-hclog v1.6.2/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= @@ -882,6 +886,8 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk= gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= diff --git a/test/e2e/sut_helper.go b/test/e2e/sut_helper.go index ebf1249dfa..ba9a56d14b 100644 --- a/test/e2e/sut_helper.go +++ b/test/e2e/sut_helper.go @@ -51,6 +51,7 @@ func NewSystemUnderTest(t *testing.T) *SystemUnderTest { cmdToPids: make(map[string][]int), outBuff: ring.New(100), errBuff: ring.New(100), + debug: testing.Verbose(), } t.Cleanup(func() { if t.Failed() { @@ -74,7 +75,7 @@ func (s *SystemUnderTest) RunCmd(cmd string, args ...string) (string, error) { } // ExecCmd starts a process for the given command and manages it cleanup on test end. -func (s *SystemUnderTest) ExecCmd(cmd string, args ...string) { +func (s *SystemUnderTest) ExecCmd(cmd string, args ...string) *os.Process { executable := locateExecutable(cmd) c := exec.Command( //nolint:gosec // used by tests only executable, @@ -86,10 +87,11 @@ func (s *SystemUnderTest) ExecCmd(cmd string, args ...string) { err := c.Start() require.NoError(s.t, err) if s.debug { - s.logf("Exec cmd (pid: %d): %s %s", c.Process.Pid, executable, strings.Join(c.Args, " ")) + s.logf("Exec cmd (pid: %d): %s %s", c.Process.Pid, executable, strings.Join(args, " ")) } // cleanup when stopped s.awaitProcessCleanup(c) + return c.Process } // AwaitNodeUp waits until a node is operational by validating it produces blocks. @@ -103,7 +105,7 @@ func (s *SystemUnderTest) AwaitNodeUp(t *testing.T, rpcAddr string, timeout time require.NotNil(t, c) _, err := c.GetHealth(ctx) require.NoError(t, err) - }, timeout, timeout/10, "node is not up") + }, timeout, min(timeout/10, 200*time.Millisecond), "node is not up") } // AwaitNBlocks waits until the node has produced at least `n` blocks. @@ -153,16 +155,24 @@ func (s *SystemUnderTest) awaitProcessCleanup(cmd *exec.Cmd) { func (s *SystemUnderTest) watchLogs(cmd *exec.Cmd) { errReader, err := cmd.StderrPipe() - if err != nil { - panic(fmt.Sprintf("stderr reader error %#+v", err)) + require.NoError(s.t, err) + outReader, err := cmd.StdoutPipe() + require.NoError(s.t, err) + + if s.debug { + logDir := filepath.Join(WorkDir, "testnet") + require.NoError(s.t, os.MkdirAll(logDir, 0o750)) + testName := strings.ReplaceAll(s.t.Name(), "/", "-") + logfileName := filepath.Join(logDir, fmt.Sprintf("exec-%s-%s-%d.out", filepath.Base(cmd.Args[0]), testName, time.Now().UnixNano())) + logfile, err := os.Create(logfileName) + require.NoError(s.t, err) + errReader = io.NopCloser(io.TeeReader(errReader, logfile)) + outReader = io.NopCloser(io.TeeReader(outReader, logfile)) } + stopRingBuffer := make(chan struct{}) go appendToBuf(errReader, s.errBuff, stopRingBuffer) - outReader, err := cmd.StdoutPipe() - if err != nil { - panic(fmt.Sprintf("stdout reader error %#+v", err)) - } go appendToBuf(outReader, s.outBuff, stopRingBuffer) s.t.Cleanup(func() { close(stopRingBuffer)