From 9365717e97c36f82311cec634e0a76e392a1b992 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 17 Sep 2024 15:19:10 -0400 Subject: [PATCH 01/70] wip --- services/api/service.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/services/api/service.go b/services/api/service.go index a5d7933d..7607c969 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -360,6 +360,7 @@ func (api *RelayAPI) getRouter() http.Handler { if api.opts.BlockBuilderAPI { api.log.Info("block builder API enabled") r.HandleFunc(pathBuilderGetValidators, api.handleBuilderGetValidators).Methods(http.MethodGet) + // TODO: Need to update this endpoint to reject requests with a unregistered builder pubkey for a target slot r.HandleFunc(pathSubmitNewBlock, api.handleSubmitNewBlock).Methods(http.MethodPost) } @@ -1733,6 +1734,14 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr return false } + // Do a check in memchache for the slot being with a registered provider. If miss, go to redis. if miss again go to postgres. + api.beaconClient.GetProposerDuties(submission.BidTrace.Slot) // we want to cache this itself + if submission.BidTrace.BuilderPubkey == nil { + log.Info("submitNewBlock failed: builder pubkey is nil") + api.RespondError(w, http.StatusBadRequest, "builder pubkey is nil") + return false + } + // Timestamp check expectedTimestamp := api.genesisInfo.Data.GenesisTime + (submission.BidTrace.Slot * common.SecondsPerSlot) if submission.Timestamp != expectedTimestamp { @@ -1883,6 +1892,7 @@ func (api *RelayAPI) updateRedisBid(opts redisUpdateBidOpts) (*datastore.SaveBid return &updateBidResult, getPayloadResponse, true } +// TODO: Need to update this endpoint to reject requests with a unregistered builder pubkey for a target slot func (api *RelayAPI) handleSubmitNewBlock(w http.ResponseWriter, req *http.Request) { var pf common.Profile var prevTime, nextTime time.Time @@ -2010,7 +2020,7 @@ func (api *RelayAPI) handleSubmitNewBlock(w http.ResponseWriter, req *http.Reque "excessBlobGas": payload.Deneb.ExecutionPayload.ExcessBlobGas, }) } - + // TODO: Need to update this endpoint to reject requests with a unregistered builder pubkey for a target slot ok := api.checkSubmissionSlotDetails(w, log, headSlot, payload, submission) if !ok { return From 803077671c35a7335c6dc0dfa34389a86998e3c7 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 17 Sep 2024 15:25:41 -0400 Subject: [PATCH 02/70] wip: implements basic filtering --- services/api/service.go | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/services/api/service.go b/services/api/service.go index 7607c969..0ab80833 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1735,13 +1735,26 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr } // Do a check in memchache for the slot being with a registered provider. If miss, go to redis. if miss again go to postgres. - api.beaconClient.GetProposerDuties(submission.BidTrace.Slot) // we want to cache this itself - if submission.BidTrace.BuilderPubkey == nil { - log.Info("submitNewBlock failed: builder pubkey is nil") - api.RespondError(w, http.StatusBadRequest, "builder pubkey is nil") + duties, err := api.beaconClient.GetProposerDuties(submission.BidTrace.Slot) // we want to cache this itself + if err != nil { + log.WithError(err).Error("failed to get proposer duties") + api.RespondError(w, http.StatusBadRequest, "failed to get proposer duties") return false } + // memcache this TODO + for _, duty := range duties.Data { + if duty.Slot == submission.BidTrace.Slot { + if api.MevCommitClient.IsValidatorRegistered(duty.Pubkey) { + if !api.MevCommitClient.IsBuilderRegistered(submission.BidTrace.BuilderPubkey.String()) { + api.RespondError(w, http.StatusBadRequest, "builder pubkey is not registered under mev-commit") + return false + } + } + break + } + } + // Timestamp check expectedTimestamp := api.genesisInfo.Data.GenesisTime + (submission.BidTrace.Slot * common.SecondsPerSlot) if submission.Timestamp != expectedTimestamp { From 2776c6a2ac399e39a88dedc20092395eec6eb5c7 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 17 Sep 2024 16:13:12 -0400 Subject: [PATCH 03/70] wip: adds comments around technical decisions that need to be made. --- services/api/service.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/services/api/service.go b/services/api/service.go index 0ab80833..ec6bdf46 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1747,6 +1747,9 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr if duty.Slot == submission.BidTrace.Slot { if api.MevCommitClient.IsValidatorRegistered(duty.Pubkey) { if !api.MevCommitClient.IsBuilderRegistered(submission.BidTrace.BuilderPubkey.String()) { + // TODO: Need to add a check to retrieve if a builder is registered under mev-commit with a specific pubkey. This would slow things down, but hopefully with memcache this isn't too bad. + // One could also archietct to have a member node co-located to the relayer so it has access to the same cache. Or an alternate fast service that receives events from mev-commit and caches the results of provider inclusion. + // A technical decision that needs to be better understood. api.RespondError(w, http.StatusBadRequest, "builder pubkey is not registered under mev-commit") return false } From be89e8496c81345c980fc93903f5fab37e0dd754 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 18 Sep 2024 10:19:47 -0400 Subject: [PATCH 04/70] wip: adds mevcommit relay --- mevcommitclient/mev_commit_client.go | 17 +++++++++ services/api/service.go | 57 +++++++++++++++++----------- 2 files changed, 51 insertions(+), 23 deletions(-) create mode 100644 mevcommitclient/mev_commit_client.go diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go new file mode 100644 index 00000000..02dcda64 --- /dev/null +++ b/mevcommitclient/mev_commit_client.go @@ -0,0 +1,17 @@ +package mevcommitclient + +type IMevCommitClient interface { + IsValidatorRegistered(pubkey string) (bool, error) + IsBuilderRegistered(pubkey string) (bool, error) +} + +type MevCommitClient struct { + L1Address string + MevCommitAddress string +} + +func NewMevCommitClient(apiUrl string) IMevCommitClient { + return &MevCommitClient{ + apiUrl: apiUrl, + } +} \ No newline at end of file diff --git a/services/api/service.go b/services/api/service.go index ec6bdf46..11d81441 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -35,6 +35,7 @@ import ( "github.com/flashbots/mev-boost-relay/database" "github.com/flashbots/mev-boost-relay/datastore" "github.com/flashbots/mev-boost-relay/metrics" + "github.com/flashbots/mev-boost-relay/mevcommitclient" "github.com/go-redis/redis/v9" "github.com/gorilla/mux" "github.com/holiman/uint256" @@ -182,11 +183,13 @@ type RelayAPI struct { srvStarted uberatomic.Bool srvShutdown uberatomic.Bool - beaconClient beaconclient.IMultiBeaconClient - datastore *datastore.Datastore - redis *datastore.RedisCache - memcached *datastore.Memcached - db database.IDatabaseService + beaconClient beaconclient.IMultiBeaconClient + mevCommitClient mevcommitclient.IMevCommitClient + + datastore *datastore.Datastore + redis *datastore.RedisCache + memcached *datastore.Memcached + db database.IDatabaseService headSlot uberatomic.Uint64 genesisInfo *beaconclient.GetGenesisResponse @@ -200,8 +203,7 @@ type RelayAPI struct { isUpdatingProposerDuties uberatomic.Bool blockSimRateLimiter IBlockSimRateLimiter - - validatorRegC chan builderApiV1.SignedValidatorRegistration + validatorRegC chan builderApiV1.SignedValidatorRegistration // used to notify when a new validator has been registered validatorUpdateCh chan struct{} @@ -1735,26 +1737,35 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr } // Do a check in memchache for the slot being with a registered provider. If miss, go to redis. if miss again go to postgres. - duties, err := api.beaconClient.GetProposerDuties(submission.BidTrace.Slot) // we want to cache this itself + + // Find the duty for the submission slot + duty := api.proposerDutiesMap[submission.BidTrace.Slot] + if duty == nil { + log.Info("no duty found for submission slot") + api.RespondError(w, http.StatusBadRequest, "no duty found for submission slot") + return false + } + // Check if validator is registered + isValidatorRegistered, err := api.mevCommitClient.IsValidatorRegistered(duty.Entry.Message.Pubkey.String()) if err != nil { - log.WithError(err).Error("failed to get proposer duties") - api.RespondError(w, http.StatusBadRequest, "failed to get proposer duties") + log.WithError(err).Error("Failed to check validator registration") + api.RespondError(w, http.StatusInternalServerError, "Internal server error") return false } - // memcache this TODO - for _, duty := range duties.Data { - if duty.Slot == submission.BidTrace.Slot { - if api.MevCommitClient.IsValidatorRegistered(duty.Pubkey) { - if !api.MevCommitClient.IsBuilderRegistered(submission.BidTrace.BuilderPubkey.String()) { - // TODO: Need to add a check to retrieve if a builder is registered under mev-commit with a specific pubkey. This would slow things down, but hopefully with memcache this isn't too bad. - // One could also archietct to have a member node co-located to the relayer so it has access to the same cache. Or an alternate fast service that receives events from mev-commit and caches the results of provider inclusion. - // A technical decision that needs to be better understood. - api.RespondError(w, http.StatusBadRequest, "builder pubkey is not registered under mev-commit") - return false - } - } - break + if isValidatorRegistered { + // Check if builder is registered + isBuilderRegistered, err := api.mevCommitClient.IsBuilderRegistered(submission.BidTrace.BuilderPubkey.String()) + if err != nil { + log.WithError(err).Error("Failed to check builder registration") + api.RespondError(w, http.StatusInternalServerError, "Internal server error") + return false + } + + if !isBuilderRegistered { + // TODO: Implement caching strategy for builder registration status + api.RespondError(w, http.StatusBadRequest, "Builder pubkey is not registered under mev-commit") + return false } } From f6703a18da22694832ef8ab91b9741274374b637 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 18 Sep 2024 10:37:25 -0400 Subject: [PATCH 05/70] wip: documenting some thoughts --- mevcommitclient/mev_commit_client.go | 5 +++-- services/api/service.go | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 02dcda64..d949aded 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -1,12 +1,13 @@ package mevcommitclient type IMevCommitClient interface { + // Need to provide some SLA's around response times here. Should be down to milliseconds with memcache. IsValidatorRegistered(pubkey string) (bool, error) IsBuilderRegistered(pubkey string) (bool, error) } type MevCommitClient struct { - L1Address string + L1Address string MevCommitAddress string } @@ -14,4 +15,4 @@ func NewMevCommitClient(apiUrl string) IMevCommitClient { return &MevCommitClient{ apiUrl: apiUrl, } -} \ No newline at end of file +} diff --git a/services/api/service.go b/services/api/service.go index 11d81441..4298b74d 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1475,6 +1475,7 @@ func (api *RelayAPI) handleGetPayload(w http.ResponseWriter, req *http.Request) return } + // TODO(@ckartik): We could do something similar for validator registrations with L1 mevcommit contract. // Get registration entry from the DB. registrationEntry, err := api.db.GetValidatorRegistration(proposerPubkey.String()) if err != nil { From b498fe30b2267652fb1f89077ab97368ea782fa0 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Fri, 20 Sep 2024 10:14:36 -0400 Subject: [PATCH 06/70] wip: more details --- mevcommitclient/mev_commit_client.go | 3 ++- services/api/service.go | 2 ++ services/housekeeper/housekeeper.go | 21 +++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index d949aded..6e354fbc 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -4,10 +4,11 @@ type IMevCommitClient interface { // Need to provide some SLA's around response times here. Should be down to milliseconds with memcache. IsValidatorRegistered(pubkey string) (bool, error) IsBuilderRegistered(pubkey string) (bool, error) + GetRegisteredValidators() ([]string, error) } type MevCommitClient struct { - L1Address string + L1Address string // 0x5d4fC7B5Aeea4CF4F0Ca6Be09A2F5AaDAd2F2803 created at 1731009 block MevCommitAddress string } diff --git a/services/api/service.go b/services/api/service.go index 4298b74d..d2f5ab49 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -139,6 +139,8 @@ type RelayAPIOpts struct { DataAPI bool PprofAPI bool InternalAPI bool + + MevCommitEnabled bool } type payloadAttributesHelper struct { diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index 47ec0e9d..357fcc72 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -21,6 +21,7 @@ import ( "github.com/flashbots/mev-boost-relay/common" "github.com/flashbots/mev-boost-relay/database" "github.com/flashbots/mev-boost-relay/datastore" + "github.com/flashbots/mev-boost-relay/mevcommitclient" "github.com/gorilla/mux" "github.com/sirupsen/logrus" uberatomic "go.uber.org/atomic" @@ -53,6 +54,8 @@ type Housekeeper struct { headSlot uberatomic.Uint64 + mevCommitClient mevcommitclient.IMevCommitClient + proposersAlreadySaved map[uint64]string // to avoid repeating redis writes } @@ -142,6 +145,7 @@ func (hk *Housekeeper) processNewSlot(headSlot uint64) { // Update proposer duties go hk.updateProposerDuties(headSlot) + go hk.updatemevcommitvalidatorregistrations(headSlot) // Set headSlot in redis (for the website) err := hk.redis.SetStats(datastore.RedisStatsFieldLatestSlot, headSlot) @@ -248,6 +252,23 @@ func (hk *Housekeeper) UpdateProposerDutiesWithoutChecks(headSlot uint64) { log.WithField("numDuties", len(_duties)).Infof("proposer duties updated: %s", strings.Join(_duties, ", ")) } +func (hk *Housekeeper) updateMevCommitValidatorRegistrations(headSlot uint64) { + registeredValidators, err := hk.mevCommitClient.GetRegisteredValidators() + if err != nil { + hk.log.WithError(err).Error("failed to get registered validators from MEV-Commit client") + return + } + + // Store the registered validators in Redis + err = hk.redis.SetMevCommitRegisteredValidators(registeredValidators) + if err != nil { + hk.log.WithError(err).Error("failed to store MEV-Commit registered validators in Redis") + return + } + + hk.log.WithField("numValidators", len(registeredValidators)).Info("updated MEV-Commit registered validators in Redis") +} + // updateValidatorRegistrationsInRedis saves all latest validator registrations from the database to Redis func (hk *Housekeeper) updateValidatorRegistrationsInRedis() { regs, err := hk.db.GetLatestValidatorRegistrations(true) From 5216a9fee066336ae440867d39b77ef1338a23e6 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 24 Sep 2024 10:44:34 -0400 Subject: [PATCH 07/70] feat: adds opted in column to builder table --- .../012_add_mev_commit_column_builders.go | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 database/migrations/012_add_mev_commit_column_builders.go diff --git a/database/migrations/012_add_mev_commit_column_builders.go b/database/migrations/012_add_mev_commit_column_builders.go new file mode 100644 index 00000000..09724220 --- /dev/null +++ b/database/migrations/012_add_mev_commit_column_builders.go @@ -0,0 +1,19 @@ +package migrations + +import ( + "github.com/flashbots/mev-boost-relay/database/vars" + migrate "github.com/rubenv/sql-migrate" +) + +var Migration012AddMevCommitColumnBuilders = &migrate.Migration{ + Id: "012-add-mev-commit-column-builders", + Up: []string{` + ALTER TABLE ` + vars.TableBlockBuilder + ` ADD is_mev_commit_enabled boolean NOT NULL DEFAULT false; + `}, + Down: []string{` + ALTER TABLE ` + vars.TableBlockBuilder + ` DROP COLUMN is_mev_commit_enabled; + `}, + + DisableTransactionUp: true, + DisableTransactionDown: true, +} From 44adf4cb0d5569bd89f13ac8d89a3bfc3c3a63c9 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 24 Sep 2024 10:47:30 -0400 Subject: [PATCH 08/70] feat: adds opted in status for validators --- .../012_add_mev_commit_column_builders.go | 4 ++-- .../013_add_mev_commit_column_validators.go | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 database/migrations/013_add_mev_commit_column_validators.go diff --git a/database/migrations/012_add_mev_commit_column_builders.go b/database/migrations/012_add_mev_commit_column_builders.go index 09724220..4c94dd9c 100644 --- a/database/migrations/012_add_mev_commit_column_builders.go +++ b/database/migrations/012_add_mev_commit_column_builders.go @@ -8,10 +8,10 @@ import ( var Migration012AddMevCommitColumnBuilders = &migrate.Migration{ Id: "012-add-mev-commit-column-builders", Up: []string{` - ALTER TABLE ` + vars.TableBlockBuilder + ` ADD is_mev_commit_enabled boolean NOT NULL DEFAULT false; + ALTER TABLE ` + vars.TableBlockBuilder + ` ADD is_mev_commit_opted_in boolean NOT NULL DEFAULT false; `}, Down: []string{` - ALTER TABLE ` + vars.TableBlockBuilder + ` DROP COLUMN is_mev_commit_enabled; + ALTER TABLE ` + vars.TableBlockBuilder + ` DROP COLUMN is_mev_commit_opted_in; `}, DisableTransactionUp: true, diff --git a/database/migrations/013_add_mev_commit_column_validators.go b/database/migrations/013_add_mev_commit_column_validators.go new file mode 100644 index 00000000..e8a39b31 --- /dev/null +++ b/database/migrations/013_add_mev_commit_column_validators.go @@ -0,0 +1,19 @@ +package migrations + +import ( + "github.com/flashbots/mev-boost-relay/database/vars" + migrate "github.com/rubenv/sql-migrate" +) + +var Migration013AddMevCommitColumnValidators = &migrate.Migration{ + Id: "013-add-mev-commit-column-validators", + Up: []string{` + ALTER TABLE ` + vars.TableValidatorRegistration + ` ADD is_mev_commit_opted_in boolean NOT NULL DEFAULT false; + `}, + Down: []string{` + ALTER TABLE ` + vars.TableValidatorRegistration + ` DROP COLUMN is_mev_commit_opted_in; + `}, + + DisableTransactionUp: true, + DisableTransactionDown: true, +} From c440444b434f4be5f7fd8cd7d9c78c0dae6d314e Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 24 Sep 2024 13:34:47 -0400 Subject: [PATCH 09/70] feat: stubs basic mevcommit client --- go.mod | 66 +++-- go.sum | 413 ++++++++------------------- mevcommitclient/mev_commit_client.go | 37 ++- 3 files changed, 181 insertions(+), 335 deletions(-) diff --git a/go.mod b/go.mod index e86481a4..71535693 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/flashbots/mev-boost-relay -go 1.21 +go 1.22 + +toolchain go1.23.1 require ( github.com/NYTimes/gziphandler v1.1.1 @@ -10,7 +12,7 @@ require ( github.com/bradfitz/gomemcache v0.0.0-20230124162541-5f7a7d875746 github.com/btcsuite/btcd/btcutil v1.1.2 github.com/buger/jsonparser v1.1.1 - github.com/ethereum/go-ethereum v1.13.10 + github.com/ethereum/go-ethereum v1.13.14 github.com/flashbots/go-boost-utils v1.8.0 github.com/flashbots/go-utils v0.5.0 github.com/go-redis/redis/v9 v9.0.0-rc.1 @@ -19,7 +21,8 @@ require ( github.com/jmoiron/sqlx v1.3.5 github.com/lib/pq v1.10.8 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.19.0 + github.com/primev/mev-commit/contracts-abi v0.0.0-20240924081916-a1d9f63df193 + github.com/prometheus/client_golang v1.19.1 github.com/r3labs/sse/v2 v2.10.0 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 @@ -31,58 +34,65 @@ require ( go.opentelemetry.io/otel/sdk v1.25.0 go.opentelemetry.io/otel/sdk/metric v1.25.0 go.uber.org/atomic v1.11.0 - golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/text v0.14.0 + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 + golang.org/x/text v0.16.0 ) require ( - github.com/DataDog/zstd v1.5.2 // indirect + github.com/DataDog/zstd v1.5.5 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect github.com/StackExchange/wmi v1.2.1 // indirect - github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.10.0 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/errors v1.11.3 // indirect + github.com/cockroachdb/fifo v0.0.0-20240616162244-4768e80dfb9a // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect + github.com/cockroachdb/pebble v1.1.1 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/fatih/color v1.16.0 // indirect + github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect - github.com/getsentry/sentry-go v0.18.0 // indirect + github.com/getsentry/sentry-go v0.28.1 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-ole/go-ole v1.2.5 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/goccy/go-yaml v1.11.2 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/google/uuid v1.3.1 // indirect - github.com/klauspost/compress v1.15.15 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/klauspost/compress v1.17.9 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.48.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 // indirect - github.com/rivo/uniseg v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/rivo/uniseg v0.4.2 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect go.opentelemetry.io/otel/trace v1.25.0 // indirect - golang.org/x/sync v0.5.0 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/tools v0.23.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) @@ -91,14 +101,14 @@ require ( github.com/btcsuite/btcd v0.23.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/ferranbt/fastssz v0.1.3 github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect - github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect @@ -106,14 +116,14 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/tdewolff/parse v2.3.4+incompatible // indirect github.com/tdewolff/test v1.0.7 // indirect - github.com/tklauser/go-sysconf v0.3.12 // indirect - github.com/tklauser/numcpus v0.6.1 // indirect + github.com/tklauser/go-sysconf v0.3.13 // indirect + github.com/tklauser/numcpus v0.7.0 // indirect github.com/yuin/gopher-lua v1.1.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.25.0 // indirect - golang.org/x/crypto v0.20.0 // indirect - golang.org/x/net v0.21.0 // indirect - golang.org/x/sys v0.18.0 // indirect + golang.org/x/crypto v0.25.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/sys v0.22.0 // indirect gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index d4d8230f..66230a62 100644 --- a/go.sum +++ b/go.sum @@ -1,32 +1,22 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= -github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= -github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +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.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= github.com/alicebob/miniredis/v2 v2.32.1 h1:Bz7CciDnYSaa0mX5xODh6GUITRSx+cVhjNoOR4JssBo= github.com/alicebob/miniredis/v2 v2.32.1/go.mod h1:AqkLNAfUm0K07J28hnAyyQKf/x0YkCY/g5DCtuL01Mw= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= -github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/attestantio/go-builder-client v0.4.3-0.20240124194555-d44db06f45fa h1:Kj6d1tXAA+EAi7fK8z8NakBEpY4WYzZMuCmLZjwBpTM= github.com/attestantio/go-builder-client v0.4.3-0.20240124194555-d44db06f45fa/go.mod h1:e02i/WO4fjs3/u9oIZEjiC8CK1Qyxy4cpiMMGKx4VqQ= github.com/attestantio/go-eth2-client v0.21.1 h1:yvsMd/azPUbxiJzWZhgqfOJJRNF1zLvAJpcBXTHzyh8= github.com/attestantio/go-eth2-client v0.21.1/go.mod h1:Tb412NpzhsC0sbtpXS4D51y5se6nDkWAi6amsJrqX9c= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -61,37 +51,32 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240616162244-4768e80dfb9a h1:f52TdbU4D5nozMAhO9TvTJ2ZMCXtN4VIAmfrrZ0JXQ4= +github.com/cockroachdb/fifo v0.0.0-20240616162244-4768e80dfb9a/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593 h1:aPEJyR4rPBvDmeyi+l/FS/VtA00IWvjeFvjen1m1l1A= -github.com/cockroachdb/pebble v0.0.0-20230928194634-aa077af62593/go.mod h1:6hk1eMY/u5t+Cf18q5lFMUA1Rc+Sm5I6Ra1QuPyxXCo= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/pebble v1.1.1 h1:XnKU22oiCLy2Xn8vp1re67cXg4SAasg/WDt1NtcRFaw= +github.com/cockroachdb/pebble v1.1.1/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= @@ -102,34 +87,27 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.13.10 h1:Ppdil79nN+Vc+mXfge0AuUgmKWuVv4eMqzoIVSdqZek= -github.com/ethereum/go-ethereum v1.13.10/go.mod h1:sc48XYQxCzH3fG9BcrXCOOgQk2JfZzNAmIKnceogzsA= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/ethereum/go-ethereum v1.13.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ= +github.com/ethereum/go-ethereum v1.13.14/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU= 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/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/ferranbt/fastssz v0.1.3 h1:ZI+z3JH05h4kgmFXdHuR1aWYsgrg7o+Fw7/NCzM16Mo= github.com/ferranbt/fastssz v0.1.3/go.mod h1:0Y9TEd/9XuFlh7mskMPfXiI2Dkw4Ddg9EyXt1W7MRvE= +github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA= +github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/flashbots/go-boost-utils v1.8.0 h1:z3K1hw+Fbl9AGMNQKnK7Bvf0M/rKgjfruAEvra+Z8Mg= github.com/flashbots/go-boost-utils v1.8.0/go.mod h1:Ry1Rw8Lx5v1rpAR0+IvR4sV10jYAeQaGVM3vRD8mYdM= github.com/flashbots/go-utils v0.5.0 h1:ldjWta9B9//DJU2QcwRbErez3+1aKhSn6EoFc6d5kPY= @@ -138,16 +116,12 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= -github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/getsentry/sentry-go v0.28.1 h1:zzaSm/vHmGllRM6Tpx1492r0YDzauArdBfkJRtY6P5k= +github.com/getsentry/sentry-go v0.28.1/go.mod h1:1fQZ+7l7eeJ3wYi82q5Hg8GqAPgefRq+FP/QhafYVgg= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= @@ -157,9 +131,9 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/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-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= -github.com/go-ole/go-ole v1.2.5 h1:t4MGB5xEDZvXI+0rMjjsfBsD7yAgp/s9ZDkL1JndXwY= 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-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= @@ -176,58 +150,44 @@ github.com/gobuffalo/packd v1.0.1 h1:U2wXfRr4E9DH8IdsDLlRFwTZTK7hLfq9qT/QHXGVe/0 github.com/gobuffalo/packd v1.0.1/go.mod h1:PP2POP3p3RXGz7Jh6eYEf93S7vA2za6xM7QT85L4+VY= github.com/gobuffalo/packr/v2 v2.8.3 h1:xE1yzvnO56cUC0sTpKR3DIbxZgB54AftTFMhB2XEWlY= github.com/gobuffalo/packr/v2 v2.8.3/go.mod h1:0SahksCVcx4IMnigTjiFuyldmTrdTctXsOdiU5KwbKc= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/goccy/go-yaml v1.11.2 h1:joq77SxuyIs9zzxEjgyLBugMQ9NEgTWxXfz2wVqwAaQ= github.com/goccy/go-yaml v1.11.2/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/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/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/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/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -235,54 +195,32 @@ github.com/huandu/go-clone v1.6.0 h1:HMo5uvg4wgfiy5FoGOqlFLQED/VGRm2D9Pi8g1FXPGc github.com/huandu/go-clone v1.6.0/go.mod h1:ReGivhG6op3GYr+UY3lS6mxjKp7MIGTknuU5TbTVaXE= github.com/huandu/go-clone/generic v1.6.0 h1:Wgmt/fUZ28r16F2Y3APotFD59sHk1p78K0XLdbUYN5U= github.com/huandu/go-clone/generic v1.6.0/go.mod h1:xgd9ZebcMsBWWcBx5mVMCoqMX24gLWr5lQicr+nVXNs= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +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= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= -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/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= github.com/karrick/godirwalk v1.16.1 h1:DynhcF+bztK8gooS0+NDJFrdNZjJ3gzVzC545UNA9iw= github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= -github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= @@ -290,61 +228,41 @@ github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ic github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.8 h1:3fdt97i/cwSU83+E0hZTC/Xpc9mTZxc6UWSCRcSbxiE= github.com/lib/pq v1.10.8/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/markbates/errx v1.1.0 h1:QDFeR+UP95dO12JgW+tgi2UVfo0V8YBHiUIOaeBPiEI= github.com/markbates/errx v1.1.0/go.mod h1:PLa46Oex9KNbVDZhKel8v1OT7hD5JZ2eI7AHhA0wswc= github.com/markbates/oncer v1.0.0 h1:E83IaVAHygyndzPimgUYJjbshhDTALZyXxvk9FOlQRY= github.com/markbates/oncer v1.0.0/go.mod h1:Z59JA581E9GP6w96jai+TGqafHPW+cPfRxz2aSZ0mcI= github.com/markbates/safe v1.0.1 h1:yjZkbvRM6IzKj9tlu/zMJLS0n/V351OZWRnF3QfaUxI= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/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.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= -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.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= -github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= -github.com/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/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +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/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -355,66 +273,53 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.21.1 h1:OB/euWYIExnPBohllTicTHmGTrMaqJ67nIu80j0/uEM= github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -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= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/primev/mev-commit/contracts-abi v0.0.0-20240924081916-a1d9f63df193 h1:XF8Dyvm4wocRgkfqr9jDYYz065HITOgZ/D3rUgR1ZDQ= +github.com/primev/mev-commit/contracts-abi v0.0.0-20240924081916-a1d9f63df193/go.mod h1:TcPhQiI7UmkDTzVGlXlwMq+fmrQ5Sj1xDSSzePZ/rq0= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSzKKE= -github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 h1:0tVE4tdWQK9ZpYygoV7+vS6QkDvQVySboMVEIxBJmXw= github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h1:wmuf/mdK4VMD+jA9ThwcUKjg3a2XWM9cVfFYjDyY4j4= github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0= github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= +github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzFtS0= github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= @@ -428,35 +333,22 @@ github.com/tdewolff/parse v2.3.4+incompatible h1:x05/cnGwIMf4ceLuDMBOdQ1qGniMoxp github.com/tdewolff/parse v2.3.4+incompatible/go.mod h1:8oBwCsVmUkgHO8M5iCzSIDtpzXOT0WXX9cWhz+bIzJQ= github.com/tdewolff/test v1.0.7 h1:8Vs0142DmPFW/bQeHRP3MV19m1gvndjUb1sn8yy74LM= github.com/tdewolff/test v1.0.7/go.mod h1:6DAvZliBAAnD7rhVgwaM7DE5/d9NMOAJ09SqYqeK4QE= -github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= -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/tklauser/go-sysconf v0.3.13 h1:GBUpcahXSpR2xN01jhkNAbTLRk2Yzgggk8IM08lq3r4= +github.com/tklauser/go-sysconf v0.3.13/go.mod h1:zwleP4Q4OehZHGn4CYZDipCgg9usW5IJePewFCGVEa0= +github.com/tklauser/numcpus v0.7.0 h1:yjuerZP127QG9m5Zh/mSO4wqurYil27tHrqwRoRjpr4= +github.com/tklauser/numcpus v0.7.0/go.mod h1:bb6dMVcj8A42tSE7i32fsIUCbQNllK5iDguyOZRUzAY= github.com/trailofbits/go-fuzz-utils v0.0.0-20210901195358-9657fcfd256c h1:4WU+p200eLYtBsx3M5CKXvkjVdf5SC3W9nMg37y0TFI= github.com/trailofbits/go-fuzz-utils v0.0.0-20210901195358-9657fcfd256c/go.mod h1:f3jBhpWvuZmue0HZK52GzRHJOYHYSILs/c8+K2S/J+o= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10 h1:CQh33pStIp/E30b7TxDlXfM0145bn2e8boI30IxAhTg= github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod h1:x/Pa0FF5Te9kdrlZKJK82YmAkvL8+f989USgz6Jiw7M= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= +github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= +github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI= +github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= go.opentelemetry.io/otel v1.25.0 h1:gldB5FfhRl7OJQbUHt/8s0a7cE8fbsPAtdpRaApKy4k= @@ -480,183 +372,102 @@ go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN8 go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/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-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg= -golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= -golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= +golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/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-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/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-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= +golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 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-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 6e354fbc..512b514c 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -1,4 +1,10 @@ -package mevcommitclient +package mevcommitclientz + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + validatoroptinrouter "github.com/primev/mev-commit/contracts-abi/clients/ValidatorOptInRouter" +) type IMevCommitClient interface { // Need to provide some SLA's around response times here. Should be down to milliseconds with memcache. @@ -8,12 +14,31 @@ type IMevCommitClient interface { } type MevCommitClient struct { - L1Address string // 0x5d4fC7B5Aeea4CF4F0Ca6Be09A2F5AaDAd2F2803 created at 1731009 block - MevCommitAddress string + L1Address string // 0x5d4fC7B5Aeea4CF4F0Ca6Be09A2F5AaDAd2F2803 created at 1731009 block + MevCommitAddress string + validatorOptInRouterCaller *validatoroptinrouter.ValidatoroptinrouterCaller } -func NewMevCommitClient(apiUrl string) IMevCommitClient { - return &MevCommitClient{ - apiUrl: apiUrl, +func NewMevCommitClient(apiUrl string, contractAddress string, client *ethclient.Client) (IMevCommitClient, error) { + + validatorOptInRouter, err := validatoroptinrouter.NewValidatoroptinrouterCaller(common.HexToAddress(contractAddress), client) + if err != nil { + return nil, err } + + return &MevCommitClient{ + validatorOptInRouterCaller: validatorOptInRouter, + }, nil +} + +func (m *MevCommitClient) IsValidatorRegistered(pubkey string) (bool, error) { + return false, nil +} + +func (m *MevCommitClient) IsBuilderRegistered(pubkey string) (bool, error) { + return false, nil +} + +func (m *MevCommitClient) GetRegisteredValidators() ([]string, error) { + return nil, nil } From 274a15e4b7188a15dd6253e60abb4268c3263aa2 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 24 Sep 2024 13:40:35 -0400 Subject: [PATCH 10/70] feat: get's current opted in status of validators via mev-commit client --- mevcommitclient/mev_commit_client.go | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 512b514c..c0f74fa4 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -8,7 +8,7 @@ import ( type IMevCommitClient interface { // Need to provide some SLA's around response times here. Should be down to milliseconds with memcache. - IsValidatorRegistered(pubkey string) (bool, error) + GetOptInStatusForValidators(pubkeys [][]byte) (map[string]bool, error) IsBuilderRegistered(pubkey string) (bool, error) GetRegisteredValidators() ([]string, error) } @@ -31,8 +31,17 @@ func NewMevCommitClient(apiUrl string, contractAddress string, client *ethclient }, nil } -func (m *MevCommitClient) IsValidatorRegistered(pubkey string) (bool, error) { - return false, nil +func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) (map[string]bool, error) { + optedIn, err := m.validatorOptInRouterCaller.AreValidatorsOptedIn(nil, pubkeys) + if err != nil { + return nil, err + } + + pubkeyMap := make(map[string]bool) + for i, pubkey := range pubkeys { + pubkeyMap[string(pubkey)] = optedIn[i] + } + return pubkeyMap, nil } func (m *MevCommitClient) IsBuilderRegistered(pubkey string) (bool, error) { From 7de9955c9fa84dc7bb15b62498e8aaaf675e5f0c Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 25 Sep 2024 10:26:18 -0400 Subject: [PATCH 11/70] feat: adds new table instead of just column --- .../013_add_mev_commit_column_validators.go | 19 ------------------- database/vars/tables.go | 1 + 2 files changed, 1 insertion(+), 19 deletions(-) delete mode 100644 database/migrations/013_add_mev_commit_column_validators.go diff --git a/database/migrations/013_add_mev_commit_column_validators.go b/database/migrations/013_add_mev_commit_column_validators.go deleted file mode 100644 index e8a39b31..00000000 --- a/database/migrations/013_add_mev_commit_column_validators.go +++ /dev/null @@ -1,19 +0,0 @@ -package migrations - -import ( - "github.com/flashbots/mev-boost-relay/database/vars" - migrate "github.com/rubenv/sql-migrate" -) - -var Migration013AddMevCommitColumnValidators = &migrate.Migration{ - Id: "013-add-mev-commit-column-validators", - Up: []string{` - ALTER TABLE ` + vars.TableValidatorRegistration + ` ADD is_mev_commit_opted_in boolean NOT NULL DEFAULT false; - `}, - Down: []string{` - ALTER TABLE ` + vars.TableValidatorRegistration + ` DROP COLUMN is_mev_commit_opted_in; - `}, - - DisableTransactionUp: true, - DisableTransactionDown: true, -} diff --git a/database/vars/tables.go b/database/vars/tables.go index 68e496cf..46d90a6f 100644 --- a/database/vars/tables.go +++ b/database/vars/tables.go @@ -15,4 +15,5 @@ var ( TableBuilderDemotions = tableBase + "_builder_demotions" TableBlockedValidator = tableBase + "_blocked_validator" TableTooLateGetPayload = tableBase + "_too_late_get_payload" + TableMevCommitValidators = tableBase + "_mev_commit_validators" ) From f95c08659e4102a39e22da7c5e4f0db5047b23f5 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 25 Sep 2024 10:26:37 -0400 Subject: [PATCH 12/70] feat: adds the new table migration --- .../013_add_mev_commit_validators_table.go | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 database/migrations/013_add_mev_commit_validators_table.go diff --git a/database/migrations/013_add_mev_commit_validators_table.go b/database/migrations/013_add_mev_commit_validators_table.go new file mode 100644 index 00000000..06571f59 --- /dev/null +++ b/database/migrations/013_add_mev_commit_validators_table.go @@ -0,0 +1,24 @@ +package migrations + +import ( + "github.com/flashbots/mev-boost-relay/database/vars" + migrate "github.com/rubenv/sql-migrate" +) + +var Migration013AddMevCommitValidatorsTable = &migrate.Migration{ + Id: "013-add-mev-commit-validators-table", + Up: []string{` + CREATE TABLE IF NOT EXISTS ` + vars.TableMevCommitValidators + ` ( + id SERIAL PRIMARY KEY, + bls_key VARCHAR(98) NOT NULL, + is_opted_in BOOLEAN NOT NULL DEFAULT false, + timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP + ); + `}, + Down: []string{` + DROP TABLE mev_commit_validator_registration; + `}, + + DisableTransactionUp: true, + DisableTransactionDown: true, +} From fa672e038e70fb4e5d544aa85fbcc6134e466437 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 25 Sep 2024 10:35:34 -0400 Subject: [PATCH 13/70] feat: adds db entries for validators --- .gitignore | 3 ++- database/database.go | 22 ++++++++++++++++++- .../013_add_mev_commit_validators_table.go | 2 +- database/types.go | 7 ++++++ 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 68f41fa9..a405d827 100644 --- a/.gitignore +++ b/.gitignore @@ -24,4 +24,5 @@ .DS_Store /website-index.html /README.internal.md -/internal/_investigations/ \ No newline at end of file +/internal/_investigations/ +vendor* \ No newline at end of file diff --git a/database/database.go b/database/database.go index 1df6a3dd..65587d46 100644 --- a/database/database.go +++ b/database/database.go @@ -26,7 +26,8 @@ type IDatabaseService interface { GetLatestValidatorRegistrations(timestampOnly bool) ([]*ValidatorRegistrationEntry, error) GetValidatorRegistration(pubkey string) (*ValidatorRegistrationEntry, error) GetValidatorRegistrationsForPubkeys(pubkeys []string) ([]*ValidatorRegistrationEntry, error) - + GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) + SaveMevCommitValidatorRegistration(entry MevCommitValidatorEntry) error SaveBuilderBlockSubmission(payload *common.VersionedSubmitBlockRequest, requestError, validationError error, receivedAt, eligibleAt time.Time, wasSimulated, saveExecPayload bool, profile common.Profile, optimisticSubmission bool, blockValue *uint256.Int) (entry *BuilderBlockSubmissionEntry, err error) GetBlockSubmissionEntry(slot uint64, proposerPubkey, blockHash string) (entry *BuilderBlockSubmissionEntry, err error) GetBuilderSubmissions(filters GetBuilderSubmissionsFilters) ([]*BuilderBlockSubmissionEntry, error) @@ -140,6 +141,15 @@ func (s *DatabaseService) SaveValidatorRegistration(entry ValidatorRegistrationE return err } +func (s *DatabaseService) SaveMevCommitValidatorRegistration(entry MevCommitValidatorEntry) error { + // On conflict, set the correct opted in status + query := `INSERT INTO ` + vars.TableMevCommitValidators + ` (pubkey, is_opted_in, timestamp) + VALUES (:pubkey, :is_opted_in, :timestamp) + ON CONFLICT (pubkey) DO UPDATE SET is_opted_in = EXCLUDED.is_opted_in, timestamp = EXCLUDED.timestamp;` + _, err := s.DB.NamedExec(query, entry) + return err +} + func (s *DatabaseService) GetValidatorRegistration(pubkey string) (*ValidatorRegistrationEntry, error) { query := `SELECT DISTINCT ON (pubkey) pubkey, fee_recipient, timestamp, gas_limit, signature FROM ` + vars.TableValidatorRegistration + ` @@ -150,6 +160,16 @@ func (s *DatabaseService) GetValidatorRegistration(pubkey string) (*ValidatorReg return entry, err } +func (s *DatabaseService) GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) { + query := `SELECT DISTINCT ON (pubkey) pubkey, is_opted_in, timestamp + FROM ` + vars.TableMevCommitValidators + ` + WHERE pubkey=$1 + ORDER BY pubkey, timestamp DESC;` + entry := &MevCommitValidatorEntry{} + err := s.DB.Get(entry, query, pubkey) + return entry, err +} + func (s *DatabaseService) GetValidatorRegistrationsForPubkeys(pubkeys []string) (entries []*ValidatorRegistrationEntry, err error) { query := `SELECT DISTINCT ON (pubkey) pubkey, fee_recipient, timestamp, gas_limit, signature FROM ` + vars.TableValidatorRegistration + ` diff --git a/database/migrations/013_add_mev_commit_validators_table.go b/database/migrations/013_add_mev_commit_validators_table.go index 06571f59..56964510 100644 --- a/database/migrations/013_add_mev_commit_validators_table.go +++ b/database/migrations/013_add_mev_commit_validators_table.go @@ -10,7 +10,7 @@ var Migration013AddMevCommitValidatorsTable = &migrate.Migration{ Up: []string{` CREATE TABLE IF NOT EXISTS ` + vars.TableMevCommitValidators + ` ( id SERIAL PRIMARY KEY, - bls_key VARCHAR(98) NOT NULL, + pubkey VARCHAR(98) NOT NULL, is_opted_in BOOLEAN NOT NULL DEFAULT false, timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); diff --git a/database/types.go b/database/types.go index 25470141..f4a6b6bc 100644 --- a/database/types.go +++ b/database/types.go @@ -62,6 +62,13 @@ type ValidatorRegistrationEntry struct { Signature string `db:"signature"` } +type MevCommitValidatorEntry struct { + ID int64 `db:"id"` + Pubkey string `db:"pubkey"` + IsOptedIn bool `db:"is_opted_in"` + Timestamp time.Time `db:"timestamp"` +} + func (reg ValidatorRegistrationEntry) ToSignedValidatorRegistration() (*builderApiV1.SignedValidatorRegistration, error) { pubkey, err := utils.HexToPubkey(reg.Pubkey) if err != nil { From bd03f6f0c6232f16b534f3db61e2975a0febb704 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 25 Sep 2024 12:32:58 -0400 Subject: [PATCH 14/70] feat: updates format of validator registration --- database/database.go | 58 ++++++++++++++++--- .../013_add_mev_commit_validators_table.go | 1 - database/types.go | 1 - 3 files changed, 49 insertions(+), 11 deletions(-) diff --git a/database/database.go b/database/database.go index 65587d46..60af6465 100644 --- a/database/database.go +++ b/database/database.go @@ -5,6 +5,7 @@ import ( "context" "database/sql" "encoding/json" + "errors" "fmt" "os" "strings" @@ -26,8 +27,10 @@ type IDatabaseService interface { GetLatestValidatorRegistrations(timestampOnly bool) ([]*ValidatorRegistrationEntry, error) GetValidatorRegistration(pubkey string) (*ValidatorRegistrationEntry, error) GetValidatorRegistrationsForPubkeys(pubkeys []string) ([]*ValidatorRegistrationEntry, error) - GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) - SaveMevCommitValidatorRegistration(entry MevCommitValidatorEntry) error + IsMevCommitValidatorRegistered(pubkey string) (bool, error) + StoreMevCommitValidatorRegistration(pubkey string) error + RemoveMevCommitValidatorRegistration(pubkey string) error + SaveBuilderBlockSubmission(payload *common.VersionedSubmitBlockRequest, requestError, validationError error, receivedAt, eligibleAt time.Time, wasSimulated, saveExecPayload bool, profile common.Profile, optimisticSubmission bool, blockValue *uint256.Int) (entry *BuilderBlockSubmissionEntry, err error) GetBlockSubmissionEntry(slot uint64, proposerPubkey, blockHash string) (entry *BuilderBlockSubmissionEntry, err error) GetBuilderSubmissions(filters GetBuilderSubmissionsFilters) ([]*BuilderBlockSubmissionEntry, error) @@ -160,14 +163,51 @@ func (s *DatabaseService) GetValidatorRegistration(pubkey string) (*ValidatorReg return entry, err } +var ErrValidatorNotFound = errors.New("validator not found") + +func (s *DatabaseService) IsMevCommitValidatorRegistered(pubkey string) (bool, error) { + query := `SELECT EXISTS(SELECT 1 FROM ` + vars.TableMevCommitValidators + ` WHERE pubkey=$1)` + var exists bool + err := s.DB.Get(&exists, query, pubkey) + if err != nil { + return false, err + } + return exists, nil +} + +func (s *DatabaseService) RegisterMevCommitValidator(pubkey string) error { + query := `INSERT INTO ` + vars.TableMevCommitValidators + ` (pubkey, timestamp) VALUES ($1, NOW())` + _, err := s.DB.Exec(query, pubkey) + return err +} + +func (s *DatabaseService) UnregisterMevCommitValidator(pubkey string) error { + query := `DELETE FROM ` + vars.TableMevCommitValidators + ` WHERE pubkey=$1` + result, err := s.DB.Exec(query, pubkey) + if err != nil { + return err + } + rowsAffected, err := result.RowsAffected() + if err != nil { + return err + } + if rowsAffected == 0 { + return ErrValidatorNotFound + } + return nil +} + func (s *DatabaseService) GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) { - query := `SELECT DISTINCT ON (pubkey) pubkey, is_opted_in, timestamp - FROM ` + vars.TableMevCommitValidators + ` - WHERE pubkey=$1 - ORDER BY pubkey, timestamp DESC;` - entry := &MevCommitValidatorEntry{} - err := s.DB.Get(entry, query, pubkey) - return entry, err + query := `SELECT pubkey, timestamp FROM ` + vars.TableMevCommitValidators + ` WHERE pubkey=$1` + var entry MevCommitValidatorEntry + err := s.DB.Get(&entry, query, pubkey) + if err == sql.ErrNoRows { + return nil, ErrValidatorNotFound + } + if err != nil { + return nil, err + } + return &entry, nil } func (s *DatabaseService) GetValidatorRegistrationsForPubkeys(pubkeys []string) (entries []*ValidatorRegistrationEntry, err error) { diff --git a/database/migrations/013_add_mev_commit_validators_table.go b/database/migrations/013_add_mev_commit_validators_table.go index 56964510..9a01e12d 100644 --- a/database/migrations/013_add_mev_commit_validators_table.go +++ b/database/migrations/013_add_mev_commit_validators_table.go @@ -11,7 +11,6 @@ var Migration013AddMevCommitValidatorsTable = &migrate.Migration{ CREATE TABLE IF NOT EXISTS ` + vars.TableMevCommitValidators + ` ( id SERIAL PRIMARY KEY, pubkey VARCHAR(98) NOT NULL, - is_opted_in BOOLEAN NOT NULL DEFAULT false, timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); `}, diff --git a/database/types.go b/database/types.go index f4a6b6bc..5eda345c 100644 --- a/database/types.go +++ b/database/types.go @@ -65,7 +65,6 @@ type ValidatorRegistrationEntry struct { type MevCommitValidatorEntry struct { ID int64 `db:"id"` Pubkey string `db:"pubkey"` - IsOptedIn bool `db:"is_opted_in"` Timestamp time.Time `db:"timestamp"` } From 54ea6de9982e4c6a71fdc525987c672d0faa3b41 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 25 Sep 2024 16:30:02 -0400 Subject: [PATCH 15/70] feat: adds a redis handlers for validator registration --- datastore/redis.go | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/datastore/redis.go b/datastore/redis.go index 02b307f8..26606322 100644 --- a/datastore/redis.go +++ b/datastore/redis.go @@ -24,7 +24,8 @@ var ( redisScheme = "redis://" redisPrefix = "boost-relay" - expiryBidCache = 45 * time.Second + mevCommitValidatorRegistrationExpiry = 1 * time.Hour + expiryBidCache = 45 * time.Second RedisConfigFieldPubkey = "pubkey" RedisStatsFieldLatestSlot = "latest-slot" @@ -94,7 +95,8 @@ type RedisCache struct { prefixFloorBidValue string // keys - keyValidatorRegistrationTimestamp string + keyValidatorRegistrationTimestamp string + keyMevCommitValidatorRegistrationHash string keyRelayConfig string keyStats string @@ -134,8 +136,9 @@ func NewRedisCache(prefix, redisURI, readonlyURI string) (*RedisCache, error) { prefixFloorBid: fmt.Sprintf("%s/%s:bid-floor", redisPrefix, prefix), // prefix:slot_parentHash_proposerPubkey prefixFloorBidValue: fmt.Sprintf("%s/%s:bid-floor-value", redisPrefix, prefix), // prefix:slot_parentHash_proposerPubkey - keyValidatorRegistrationTimestamp: fmt.Sprintf("%s/%s:validator-registration-timestamp", redisPrefix, prefix), - keyRelayConfig: fmt.Sprintf("%s/%s:relay-config", redisPrefix, prefix), + keyValidatorRegistrationTimestamp: fmt.Sprintf("%s/%s:validator-registration-timestamp", redisPrefix, prefix), + keyMevCommitValidatorRegistrationHash: fmt.Sprintf("%s/%s:mev-commit-validator-registration", redisPrefix, prefix), + keyRelayConfig: fmt.Sprintf("%s/%s:relay-config", redisPrefix, prefix), keyStats: fmt.Sprintf("%s/%s:stats", redisPrefix, prefix), keyProposerDuties: fmt.Sprintf("%s/%s:proposer-duties", redisPrefix, prefix), @@ -241,6 +244,36 @@ func (r *RedisCache) GetValidatorRegistrationTimestamp(proposerPubkey common.Pub return timestamp, err } +// Add these methods to the existing RedisCache struct + +func (r *RedisCache) SetMevCommitValidatorRegistration(pubkey string) error { + err := r.client.Set(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+pubkey, "1", mevCommitValidatorRegistrationExpiry).Err() + if err != nil { + return fmt.Errorf("failed to add validator to MEV-Commit registration: %w", err) + } + return nil +} + +func (r *RedisCache) IsMevCommitValidatorRegistered(pubkey string) (bool, error) { + _, err := r.client.Get(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+pubkey).Result() + if err == redis.Nil { + return false, nil + } + if err != nil { + return false, fmt.Errorf("failed to check MEV-Commit validator registration: %w", err) + } + + return true, nil +} + +func (r *RedisCache) DeleteMevCommitValidatorRegistration(pubkey string) error { + err := r.client.Del(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+pubkey).Err() + if err != nil { + return fmt.Errorf("failed to remove validator from MEV-Commit registration: %w", err) + } + return nil +} + func (r *RedisCache) SetValidatorRegistrationTimestampIfNewer(proposerPubkey common.PubkeyHex, timestamp uint64) error { knownTimestamp, err := r.GetValidatorRegistrationTimestamp(proposerPubkey) if err != nil { From 9f236de6cd16c4cc05420d4dae7daf26c9454751 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Thu, 26 Sep 2024 11:30:24 -0400 Subject: [PATCH 16/70] feat: wip move most data to redis for validators --- datastore/datastore.go | 14 +++++++++++ datastore/redis.go | 12 ++++----- mevcommitclient/mev_commit_client.go | 12 +++------ services/api/service.go | 5 ++-- services/housekeeper/housekeeper.go | 37 +++++++++++++++++++++++----- 5 files changed, 58 insertions(+), 22 deletions(-) diff --git a/datastore/datastore.go b/datastore/datastore.go index 3dc7be13..bb235c93 100644 --- a/datastore/datastore.go +++ b/datastore/datastore.go @@ -184,6 +184,20 @@ func (ds *Datastore) SetKnownValidator(pubkeyHex common.PubkeyHex, index uint64) ds.knownValidatorsByIndex[index] = pubkeyHex } +// SaveMevCommitValidatorRegistration saves a validator registration for MEV-Commit into Redis +func (ds *Datastore) SaveMevCommitValidatorRegistration(pubkeyHex common.PubkeyHex) error { + err := ds.redis.SetMevCommitValidatorRegistration(pubkeyHex) + if err != nil { + return errors.Wrap(err, "failed saving MEV-Commit validator registration to redis") + } + return nil +} + +// IsMevCommitRegisteredValidator checks if a validator is registered for MEV-Commit +func (ds *Datastore) IsMevCommitValidatorRegistered(pubkeyHex common.PubkeyHex) (bool, error) { + return ds.redis.IsMevCommitValidatorRegistered(pubkeyHex) +} + // SaveValidatorRegistration saves a validator registration into both Redis and the database func (ds *Datastore) SaveValidatorRegistration(entry builderApiV1.SignedValidatorRegistration) error { // First save in the database diff --git a/datastore/redis.go b/datastore/redis.go index 26606322..1f316a6a 100644 --- a/datastore/redis.go +++ b/datastore/redis.go @@ -246,16 +246,16 @@ func (r *RedisCache) GetValidatorRegistrationTimestamp(proposerPubkey common.Pub // Add these methods to the existing RedisCache struct -func (r *RedisCache) SetMevCommitValidatorRegistration(pubkey string) error { - err := r.client.Set(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+pubkey, "1", mevCommitValidatorRegistrationExpiry).Err() +func (r *RedisCache) SetMevCommitValidatorRegistration(proposerPubkey common.PubkeyHex) error { + err := r.client.Set(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+proposerPubkey.String(), "1", mevCommitValidatorRegistrationExpiry).Err() if err != nil { return fmt.Errorf("failed to add validator to MEV-Commit registration: %w", err) } return nil } -func (r *RedisCache) IsMevCommitValidatorRegistered(pubkey string) (bool, error) { - _, err := r.client.Get(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+pubkey).Result() +func (r *RedisCache) IsMevCommitValidatorRegistered(proposerPubkey common.PubkeyHex) (bool, error) { + _, err := r.client.Get(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+proposerPubkey.String()).Result() if err == redis.Nil { return false, nil } @@ -266,8 +266,8 @@ func (r *RedisCache) IsMevCommitValidatorRegistered(pubkey string) (bool, error) return true, nil } -func (r *RedisCache) DeleteMevCommitValidatorRegistration(pubkey string) error { - err := r.client.Del(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+pubkey).Err() +func (r *RedisCache) DeleteMevCommitValidatorRegistration(proposerPubkey common.PubkeyHex) error { + err := r.client.Del(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+proposerPubkey.String()).Err() if err != nil { return fmt.Errorf("failed to remove validator from MEV-Commit registration: %w", err) } diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index c0f74fa4..92b93cf4 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -1,4 +1,4 @@ -package mevcommitclientz +package mevcommitclient import ( "github.com/ethereum/go-ethereum/common" @@ -8,7 +8,7 @@ import ( type IMevCommitClient interface { // Need to provide some SLA's around response times here. Should be down to milliseconds with memcache. - GetOptInStatusForValidators(pubkeys [][]byte) (map[string]bool, error) + GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) IsBuilderRegistered(pubkey string) (bool, error) GetRegisteredValidators() ([]string, error) } @@ -31,17 +31,13 @@ func NewMevCommitClient(apiUrl string, contractAddress string, client *ethclient }, nil } -func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) (map[string]bool, error) { +func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) { optedIn, err := m.validatorOptInRouterCaller.AreValidatorsOptedIn(nil, pubkeys) if err != nil { return nil, err } - pubkeyMap := make(map[string]bool) - for i, pubkey := range pubkeys { - pubkeyMap[string(pubkey)] = optedIn[i] - } - return pubkeyMap, nil + return optedIn, nil } func (m *MevCommitClient) IsBuilderRegistered(pubkey string) (bool, error) { diff --git a/services/api/service.go b/services/api/service.go index d2f5ab49..823b71c4 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1748,8 +1748,9 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr api.RespondError(w, http.StatusBadRequest, "no duty found for submission slot") return false } + // Check if validator is registered - isValidatorRegistered, err := api.mevCommitClient.IsValidatorRegistered(duty.Entry.Message.Pubkey.String()) + isValidatorRegistered, err := api.datastore.IsMevCommitValidatorRegistered(common.NewPubkeyHex(duty.Entry.Message.Pubkey.String())) if err != nil { log.WithError(err).Error("Failed to check validator registration") api.RespondError(w, http.StatusInternalServerError, "Internal server error") @@ -1757,7 +1758,7 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr } if isValidatorRegistered { - // Check if builder is registered + // Check if builder is registered TODO(@ckartik): Move this to datastore isBuilderRegistered, err := api.mevCommitClient.IsBuilderRegistered(submission.BidTrace.BuilderPubkey.String()) if err != nil { log.WithError(err).Error("Failed to check builder registration") diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index 357fcc72..879ab135 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -145,7 +145,7 @@ func (hk *Housekeeper) processNewSlot(headSlot uint64) { // Update proposer duties go hk.updateProposerDuties(headSlot) - go hk.updatemevcommitvalidatorregistrations(headSlot) + go hk.updateMevCommitValidatorRegistrations(headSlot) // Set headSlot in redis (for the website) err := hk.redis.SetStats(datastore.RedisStatsFieldLatestSlot, headSlot) @@ -252,19 +252,44 @@ func (hk *Housekeeper) UpdateProposerDutiesWithoutChecks(headSlot uint64) { log.WithField("numDuties", len(_duties)).Infof("proposer duties updated: %s", strings.Join(_duties, ", ")) } +// When the update is triggered, we store registered validators in Redis for an the current and next epoch. +// This allows us to maintain 1 epoch in advance, which is enough to check if a validator is registered for a given epoch. func (hk *Housekeeper) updateMevCommitValidatorRegistrations(headSlot uint64) { - registeredValidators, err := hk.mevCommitClient.GetRegisteredValidators() + // Only update once per epoch - at the epoch start of the epoch + if headSlot%common.SlotsPerEpoch == 0 { + return + } + + epoch := headSlot / common.SlotsPerEpoch + + duties, err := hk.beaconClient.GetProposerDuties(epoch) if err != nil { - hk.log.WithError(err).Error("failed to get registered validators from MEV-Commit client") + hk.log.WithError(err).Error("failed to get proposer duties for epoch") + return + } + nextDuties, err := hk.beaconClient.GetProposerDuties(epoch + 1) + if err != nil { + hk.log.WithError(err).Error("failed to get proposer duties for next epoch") return } + // Combine duties from current and next epoch into a single array + duties.Data = append(duties.Data, nextDuties.Data...) + + pubkeys := [][]byte{} + for _, duty := range duties.Data { + pubkeys = append(pubkeys, []byte(duty.Pubkey)) + } - // Store the registered validators in Redis - err = hk.redis.SetMevCommitRegisteredValidators(registeredValidators) + registeredValidators, err := hk.mevCommitClient.GetOptInStatusForValidators(pubkeys) if err != nil { - hk.log.WithError(err).Error("failed to store MEV-Commit registered validators in Redis") + hk.log.WithError(err).Error("failed to get registered validators from MEV-Commit client") return } + for i, registeredValidator := range registeredValidators { + if registeredValidator { + hk.redis.SetMevCommitValidatorRegistration(common.NewPubkeyHex(duties.Data[i].Pubkey)) + } + } hk.log.WithField("numValidators", len(registeredValidators)).Info("updated MEV-Commit registered validators in Redis") } From d1d8e5fe99108c29d7a6d8e907eec586d8737517 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Fri, 27 Sep 2024 15:31:44 -0400 Subject: [PATCH 17/70] feat: completes implementation of mevcommit client --- mevcommitclient/mev_commit_client.go | 124 ++++++++++++++++++++++++--- 1 file changed, 110 insertions(+), 14 deletions(-) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 92b93cf4..0c606d3f 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -1,49 +1,145 @@ package mevcommitclient import ( + "context" + "fmt" + "math/big" + "strings" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" + builderRegistry "github.com/primev/mev-commit/contracts-abi/clients/ProviderRegistry" validatoroptinrouter "github.com/primev/mev-commit/contracts-abi/clients/ValidatorOptInRouter" ) +type BuilderRegisteredEvent struct { + Builder common.Address + Value *big.Int + BlsPublicKey []byte + BlockNumber uint64 + TxHash common.Hash + Timestamp time.Time + IsValid bool +} + type IMevCommitClient interface { - // Need to provide some SLA's around response times here. Should be down to milliseconds with memcache. GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) - IsBuilderRegistered(pubkey string) (bool, error) - GetRegisteredValidators() ([]string, error) + GetActiveBuilders() ([]common.Address, error) } type MevCommitClient struct { - L1Address string // 0x5d4fC7B5Aeea4CF4F0Ca6Be09A2F5AaDAd2F2803 created at 1731009 block + L1Address string MevCommitAddress string + ValidatorRouterAddress common.Address + BuilderRegistryAddress common.Address validatorOptInRouterCaller *validatoroptinrouter.ValidatoroptinrouterCaller + builderRegistryCaller *builderRegistry.ProviderregistryCaller + l1Client *ethclient.Client + mevCommitClient *ethclient.Client + contractAbi abi.ABI } -func NewMevCommitClient(apiUrl string, contractAddress string, client *ethclient.Client) (IMevCommitClient, error) { +const ( + abiJSON = `[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"builder","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"blsPublicKey","type":"bytes"}],"name":"BuilderRegistered","type":"event"},{"inputs":[{"internalType":"address","name":"builder","type":"address"}],"name":"isBuilderValid","outputs":[],"stateMutability":"view","type":"function"}]` +) + +func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddress, builderRegistryAddress common.Address) (IMevCommitClient, error) { + l1Client, err := ethclient.Dial(l1MainnetUrl) + if err != nil { + return nil, fmt.Errorf("failed to connect to L1 Mainnet: %w", err) + } + + mevCommitClient, err := ethclient.Dial(mevCommitUrl) + if err != nil { + return nil, fmt.Errorf("failed to connect to MEV-Commit EVM: %w", err) + } + + validatorOptInRouter, err := validatoroptinrouter.NewValidatoroptinrouterCaller(validatorRouterAddress, l1Client) + if err != nil { + return nil, fmt.Errorf("failed to create ValidatorOptInRouter caller: %w", err) + } + + builderRegistryCaller, err := builderRegistry.NewProviderregistryCaller(builderRegistryAddress, mevCommitClient) + if err != nil { + return nil, fmt.Errorf("failed to create BuilderRegistry caller: %w", err) + } - validatorOptInRouter, err := validatoroptinrouter.NewValidatoroptinrouterCaller(common.HexToAddress(contractAddress), client) + contractAbi, err := abi.JSON(strings.NewReader(abiJSON)) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to parse contract ABI: %w", err) } return &MevCommitClient{ + L1Address: l1MainnetUrl, + MevCommitAddress: mevCommitUrl, + ValidatorRouterAddress: validatorRouterAddress, + BuilderRegistryAddress: builderRegistryAddress, validatorOptInRouterCaller: validatorOptInRouter, + builderRegistryCaller: builderRegistryCaller, + l1Client: l1Client, + mevCommitClient: mevCommitClient, + contractAbi: contractAbi, }, nil } func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) { - optedIn, err := m.validatorOptInRouterCaller.AreValidatorsOptedIn(nil, pubkeys) + return m.validatorOptInRouterCaller.AreValidatorsOptedIn(nil, pubkeys) +} +func (m *MevCommitClient) GetActiveBuilders() ([]common.Address, error) { + latestBlock, err := m.mevCommitClient.BlockNumber(context.Background()) + if err != nil { + return nil, fmt.Errorf("failed to get latest block number: %w", err) + } + + query := ethereum.FilterQuery{ + FromBlock: big.NewInt(0), + ToBlock: big.NewInt(int64(latestBlock)), + Addresses: []common.Address{m.BuilderRegistryAddress}, + Topics: [][]common.Hash{{m.contractAbi.Events["BuilderRegistered"].ID}}, + } + + logs, err := m.mevCommitClient.FilterLogs(context.Background(), query) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to filter logs: %w", err) + } + + activeBuilders := make([]common.Address, 0) + for _, vLog := range logs { + builderAddress := common.HexToAddress(vLog.Topics[1].Hex()) + if m.isBuilderValid(builderAddress) { + activeBuilders = append(activeBuilders, builderAddress) + } } - return optedIn, nil + return activeBuilders, nil } -func (m *MevCommitClient) IsBuilderRegistered(pubkey string) (bool, error) { - return false, nil +func (m *MevCommitClient) parseBuilderRegisteredEvent(vLog types.Log) (BuilderRegisteredEvent, error) { + var event BuilderRegisteredEvent + err := m.contractAbi.UnpackIntoInterface(&event, "BuilderRegistered", vLog.Data) + if err != nil { + return event, err + } + event.Builder = common.HexToAddress(vLog.Topics[1].Hex()) + event.BlockNumber = vLog.BlockNumber + event.TxHash = vLog.TxHash + + block, err := m.mevCommitClient.BlockByNumber(context.Background(), big.NewInt(int64(vLog.BlockNumber))) + if err != nil { + return event, fmt.Errorf("failed to fetch block %d: %w", vLog.BlockNumber, err) + } + + event.Timestamp = time.Unix(int64(block.Time()), 0) + event.IsValid = m.isBuilderValid(event.Builder) + + return event, nil } -func (m *MevCommitClient) GetRegisteredValidators() ([]string, error) { - return nil, nil +func (m *MevCommitClient) isBuilderValid(builderAddress common.Address) bool { + err := m.builderRegistryCaller.IsProviderValid(nil, builderAddress) + return err == nil } From 26d30474aa30cb7878c68c60548bec83108818bc Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Fri, 27 Sep 2024 15:51:35 -0400 Subject: [PATCH 18/70] feat: use the provider registry client --- mevcommitclient/mev_commit_client.go | 74 +++++++++++++--------------- 1 file changed, 33 insertions(+), 41 deletions(-) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 0c606d3f..89bb1f47 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -1,16 +1,14 @@ package mevcommitclient import ( - "context" "fmt" "math/big" "strings" "time" - "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" builderRegistry "github.com/primev/mev-commit/contracts-abi/clients/ProviderRegistry" validatoroptinrouter "github.com/primev/mev-commit/contracts-abi/clients/ValidatorOptInRouter" @@ -38,6 +36,7 @@ type MevCommitClient struct { BuilderRegistryAddress common.Address validatorOptInRouterCaller *validatoroptinrouter.ValidatoroptinrouterCaller builderRegistryCaller *builderRegistry.ProviderregistryCaller + builderRegistryFilterer *builderRegistry.ProviderregistryFilterer l1Client *ethclient.Client mevCommitClient *ethclient.Client contractAbi abi.ABI @@ -68,6 +67,11 @@ func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddres return nil, fmt.Errorf("failed to create BuilderRegistry caller: %w", err) } + builderRegistryFilterer, err := builderRegistry.NewProviderregistryFilterer(builderRegistryAddress, mevCommitClient) + if err != nil { + return nil, fmt.Errorf("failed to create BuilderRegistry filterer: %w", err) + } + contractAbi, err := abi.JSON(strings.NewReader(abiJSON)) if err != nil { return nil, fmt.Errorf("failed to parse contract ABI: %w", err) @@ -80,6 +84,7 @@ func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddres BuilderRegistryAddress: builderRegistryAddress, validatorOptInRouterCaller: validatorOptInRouter, builderRegistryCaller: builderRegistryCaller, + builderRegistryFilterer: builderRegistryFilterer, l1Client: l1Client, mevCommitClient: mevCommitClient, contractAbi: contractAbi, @@ -89,57 +94,44 @@ func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddres func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) { return m.validatorOptInRouterCaller.AreValidatorsOptedIn(nil, pubkeys) } -func (m *MevCommitClient) GetActiveBuilders() ([]common.Address, error) { - latestBlock, err := m.mevCommitClient.BlockNumber(context.Background()) - if err != nil { - return nil, fmt.Errorf("failed to get latest block number: %w", err) - } - query := ethereum.FilterQuery{ - FromBlock: big.NewInt(0), - ToBlock: big.NewInt(int64(latestBlock)), - Addresses: []common.Address{m.BuilderRegistryAddress}, - Topics: [][]common.Hash{{m.contractAbi.Events["BuilderRegistered"].ID}}, +func (m *MevCommitClient) GetActiveBuilders() ([]common.Address, error) { + opts := &bind.FilterOpts{ + Start: 0, + End: nil, // Latest block } - logs, err := m.mevCommitClient.FilterLogs(context.Background(), query) + iterator, err := m.builderRegistryFilterer.FilterProviderRegistered(opts, nil) if err != nil { - return nil, fmt.Errorf("failed to filter logs: %w", err) + return nil, fmt.Errorf("failed to filter ProviderRegistered events: %w", err) } + defer iterator.Close() activeBuilders := make([]common.Address, 0) - for _, vLog := range logs { - builderAddress := common.HexToAddress(vLog.Topics[1].Hex()) - if m.isBuilderValid(builderAddress) { - activeBuilders = append(activeBuilders, builderAddress) + for iterator.Next() { + isValid, err := m.isBuilderValid(iterator.Event.Provider) + if err != nil { + return nil, fmt.Errorf("failed to check if builder is valid: %w", err) + } + if isValid { + activeBuilders = append(activeBuilders, iterator.Event.Provider) } } - return activeBuilders, nil -} - -func (m *MevCommitClient) parseBuilderRegisteredEvent(vLog types.Log) (BuilderRegisteredEvent, error) { - var event BuilderRegisteredEvent - err := m.contractAbi.UnpackIntoInterface(&event, "BuilderRegistered", vLog.Data) - if err != nil { - return event, err - } - event.Builder = common.HexToAddress(vLog.Topics[1].Hex()) - event.BlockNumber = vLog.BlockNumber - event.TxHash = vLog.TxHash - - block, err := m.mevCommitClient.BlockByNumber(context.Background(), big.NewInt(int64(vLog.BlockNumber))) - if err != nil { - return event, fmt.Errorf("failed to fetch block %d: %w", vLog.BlockNumber, err) + if err := iterator.Error(); err != nil { + return nil, fmt.Errorf("error iterating over ProviderRegistered events: %w", err) } - event.Timestamp = time.Unix(int64(block.Time()), 0) - event.IsValid = m.isBuilderValid(event.Builder) - - return event, nil + return activeBuilders, nil } -func (m *MevCommitClient) isBuilderValid(builderAddress common.Address) bool { +func (m *MevCommitClient) isBuilderValid(builderAddress common.Address) (bool, error) { err := m.builderRegistryCaller.IsProviderValid(nil, builderAddress) - return err == nil + if err != nil { + if err.Error() == "execution reverted" { + return false, nil + } + return false, fmt.Errorf("error checking if builder is valid: %w", err) + } + return true, nil } From ed193abaac67d551d3226e3f315676d9223e9ad9 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 30 Sep 2024 11:01:16 -0400 Subject: [PATCH 19/70] feat: wip adds all the e2e calls to complete implementation for relay changes --- datastore/datastore.go | 5 +++ datastore/redis.go | 54 +++++++++++++++++++++++++++- mevcommitclient/mev_commit_client.go | 11 +++--- services/api/service.go | 6 ++-- services/housekeeper/housekeeper.go | 18 ++++++++++ 5 files changed, 85 insertions(+), 9 deletions(-) diff --git a/datastore/datastore.go b/datastore/datastore.go index bb235c93..c2853a53 100644 --- a/datastore/datastore.go +++ b/datastore/datastore.go @@ -198,6 +198,11 @@ func (ds *Datastore) IsMevCommitValidatorRegistered(pubkeyHex common.PubkeyHex) return ds.redis.IsMevCommitValidatorRegistered(pubkeyHex) } +// IsMevCommitBlockBuilder checks if a builder is registered for MEV-Commit +func (ds *Datastore) IsMevCommitBlockBuilder(builderPubkey common.PubkeyHex) (bool, error) { + return ds.redis.IsMevCommitBlockBuilder(builderPubkey) +} + // SaveValidatorRegistration saves a validator registration into both Redis and the database func (ds *Datastore) SaveValidatorRegistration(entry builderApiV1.SignedValidatorRegistration) error { // First save in the database diff --git a/datastore/redis.go b/datastore/redis.go index 1f316a6a..b0a091c1 100644 --- a/datastore/redis.go +++ b/datastore/redis.go @@ -2,6 +2,7 @@ package datastore import ( "context" + "encoding/hex" "encoding/json" "errors" "fmt" @@ -97,6 +98,7 @@ type RedisCache struct { // keys keyValidatorRegistrationTimestamp string keyMevCommitValidatorRegistrationHash string + keyMevCommitBlockBuilder string // New key for MEV-Commit block builder array keyRelayConfig string keyStats string @@ -138,6 +140,7 @@ func NewRedisCache(prefix, redisURI, readonlyURI string) (*RedisCache, error) { keyValidatorRegistrationTimestamp: fmt.Sprintf("%s/%s:validator-registration-timestamp", redisPrefix, prefix), keyMevCommitValidatorRegistrationHash: fmt.Sprintf("%s/%s:mev-commit-validator-registration", redisPrefix, prefix), + keyMevCommitBlockBuilder: fmt.Sprintf("%s/%s:mev-commit-block-builder", redisPrefix, prefix), // New key for MEV-Commit block builder array keyRelayConfig: fmt.Sprintf("%s/%s:relay-config", redisPrefix, prefix), keyStats: fmt.Sprintf("%s/%s:stats", redisPrefix, prefix), @@ -244,7 +247,56 @@ func (r *RedisCache) GetValidatorRegistrationTimestamp(proposerPubkey common.Pub return timestamp, err } -// Add these methods to the existing RedisCache struct +func (r *RedisCache) SetMevCommitBlockBuilders(builders [][]byte) error { + ctx := context.Background() + pipe := r.client.Pipeline() + + // Clear existing set + pipe.Del(ctx, r.keyMevCommitBlockBuilder) + + // Add all builders to the set + for _, builder := range builders { + pipe.SAdd(ctx, r.keyMevCommitBlockBuilder, hex.EncodeToString(builder)) + } + + // Execute pipeline + _, err := pipe.Exec(ctx) + if err != nil { + return fmt.Errorf("failed to set MEV-Commit block builders: %w", err) + } + + return nil +} + +func (r *RedisCache) GetMevCommitBlockBuilders() ([]common.PubkeyHex, error) { + ctx := context.Background() + + // Retrieve all members of the set + members, err := r.client.SMembers(ctx, r.keyMevCommitBlockBuilder).Result() + if err != nil { + return nil, fmt.Errorf("failed to get MEV-Commit block builders: %w", err) + } + + // Convert string slice to PubkeyHex slice + builders := make([]common.PubkeyHex, len(members)) + for i, member := range members { + builders[i] = common.PubkeyHex(member) + } + + return builders, nil +} + +func (r *RedisCache) IsMevCommitBlockBuilder(builderPubkey common.PubkeyHex) (bool, error) { + ctx := context.Background() + + // Check if the builder pubkey exists in the set + exists, err := r.client.SIsMember(ctx, r.keyMevCommitBlockBuilder, builderPubkey.String()).Result() + if err != nil { + return false, fmt.Errorf("failed to check if builder is in MEV-Commit block builders set: %w", err) + } + + return exists, nil +} func (r *RedisCache) SetMevCommitValidatorRegistration(proposerPubkey common.PubkeyHex) error { err := r.client.Set(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+proposerPubkey.String(), "1", mevCommitValidatorRegistrationExpiry).Err() diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 89bb1f47..3ac525c8 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -26,7 +26,7 @@ type BuilderRegisteredEvent struct { type IMevCommitClient interface { GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) - GetActiveBuilders() ([]common.Address, error) + GetActiveBuilders() ([][]byte, error) } type MevCommitClient struct { @@ -94,8 +94,7 @@ func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddres func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) { return m.validatorOptInRouterCaller.AreValidatorsOptedIn(nil, pubkeys) } - -func (m *MevCommitClient) GetActiveBuilders() ([]common.Address, error) { +func (m *MevCommitClient) GetActiveBuilders() ([][]byte, error) { opts := &bind.FilterOpts{ Start: 0, End: nil, // Latest block @@ -107,14 +106,14 @@ func (m *MevCommitClient) GetActiveBuilders() ([]common.Address, error) { } defer iterator.Close() - activeBuilders := make([]common.Address, 0) + activeBuilderKeys := make([][]byte, 0) for iterator.Next() { isValid, err := m.isBuilderValid(iterator.Event.Provider) if err != nil { return nil, fmt.Errorf("failed to check if builder is valid: %w", err) } if isValid { - activeBuilders = append(activeBuilders, iterator.Event.Provider) + activeBuilderKeys = append(activeBuilderKeys, iterator.Event.BlsPublicKey) } } @@ -122,7 +121,7 @@ func (m *MevCommitClient) GetActiveBuilders() ([]common.Address, error) { return nil, fmt.Errorf("error iterating over ProviderRegistered events: %w", err) } - return activeBuilders, nil + return activeBuilderKeys, nil } func (m *MevCommitClient) isBuilderValid(builderAddress common.Address) (bool, error) { diff --git a/services/api/service.go b/services/api/service.go index 823b71c4..044e45bc 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1748,8 +1748,8 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr api.RespondError(w, http.StatusBadRequest, "no duty found for submission slot") return false } - // Check if validator is registered + start := time.Now() isValidatorRegistered, err := api.datastore.IsMevCommitValidatorRegistered(common.NewPubkeyHex(duty.Entry.Message.Pubkey.String())) if err != nil { log.WithError(err).Error("Failed to check validator registration") @@ -1759,7 +1759,7 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr if isValidatorRegistered { // Check if builder is registered TODO(@ckartik): Move this to datastore - isBuilderRegistered, err := api.mevCommitClient.IsBuilderRegistered(submission.BidTrace.BuilderPubkey.String()) + isBuilderRegistered, err := api.datastore.IsMevCommitBlockBuilder(common.NewPubkeyHex(submission.BidTrace.BuilderPubkey.String())) if err != nil { log.WithError(err).Error("Failed to check builder registration") api.RespondError(w, http.StatusInternalServerError, "Internal server error") @@ -1772,6 +1772,8 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr return false } } + duration := time.Since(start) + log.WithField("duration", duration).Info("MEV-Commit check completed") // Timestamp check expectedTimestamp := api.genesisInfo.Data.GenesisTime + (submission.BidTrace.Slot * common.SecondsPerSlot) diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index 879ab135..6610787d 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -175,6 +175,24 @@ func (hk *Housekeeper) updateProposerDuties(headSlot uint64) { hk.UpdateProposerDutiesWithoutChecks(headSlot) } +func (hk *Housekeeper) updateMevCommitBuilderRegistrations(headSlot uint64) { + log := hk.log.WithField("headSlot", headSlot) + log.Debug("updating MEV-Commit builder registrations...") + + // Fetch all registered builders from the MEV-Commit contract + registeredBuilders, err := hk.mevCommitClient.GetActiveBuilders() + if err != nil { + log.WithError(err).Error("failed to get registered builders from MEV-Commit contract") + return + } + err = hk.redis.SetMevCommitBlockBuilders(registeredBuilders) + if err != nil { + log.WithError(err).Error("failed to set MEV-Commit builder registrations") + return + } + log.WithField("count", len(registeredBuilders)).Info("updated MEV-Commit builder registrations") +} + func (hk *Housekeeper) UpdateProposerDutiesWithoutChecks(headSlot uint64) { epoch := headSlot / common.SlotsPerEpoch From 79254ca99b11f4140f55633299f759187193ee06 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 30 Sep 2024 12:00:07 -0400 Subject: [PATCH 20/70] chore: adds to public interface --- database/database.go | 2 ++ database/mockdb.go | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/database/database.go b/database/database.go index 60af6465..fa5766fc 100644 --- a/database/database.go +++ b/database/database.go @@ -30,6 +30,8 @@ type IDatabaseService interface { IsMevCommitValidatorRegistered(pubkey string) (bool, error) StoreMevCommitValidatorRegistration(pubkey string) error RemoveMevCommitValidatorRegistration(pubkey string) error + SaveMevCommitValidatorRegistration(entry MevCommitValidatorEntry) error + GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) SaveBuilderBlockSubmission(payload *common.VersionedSubmitBlockRequest, requestError, validationError error, receivedAt, eligibleAt time.Time, wasSimulated, saveExecPayload bool, profile common.Profile, optimisticSubmission bool, blockValue *uint256.Int) (entry *BuilderBlockSubmissionEntry, err error) GetBlockSubmissionEntry(slot uint64, proposerPubkey, blockHash string) (entry *BuilderBlockSubmissionEntry, err error) diff --git a/database/mockdb.go b/database/mockdb.go index 277cd7d7..d6287f27 100644 --- a/database/mockdb.go +++ b/database/mockdb.go @@ -195,3 +195,27 @@ func (db MockDB) GetTooLateGetPayload(slot uint64) (entries []*TooLateGetPayload func (db MockDB) InsertTooLateGetPayload(slot uint64, proposerPubkey, blockHash string, slotStart, requestTime, decodeTime, msIntoSlot uint64) error { return nil } + +func (db MockDB) NumValidatorRegistrationRows() (count uint64, err error) { + return 0, nil +} + +func (db MockDB) SaveMevCommitValidatorRegistration(entry MevCommitValidatorEntry) error { + return nil +} + +func (db MockDB) IsMevCommitValidatorRegistered(pubkey string) (bool, error) { + return false, nil +} + +func (db MockDB) RegisterMevCommitValidator(pubkey string) error { + return nil +} + +func (db MockDB) UnregisterMevCommitValidator(pubkey string) error { + return nil +} + +func (db MockDB) GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) { + return nil, nil +} From 5967122490bf260339285d7e3fc79e90b7b7ed4c Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 1 Oct 2024 12:06:11 -0400 Subject: [PATCH 21/70] chore: make sure we're also updating the builder registrations --- services/housekeeper/housekeeper.go | 1 + 1 file changed, 1 insertion(+) diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index 6610787d..8956d91b 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -146,6 +146,7 @@ func (hk *Housekeeper) processNewSlot(headSlot uint64) { // Update proposer duties go hk.updateProposerDuties(headSlot) go hk.updateMevCommitValidatorRegistrations(headSlot) + go hk.updateMevCommitBuilderRegistrations(headSlot) // Set headSlot in redis (for the website) err := hk.redis.SetStats(datastore.RedisStatsFieldLatestSlot, headSlot) From e22eb54288d9c9964142fd643cff00dc4170856a Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 1 Oct 2024 15:04:46 -0400 Subject: [PATCH 22/70] chore: removes DB entries for now --- database/database.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/database/database.go b/database/database.go index fa5766fc..20352319 100644 --- a/database/database.go +++ b/database/database.go @@ -27,11 +27,11 @@ type IDatabaseService interface { GetLatestValidatorRegistrations(timestampOnly bool) ([]*ValidatorRegistrationEntry, error) GetValidatorRegistration(pubkey string) (*ValidatorRegistrationEntry, error) GetValidatorRegistrationsForPubkeys(pubkeys []string) ([]*ValidatorRegistrationEntry, error) - IsMevCommitValidatorRegistered(pubkey string) (bool, error) - StoreMevCommitValidatorRegistration(pubkey string) error - RemoveMevCommitValidatorRegistration(pubkey string) error - SaveMevCommitValidatorRegistration(entry MevCommitValidatorEntry) error - GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) + // IsMevCommitValidatorRegistered(pubkey string) (bool, error) + // StoreMevCommitValidatorRegistration(pubkey string) error + // RemoveMevCommitValidatorRegistration(pubkey string) error + // SaveMevCommitValidatorRegistration(entry MevCommitValidatorEntry) error + // GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) SaveBuilderBlockSubmission(payload *common.VersionedSubmitBlockRequest, requestError, validationError error, receivedAt, eligibleAt time.Time, wasSimulated, saveExecPayload bool, profile common.Profile, optimisticSubmission bool, blockValue *uint256.Int) (entry *BuilderBlockSubmissionEntry, err error) GetBlockSubmissionEntry(slot uint64, proposerPubkey, blockHash string) (entry *BuilderBlockSubmissionEntry, err error) From 1525d871e85c43c931a8c94488dc8f9108b6db70 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 1 Oct 2024 20:33:36 -0400 Subject: [PATCH 23/70] chore: adds the unit tests for the mev-commit client --- mevcommitclient/mev_commit_client_test.go | 81 +++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 mevcommitclient/mev_commit_client_test.go diff --git a/mevcommitclient/mev_commit_client_test.go b/mevcommitclient/mev_commit_client_test.go new file mode 100644 index 00000000..abac0fe4 --- /dev/null +++ b/mevcommitclient/mev_commit_client_test.go @@ -0,0 +1,81 @@ +package mevcommitclient + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +const ( + mevCommitRPC = "https://chainrpc.testnet.mev-commit.xyz/" + ethereumL1RPC = "https://ethereum-holesky-rpc.publicnode.com" + providerRegistryAddr = "0xf4F10e18244d836311508917A3B04694D88999Dd" + validatorOptInRouterAddr = "0xCae46e1013D33587180Db5933Abd75D977c2d7ab" +) + +func TestNewMevCommitClient(t *testing.T) { + client, err := NewMevCommitClient( + ethereumL1RPC, + mevCommitRPC, + common.HexToAddress(validatorOptInRouterAddr), + common.HexToAddress(providerRegistryAddr), + ) + require.NoError(t, err) + require.NotNil(t, client) + + mevClient, ok := client.(*MevCommitClient) + require.True(t, ok) + + assert.Equal(t, ethereumL1RPC, mevClient.L1Address) + assert.Equal(t, mevCommitRPC, mevClient.MevCommitAddress) + assert.Equal(t, common.HexToAddress(validatorOptInRouterAddr), mevClient.ValidatorRouterAddress) + assert.Equal(t, common.HexToAddress(providerRegistryAddr), mevClient.BuilderRegistryAddress) +} + +func TestGetOptInStatusForValidators(t *testing.T) { + client, err := NewMevCommitClient( + ethereumL1RPC, + mevCommitRPC, + common.HexToAddress(validatorOptInRouterAddr), + common.HexToAddress(providerRegistryAddr), + ) + require.NoError(t, err) + + // Test with some sample public keys + pubkeys := [][]byte{ + {0x01, 0x02, 0x03}, + {0x04, 0x05, 0x06}, + } + + statuses, err := client.GetOptInStatusForValidators(pubkeys) + require.NoError(t, err) + assert.Len(t, statuses, len(pubkeys)) + + // Note: The actual values will depend on the state of the contract + // This test just checks that we get a response without error + for _, status := range statuses { + assert.IsType(t, bool(true), status) + } +} + +func TestGetActiveBuilders(t *testing.T) { + client, err := NewMevCommitClient( + ethereumL1RPC, + mevCommitRPC, + common.HexToAddress(validatorOptInRouterAddr), + common.HexToAddress(providerRegistryAddr), + ) + require.NoError(t, err) + + builders, err := client.GetActiveBuilders() + require.NoError(t, err) + + assert.NotEmpty(t, builders, "There should be at least one active builder") + for _, builder := range builders { + assert.Len(t, builder, 48, "Builder BLS public key should be 48 bytes long") + } + + assert.IsType(t, [][]byte{}, builders) +} From bb957aed55876b2064a438694a92ac9dc57ee3a5 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 2 Oct 2024 10:59:49 -0400 Subject: [PATCH 24/70] feat: adds more unit test coverage. --- services/api/service_test.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/services/api/service_test.go b/services/api/service_test.go index 0e82fa93..785e4733 100644 --- a/services/api/service_test.go +++ b/services/api/service_test.go @@ -1009,6 +1009,7 @@ func TestCheckSubmissionSlotDetails(t *testing.T) { for _, tc := range cases { t.Run(tc.description, func(t *testing.T) { _, _, backend := startTestBackend(t) + builderPubKey, _ := utils.HexToPubkey(testBuilderPubkey) backend.relay.capellaEpoch = 1 backend.relay.denebEpoch = 2 headSlot := testSlot - 1 @@ -1017,6 +1018,15 @@ func TestCheckSubmissionSlotDetails(t *testing.T) { log := logrus.NewEntry(logger) submission, err := common.GetBlockSubmissionInfo(tc.payload) require.NoError(t, err) + backend.relay.proposerDutiesMap = make(map[uint64]*common.BuilderGetValidatorsResponseEntry) + backend.relay.proposerDutiesMap[testSlot] = &common.BuilderGetValidatorsResponseEntry{ + Slot: testSlot, + Entry: &builderApiV1.SignedValidatorRegistration{ + Message: &builderApiV1.ValidatorRegistration{ + Pubkey: builderPubKey, + }, + }, + } ok := backend.relay.checkSubmissionSlotDetails(w, log, headSlot, tc.payload, submission) require.Equal(t, tc.expectOk, ok) }) From 0400be7ff22a28db11c6668b8d0be5ab34f43e86 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 2 Oct 2024 13:02:31 -0400 Subject: [PATCH 25/70] chore: fix variable naming --- services/api/service_test.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/services/api/service_test.go b/services/api/service_test.go index 785e4733..d326f1bd 100644 --- a/services/api/service_test.go +++ b/services/api/service_test.go @@ -40,6 +40,7 @@ const ( testWithdrawalsRoot = "0x7f6d156912a4cb1e74ee37e492ad883f7f7ac856d987b3228b517e490aa0189e" testPrevRandao = "0x9962816e9d0a39fd4c80935338a741dc916d1545694e41eb5a505e1a3098f9e4" testBuilderPubkey = "0xfa1ed37c3553d0ce1e9349b2c5063cf6e394d231c8d3e0df75e9462257c081543086109ffddaacc0aa76f33dc9661c83" + validatorPubKey = "0x6ae5932d1e248d987d51b58665b81848814202d7b23b343d20f2a167d12f07dcb01ca41c42fdd60b7fca9c4b90890792" ) var ( @@ -1009,7 +1010,7 @@ func TestCheckSubmissionSlotDetails(t *testing.T) { for _, tc := range cases { t.Run(tc.description, func(t *testing.T) { _, _, backend := startTestBackend(t) - builderPubKey, _ := utils.HexToPubkey(testBuilderPubkey) + validatorPubKey, _ := utils.HexToPubkey(testBuilderPubkey) backend.relay.capellaEpoch = 1 backend.relay.denebEpoch = 2 headSlot := testSlot - 1 @@ -1023,7 +1024,7 @@ func TestCheckSubmissionSlotDetails(t *testing.T) { Slot: testSlot, Entry: &builderApiV1.SignedValidatorRegistration{ Message: &builderApiV1.ValidatorRegistration{ - Pubkey: builderPubKey, + Pubkey: validatorPubKey, }, }, } From 5149183374fd22e4ed4b0581be0ac70605e6ec7a Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 2 Oct 2024 13:05:25 -0400 Subject: [PATCH 26/70] nit: ensure we grab readlock on purposer duties map --- services/api/service.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/api/service.go b/services/api/service.go index 044e45bc..b13fc656 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1742,7 +1742,9 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr // Do a check in memchache for the slot being with a registered provider. If miss, go to redis. if miss again go to postgres. // Find the duty for the submission slot + api.proposerDutiesLock.RLock() duty := api.proposerDutiesMap[submission.BidTrace.Slot] + api.proposerDutiesLock.RUnlock() if duty == nil { log.Info("no duty found for submission slot") api.RespondError(w, http.StatusBadRequest, "no duty found for submission slot") From 6a05c1fe9838d4701cc884a89368365b57eb6a94 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Fri, 4 Oct 2024 13:26:39 -0400 Subject: [PATCH 27/70] chore: cleanup --- database/database.go | 84 ++++++++++++++++++++--------------------- services/api/service.go | 2 - 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/database/database.go b/database/database.go index 20352319..0dec3d3e 100644 --- a/database/database.go +++ b/database/database.go @@ -146,14 +146,14 @@ func (s *DatabaseService) SaveValidatorRegistration(entry ValidatorRegistrationE return err } -func (s *DatabaseService) SaveMevCommitValidatorRegistration(entry MevCommitValidatorEntry) error { - // On conflict, set the correct opted in status - query := `INSERT INTO ` + vars.TableMevCommitValidators + ` (pubkey, is_opted_in, timestamp) - VALUES (:pubkey, :is_opted_in, :timestamp) - ON CONFLICT (pubkey) DO UPDATE SET is_opted_in = EXCLUDED.is_opted_in, timestamp = EXCLUDED.timestamp;` - _, err := s.DB.NamedExec(query, entry) - return err -} +// func (s *DatabaseService) SaveMevCommitValidatorRegistration(entry MevCommitValidatorEntry) error { +// // On conflict, set the correct opted in status +// query := `INSERT INTO ` + vars.TableMevCommitValidators + ` (pubkey, is_opted_in, timestamp) +// VALUES (:pubkey, :is_opted_in, :timestamp) +// ON CONFLICT (pubkey) DO UPDATE SET is_opted_in = EXCLUDED.is_opted_in, timestamp = EXCLUDED.timestamp;` +// _, err := s.DB.NamedExec(query, entry) +// return err +// } func (s *DatabaseService) GetValidatorRegistration(pubkey string) (*ValidatorRegistrationEntry, error) { query := `SELECT DISTINCT ON (pubkey) pubkey, fee_recipient, timestamp, gas_limit, signature @@ -177,40 +177,40 @@ func (s *DatabaseService) IsMevCommitValidatorRegistered(pubkey string) (bool, e return exists, nil } -func (s *DatabaseService) RegisterMevCommitValidator(pubkey string) error { - query := `INSERT INTO ` + vars.TableMevCommitValidators + ` (pubkey, timestamp) VALUES ($1, NOW())` - _, err := s.DB.Exec(query, pubkey) - return err -} - -func (s *DatabaseService) UnregisterMevCommitValidator(pubkey string) error { - query := `DELETE FROM ` + vars.TableMevCommitValidators + ` WHERE pubkey=$1` - result, err := s.DB.Exec(query, pubkey) - if err != nil { - return err - } - rowsAffected, err := result.RowsAffected() - if err != nil { - return err - } - if rowsAffected == 0 { - return ErrValidatorNotFound - } - return nil -} - -func (s *DatabaseService) GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) { - query := `SELECT pubkey, timestamp FROM ` + vars.TableMevCommitValidators + ` WHERE pubkey=$1` - var entry MevCommitValidatorEntry - err := s.DB.Get(&entry, query, pubkey) - if err == sql.ErrNoRows { - return nil, ErrValidatorNotFound - } - if err != nil { - return nil, err - } - return &entry, nil -} +// func (s *DatabaseService) RegisterMevCommitValidator(pubkey string) error { +// query := `INSERT INTO ` + vars.TableMevCommitValidators + ` (pubkey, timestamp) VALUES ($1, NOW())` +// _, err := s.DB.Exec(query, pubkey) +// return err +// } + +// func (s *DatabaseService) UnregisterMevCommitValidator(pubkey string) error { +// query := `DELETE FROM ` + vars.TableMevCommitValidators + ` WHERE pubkey=$1` +// result, err := s.DB.Exec(query, pubkey) +// if err != nil { +// return err +// } +// rowsAffected, err := result.RowsAffected() +// if err != nil { +// return err +// } +// if rowsAffected == 0 { +// return ErrValidatorNotFound +// } +// return nil +// } + +// func (s *DatabaseService) GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) { +// query := `SELECT pubkey, timestamp FROM ` + vars.TableMevCommitValidators + ` WHERE pubkey=$1` +// var entry MevCommitValidatorEntry +// err := s.DB.Get(&entry, query, pubkey) +// if err == sql.ErrNoRows { +// return nil, ErrValidatorNotFound +// } +// if err != nil { +// return nil, err +// } +// return &entry, nil +// } func (s *DatabaseService) GetValidatorRegistrationsForPubkeys(pubkeys []string) (entries []*ValidatorRegistrationEntry, err error) { query := `SELECT DISTINCT ON (pubkey) pubkey, fee_recipient, timestamp, gas_limit, signature diff --git a/services/api/service.go b/services/api/service.go index b13fc656..e3e4b69b 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1760,14 +1760,12 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr } if isValidatorRegistered { - // Check if builder is registered TODO(@ckartik): Move this to datastore isBuilderRegistered, err := api.datastore.IsMevCommitBlockBuilder(common.NewPubkeyHex(submission.BidTrace.BuilderPubkey.String())) if err != nil { log.WithError(err).Error("Failed to check builder registration") api.RespondError(w, http.StatusInternalServerError, "Internal server error") return false } - if !isBuilderRegistered { // TODO: Implement caching strategy for builder registration status api.RespondError(w, http.StatusBadRequest, "Builder pubkey is not registered under mev-commit") From 152c784d8cba78be70580e1460b4ae0618d3d4b1 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Fri, 4 Oct 2024 13:36:30 -0400 Subject: [PATCH 28/70] chore: configures correct os vars on startup --- cmd/housekeeper.go | 19 +++++++++++++++++++ cmd/variables.go | 27 ++++++++++++++++++--------- services/housekeeper/housekeeper.go | 2 ++ 3 files changed, 39 insertions(+), 9 deletions(-) diff --git a/cmd/housekeeper.go b/cmd/housekeeper.go index b307a2a0..b9bf7f57 100644 --- a/cmd/housekeeper.go +++ b/cmd/housekeeper.go @@ -5,10 +5,12 @@ import ( "os" "strings" + gethCommon "github.com/ethereum/go-ethereum/common" "github.com/flashbots/mev-boost-relay/beaconclient" "github.com/flashbots/mev-boost-relay/common" "github.com/flashbots/mev-boost-relay/database" "github.com/flashbots/mev-boost-relay/datastore" + "github.com/flashbots/mev-boost-relay/mevcommitclient" "github.com/flashbots/mev-boost-relay/services/housekeeper" "github.com/sirupsen/logrus" "github.com/spf13/cobra" @@ -35,6 +37,11 @@ func init() { housekeeperCmd.Flags().BoolVar(&hkPprofEnabled, "pprof", hkDefaultPprofEnabled, "enable pprof API") housekeeperCmd.Flags().StringVar(&hkPprofListenAddr, "pprof-listen-addr", hkDefaultPprofListenAddr, "listen address for pprof server") + + housekeeperCmd.Flags().StringVar(&mevCommitRPC, "mev-commit-rpc", defaultMevCommitRPC, "MEV-Commit RPC endpoint") + housekeeperCmd.Flags().StringVar(ðereumL1RPC, "ethereum-l1-rpc", defaultEthereumL1RPC, "Ethereum L1 RPC endpoint") + housekeeperCmd.Flags().StringVar(&providerRegistryAddr, "provider-registry-addr", defaultProviderRegistryAddr, "MEV-Commit provider registry contract address") + housekeeperCmd.Flags().StringVar(&validatorOptInRouterAddr, "validator-optin-router-addr", defaultValidatorOptInRouterAddr, "MEV-Commit validator opt-in router contract address") } var housekeeperCmd = &cobra.Command{ @@ -84,6 +91,16 @@ var housekeeperCmd = &cobra.Command{ log.WithError(err).Fatalf("Failed to connect to Postgres database at %s%s", dbURL.Host, dbURL.Path) } + mevCommitClient, err := mevcommitclient.NewMevCommitClient( + ethereumL1RPC, + mevCommitRPC, + gethCommon.HexToAddress(validatorOptInRouterAddr), + gethCommon.HexToAddress(providerRegistryAddr), + ) + if err != nil { + log.WithError(err).Fatal("Failed to create MEV-Commit client") + } + opts := &housekeeper.HousekeeperOpts{ Log: log, Redis: redis, @@ -92,6 +109,8 @@ var housekeeperCmd = &cobra.Command{ PprofAPI: hkPprofEnabled, PprofListenAddress: hkPprofListenAddr, + + MevCommitClient: mevCommitClient, } service := housekeeper.NewHousekeeper(opts) log.Info("Starting housekeeper service...") diff --git a/cmd/variables.go b/cmd/variables.go index 58d6b59b..cf04286b 100644 --- a/cmd/variables.go +++ b/cmd/variables.go @@ -7,15 +7,19 @@ import ( ) var ( - defaultNetwork = common.GetEnv("NETWORK", "") - defaultBeaconURIs = common.GetSliceEnv("BEACON_URIS", []string{"http://localhost:3500"}) - defaultBeaconPublishURIs = common.GetSliceEnv("BEACON_PUBLISH_URIS", []string{}) - defaultRedisURI = common.GetEnv("REDIS_URI", "localhost:6379") - defaultRedisReadonlyURI = common.GetEnv("REDIS_READONLY_URI", "") - defaultPostgresDSN = common.GetEnv("POSTGRES_DSN", "") - defaultMemcachedURIs = common.GetSliceEnv("MEMCACHED_URIS", nil) - defaultLogJSON = os.Getenv("LOG_JSON") != "" - defaultLogLevel = common.GetEnv("LOG_LEVEL", "info") + defaultNetwork = common.GetEnv("NETWORK", "") + defaultBeaconURIs = common.GetSliceEnv("BEACON_URIS", []string{"http://localhost:3500"}) + defaultBeaconPublishURIs = common.GetSliceEnv("BEACON_PUBLISH_URIS", []string{}) + defaultRedisURI = common.GetEnv("REDIS_URI", "localhost:6379") + defaultRedisReadonlyURI = common.GetEnv("REDIS_READONLY_URI", "") + defaultPostgresDSN = common.GetEnv("POSTGRES_DSN", "") + defaultMemcachedURIs = common.GetSliceEnv("MEMCACHED_URIS", nil) + defaultLogJSON = os.Getenv("LOG_JSON") != "" + defaultLogLevel = common.GetEnv("LOG_LEVEL", "info") + defaultMevCommitRPC = common.GetEnv("MEV_COMMIT_RPC", "") + defaultEthereumL1RPC = common.GetEnv("ETHEREUM_L1_RPC", "") + defaultProviderRegistryAddr = common.GetEnv("PROVIDER_REGISTRY_ADDR", "") + defaultValidatorOptInRouterAddr = common.GetEnv("VALIDATOR_OPTIN_ROUTER_ADDR", "") beaconNodeURIs []string beaconNodePublishURIs []string @@ -24,6 +28,11 @@ var ( postgresDSN string memcachedURIs []string + mevCommitRPC string + ethereumL1RPC string + providerRegistryAddr string + validatorOptInRouterAddr string + logJSON bool logLevel string diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index 8956d91b..aa42b091 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -35,6 +35,8 @@ type HousekeeperOpts struct { PprofAPI bool PprofListenAddress string + + MevCommitClient mevcommitclient.IMevCommitClient } type Housekeeper struct { From a0a7249a7bebd1cec91e1ce03f03d848d852d40b Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 7 Oct 2024 13:20:24 -0400 Subject: [PATCH 29/70] feat: allow toggling of mev-commit filtering feature --- cmd/api.go | 61 +++++++++++++++++++++-------------------- services/api/service.go | 39 ++++++++++++++------------ 2 files changed, 53 insertions(+), 47 deletions(-) diff --git a/cmd/api.go b/cmd/api.go index 16f127bd..55e4dddf 100644 --- a/cmd/api.go +++ b/cmd/api.go @@ -28,20 +28,22 @@ var ( apiDefaultInternalAPIEnabled = os.Getenv("ENABLE_INTERNAL_API") == "1" // Default Builder, Data, and Proposer API as true. - apiDefaultBuilderAPIEnabled = os.Getenv("DISABLE_BUILDER_API") != "1" - apiDefaultDataAPIEnabled = os.Getenv("DISABLE_DATA_API") != "1" - apiDefaultProposerAPIEnabled = os.Getenv("DISABLE_PROPOSER_API") != "1" - - apiListenAddr string - apiPprofEnabled bool - apiSecretKey string - apiBlockSimURL string - apiDebug bool - apiBuilderAPI bool - apiDataAPI bool - apiInternalAPI bool - apiProposerAPI bool - apiLogTag string + apiDefaultBuilderAPIEnabled = os.Getenv("DISABLE_BUILDER_API") != "1" + apiDefaultDataAPIEnabled = os.Getenv("DISABLE_DATA_API") != "1" + apiDefaultProposerAPIEnabled = os.Getenv("DISABLE_PROPOSER_API") != "1" + apiDefaultMevCommitFilteringEnabled = os.Getenv("DISABLE_MEV_COMMIT_FILTERING") != "1" + + apiMevCommitFiltering bool + apiListenAddr string + apiPprofEnabled bool + apiSecretKey string + apiBlockSimURL string + apiDebug bool + apiBuilderAPI bool + apiDataAPI bool + apiInternalAPI bool + apiProposerAPI bool + apiLogTag string ) func init() { @@ -68,6 +70,7 @@ func init() { apiCmd.Flags().BoolVar(&apiDataAPI, "data-api", apiDefaultDataAPIEnabled, "enable data API (/data/...)") apiCmd.Flags().BoolVar(&apiInternalAPI, "internal-api", apiDefaultInternalAPIEnabled, "enable internal API (/internal/...)") apiCmd.Flags().BoolVar(&apiProposerAPI, "proposer-api", apiDefaultProposerAPIEnabled, "enable proposer API (/proposer/...)") + apiCmd.Flags().BoolVar(&apiMevCommitFiltering, "mev-commit-filtering", apiDefaultMevCommitFilteringEnabled, "enable mev-commit-filtering") } var apiCmd = &cobra.Command{ @@ -155,21 +158,21 @@ var apiCmd = &cobra.Command{ } opts := api.RelayAPIOpts{ - Log: log, - ListenAddr: apiListenAddr, - BeaconClient: beaconClient, - Datastore: ds, - Redis: redis, - Memcached: mem, - DB: db, - EthNetDetails: *networkInfo, - BlockSimURL: apiBlockSimURL, - - BlockBuilderAPI: apiBuilderAPI, - DataAPI: apiDataAPI, - InternalAPI: apiInternalAPI, - ProposerAPI: apiProposerAPI, - PprofAPI: apiPprofEnabled, + Log: log, + ListenAddr: apiListenAddr, + BeaconClient: beaconClient, + Datastore: ds, + Redis: redis, + Memcached: mem, + DB: db, + EthNetDetails: *networkInfo, + BlockSimURL: apiBlockSimURL, + MevCommitFiltering: apiMevCommitFiltering, + BlockBuilderAPI: apiBuilderAPI, + DataAPI: apiDataAPI, + InternalAPI: apiInternalAPI, + ProposerAPI: apiProposerAPI, + PprofAPI: apiPprofEnabled, } // Decode the private key diff --git a/services/api/service.go b/services/api/service.go index e3e4b69b..93656a8b 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -140,7 +140,7 @@ type RelayAPIOpts struct { PprofAPI bool InternalAPI bool - MevCommitEnabled bool + MevCommitFiltering bool } type payloadAttributesHelper struct { @@ -1750,30 +1750,33 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr api.RespondError(w, http.StatusBadRequest, "no duty found for submission slot") return false } - // Check if validator is registered - start := time.Now() - isValidatorRegistered, err := api.datastore.IsMevCommitValidatorRegistered(common.NewPubkeyHex(duty.Entry.Message.Pubkey.String())) - if err != nil { - log.WithError(err).Error("Failed to check validator registration") - api.RespondError(w, http.StatusInternalServerError, "Internal server error") - return false - } - if isValidatorRegistered { - isBuilderRegistered, err := api.datastore.IsMevCommitBlockBuilder(common.NewPubkeyHex(submission.BidTrace.BuilderPubkey.String())) + if api.opts.MevCommitFiltering { + // Check if validator is registered + start := time.Now() + isValidatorRegistered, err := api.datastore.IsMevCommitValidatorRegistered(common.NewPubkeyHex(duty.Entry.Message.Pubkey.String())) if err != nil { - log.WithError(err).Error("Failed to check builder registration") + log.WithError(err).Error("Failed to check validator registration") api.RespondError(w, http.StatusInternalServerError, "Internal server error") return false } - if !isBuilderRegistered { - // TODO: Implement caching strategy for builder registration status - api.RespondError(w, http.StatusBadRequest, "Builder pubkey is not registered under mev-commit") - return false + + if isValidatorRegistered { + isBuilderRegistered, err := api.datastore.IsMevCommitBlockBuilder(common.NewPubkeyHex(submission.BidTrace.BuilderPubkey.String())) + if err != nil { + log.WithError(err).Error("Failed to check builder registration") + api.RespondError(w, http.StatusInternalServerError, "Internal server error") + return false + } + if !isBuilderRegistered { + // TODO: Implement caching strategy for builder registration status + api.RespondError(w, http.StatusBadRequest, "Builder pubkey is not registered under mev-commit") + return false + } } + duration := time.Since(start) + log.WithField("duration", duration).Info("MEV-Commit check completed") } - duration := time.Since(start) - log.WithField("duration", duration).Info("MEV-Commit check completed") // Timestamp check expectedTimestamp := api.genesisInfo.Data.GenesisTime + (submission.BidTrace.Slot * common.SecondsPerSlot) From 79045fd99185c81bf95cc72f52ae4211a375503d Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 8 Oct 2024 16:03:56 -0400 Subject: [PATCH 30/70] nit: fixes two small bugs and adds a unit test --- datastore/redis.go | 4 +--- datastore/redis_test.go | 25 +++++++++++++++++++++++++ services/housekeeper/housekeeper.go | 2 +- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/datastore/redis.go b/datastore/redis.go index b0a091c1..ed8e3dfe 100644 --- a/datastore/redis.go +++ b/datastore/redis.go @@ -2,7 +2,6 @@ package datastore import ( "context" - "encoding/hex" "encoding/json" "errors" "fmt" @@ -256,9 +255,8 @@ func (r *RedisCache) SetMevCommitBlockBuilders(builders [][]byte) error { // Add all builders to the set for _, builder := range builders { - pipe.SAdd(ctx, r.keyMevCommitBlockBuilder, hex.EncodeToString(builder)) + pipe.SAdd(ctx, r.keyMevCommitBlockBuilder, string(builder)) } - // Execute pipeline _, err := pipe.Exec(ctx) if err != nil { diff --git a/datastore/redis_test.go b/datastore/redis_test.go index fdada757..13a76e74 100644 --- a/datastore/redis_test.go +++ b/datastore/redis_test.go @@ -444,6 +444,31 @@ func TestPipelineNilCheck(t *testing.T) { require.Equal(t, big.NewInt(0), f) } +func TestSetMevCommitBlockBuilders(t *testing.T) { + cache := setupTestRedis(t) + + builderPubkey := "0xfa1ed37c3553d0ce1e9349b2c5063cf6e394d231c8d3e0df75e9462257c081543086109ffddaacc0aa76f33dc9661c83" + // Set a commit block builder + err := cache.SetMevCommitBlockBuilders([][]byte{[]byte(builderPubkey)}) + require.NoError(t, err) + // Retrieve the list of MEV-Commit block builders + builders, err := cache.GetMevCommitBlockBuilders() + require.NoError(t, err) + require.Len(t, builders, 1) + require.Equal(t, common.PubkeyHex(builderPubkey), builders[0]) + + // Check if the commit block builder is set correctly + isSet, err := cache.IsMevCommitBlockBuilder(common.PubkeyHex(builderPubkey)) + require.NoError(t, err) + require.True(t, isSet) + + // Check if a non-existent commit block builder returns false + nonExistentBuilderPubkey := "0x2e02be2c9f9eccf9856478fdb7876598fed2da09f45c233969ba647a250231150ecf38bce5771adb6171c86b79a92f16" + isSet, err = cache.IsMevCommitBlockBuilder(common.PubkeyHex(nonExistentBuilderPubkey)) + require.NoError(t, err) + require.False(t, isSet) +} + // func TestPipeline(t *testing.T) { // cache := setupTestRedis(t) diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index aa42b091..21142b98 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -277,7 +277,7 @@ func (hk *Housekeeper) UpdateProposerDutiesWithoutChecks(headSlot uint64) { // This allows us to maintain 1 epoch in advance, which is enough to check if a validator is registered for a given epoch. func (hk *Housekeeper) updateMevCommitValidatorRegistrations(headSlot uint64) { // Only update once per epoch - at the epoch start of the epoch - if headSlot%common.SlotsPerEpoch == 0 { + if headSlot%common.SlotsPerEpoch != 0 { return } From 3035693f17f167c72864902031c842b55418e251 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 10:34:12 -0400 Subject: [PATCH 31/70] chore: cleanup and move feature flag higher --- .../012_add_mev_commit_column_builders.go | 19 --------------- .../013_add_mev_commit_validators_table.go | 23 ------------------- services/api/service.go | 21 ++++++++--------- 3 files changed, 10 insertions(+), 53 deletions(-) delete mode 100644 database/migrations/012_add_mev_commit_column_builders.go delete mode 100644 database/migrations/013_add_mev_commit_validators_table.go diff --git a/database/migrations/012_add_mev_commit_column_builders.go b/database/migrations/012_add_mev_commit_column_builders.go deleted file mode 100644 index 4c94dd9c..00000000 --- a/database/migrations/012_add_mev_commit_column_builders.go +++ /dev/null @@ -1,19 +0,0 @@ -package migrations - -import ( - "github.com/flashbots/mev-boost-relay/database/vars" - migrate "github.com/rubenv/sql-migrate" -) - -var Migration012AddMevCommitColumnBuilders = &migrate.Migration{ - Id: "012-add-mev-commit-column-builders", - Up: []string{` - ALTER TABLE ` + vars.TableBlockBuilder + ` ADD is_mev_commit_opted_in boolean NOT NULL DEFAULT false; - `}, - Down: []string{` - ALTER TABLE ` + vars.TableBlockBuilder + ` DROP COLUMN is_mev_commit_opted_in; - `}, - - DisableTransactionUp: true, - DisableTransactionDown: true, -} diff --git a/database/migrations/013_add_mev_commit_validators_table.go b/database/migrations/013_add_mev_commit_validators_table.go deleted file mode 100644 index 9a01e12d..00000000 --- a/database/migrations/013_add_mev_commit_validators_table.go +++ /dev/null @@ -1,23 +0,0 @@ -package migrations - -import ( - "github.com/flashbots/mev-boost-relay/database/vars" - migrate "github.com/rubenv/sql-migrate" -) - -var Migration013AddMevCommitValidatorsTable = &migrate.Migration{ - Id: "013-add-mev-commit-validators-table", - Up: []string{` - CREATE TABLE IF NOT EXISTS ` + vars.TableMevCommitValidators + ` ( - id SERIAL PRIMARY KEY, - pubkey VARCHAR(98) NOT NULL, - timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP - ); - `}, - Down: []string{` - DROP TABLE mev_commit_validator_registration; - `}, - - DisableTransactionUp: true, - DisableTransactionDown: true, -} diff --git a/services/api/service.go b/services/api/service.go index 93656a8b..a371be92 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1739,19 +1739,18 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr return false } - // Do a check in memchache for the slot being with a registered provider. If miss, go to redis. if miss again go to postgres. + if api.opts.MevCommitFiltering { - // Find the duty for the submission slot - api.proposerDutiesLock.RLock() - duty := api.proposerDutiesMap[submission.BidTrace.Slot] - api.proposerDutiesLock.RUnlock() - if duty == nil { - log.Info("no duty found for submission slot") - api.RespondError(w, http.StatusBadRequest, "no duty found for submission slot") - return false - } + // Find the duty for the submission slot + api.proposerDutiesLock.RLock() + duty := api.proposerDutiesMap[submission.BidTrace.Slot] + api.proposerDutiesLock.RUnlock() + if duty == nil { + log.Info("no duty found for submission slot") + api.RespondError(w, http.StatusBadRequest, "no duty found for submission slot") + return false + } - if api.opts.MevCommitFiltering { // Check if validator is registered start := time.Now() isValidatorRegistered, err := api.datastore.IsMevCommitValidatorRegistered(common.NewPubkeyHex(duty.Entry.Message.Pubkey.String())) From ca20ea21ff85defb1cbb420593bf573416556a85 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 10:54:45 -0400 Subject: [PATCH 32/70] feat: query for finalized state on purposeres --- mevcommitclient/mev_commit_client.go | 13 ++++++++++++- services/api/service.go | 1 - 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 3ac525c8..50e5f01d 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -92,7 +92,18 @@ func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddres } func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) { - return m.validatorOptInRouterCaller.AreValidatorsOptedIn(nil, pubkeys) + // Get the finalized block number + var finalizedBlockNumber *big.Int + err := m.l1Client.Client().Call(&finalizedBlockNumber, "eth_getBlockByNumber", "finalized", false) + if err != nil { + return nil, fmt.Errorf("failed to get finalized block: %w", err) + } + + opts := &bind.CallOpts{ + BlockNumber: finalizedBlockNumber, + } + + return m.validatorOptInRouterCaller.AreValidatorsOptedIn(opts, pubkeys) } func (m *MevCommitClient) GetActiveBuilders() ([][]byte, error) { opts := &bind.FilterOpts{ diff --git a/services/api/service.go b/services/api/service.go index a371be92..d59cfb14 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1740,7 +1740,6 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr } if api.opts.MevCommitFiltering { - // Find the duty for the submission slot api.proposerDutiesLock.RLock() duty := api.proposerDutiesMap[submission.BidTrace.Slot] From f76b56ed5ea629461b630344d8a2a9de9704058c Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 10:59:03 -0400 Subject: [PATCH 33/70] chore: remove db modificaitons --- database/database.go | 57 -------------------------------------------- 1 file changed, 57 deletions(-) diff --git a/database/database.go b/database/database.go index 0dec3d3e..44356f21 100644 --- a/database/database.go +++ b/database/database.go @@ -5,7 +5,6 @@ import ( "context" "database/sql" "encoding/json" - "errors" "fmt" "os" "strings" @@ -146,15 +145,6 @@ func (s *DatabaseService) SaveValidatorRegistration(entry ValidatorRegistrationE return err } -// func (s *DatabaseService) SaveMevCommitValidatorRegistration(entry MevCommitValidatorEntry) error { -// // On conflict, set the correct opted in status -// query := `INSERT INTO ` + vars.TableMevCommitValidators + ` (pubkey, is_opted_in, timestamp) -// VALUES (:pubkey, :is_opted_in, :timestamp) -// ON CONFLICT (pubkey) DO UPDATE SET is_opted_in = EXCLUDED.is_opted_in, timestamp = EXCLUDED.timestamp;` -// _, err := s.DB.NamedExec(query, entry) -// return err -// } - func (s *DatabaseService) GetValidatorRegistration(pubkey string) (*ValidatorRegistrationEntry, error) { query := `SELECT DISTINCT ON (pubkey) pubkey, fee_recipient, timestamp, gas_limit, signature FROM ` + vars.TableValidatorRegistration + ` @@ -165,53 +155,6 @@ func (s *DatabaseService) GetValidatorRegistration(pubkey string) (*ValidatorReg return entry, err } -var ErrValidatorNotFound = errors.New("validator not found") - -func (s *DatabaseService) IsMevCommitValidatorRegistered(pubkey string) (bool, error) { - query := `SELECT EXISTS(SELECT 1 FROM ` + vars.TableMevCommitValidators + ` WHERE pubkey=$1)` - var exists bool - err := s.DB.Get(&exists, query, pubkey) - if err != nil { - return false, err - } - return exists, nil -} - -// func (s *DatabaseService) RegisterMevCommitValidator(pubkey string) error { -// query := `INSERT INTO ` + vars.TableMevCommitValidators + ` (pubkey, timestamp) VALUES ($1, NOW())` -// _, err := s.DB.Exec(query, pubkey) -// return err -// } - -// func (s *DatabaseService) UnregisterMevCommitValidator(pubkey string) error { -// query := `DELETE FROM ` + vars.TableMevCommitValidators + ` WHERE pubkey=$1` -// result, err := s.DB.Exec(query, pubkey) -// if err != nil { -// return err -// } -// rowsAffected, err := result.RowsAffected() -// if err != nil { -// return err -// } -// if rowsAffected == 0 { -// return ErrValidatorNotFound -// } -// return nil -// } - -// func (s *DatabaseService) GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) { -// query := `SELECT pubkey, timestamp FROM ` + vars.TableMevCommitValidators + ` WHERE pubkey=$1` -// var entry MevCommitValidatorEntry -// err := s.DB.Get(&entry, query, pubkey) -// if err == sql.ErrNoRows { -// return nil, ErrValidatorNotFound -// } -// if err != nil { -// return nil, err -// } -// return &entry, nil -// } - func (s *DatabaseService) GetValidatorRegistrationsForPubkeys(pubkeys []string) (entries []*ValidatorRegistrationEntry, err error) { query := `SELECT DISTINCT ON (pubkey) pubkey, fee_recipient, timestamp, gas_limit, signature FROM ` + vars.TableValidatorRegistration + ` From 26004e9269400bc2a9f36702bb17b140346b00a5 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 10:59:46 -0400 Subject: [PATCH 34/70] chore: remove interface --- database/database.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/database/database.go b/database/database.go index 44356f21..dbb1b62f 100644 --- a/database/database.go +++ b/database/database.go @@ -26,12 +26,6 @@ type IDatabaseService interface { GetLatestValidatorRegistrations(timestampOnly bool) ([]*ValidatorRegistrationEntry, error) GetValidatorRegistration(pubkey string) (*ValidatorRegistrationEntry, error) GetValidatorRegistrationsForPubkeys(pubkeys []string) ([]*ValidatorRegistrationEntry, error) - // IsMevCommitValidatorRegistered(pubkey string) (bool, error) - // StoreMevCommitValidatorRegistration(pubkey string) error - // RemoveMevCommitValidatorRegistration(pubkey string) error - // SaveMevCommitValidatorRegistration(entry MevCommitValidatorEntry) error - // GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) - SaveBuilderBlockSubmission(payload *common.VersionedSubmitBlockRequest, requestError, validationError error, receivedAt, eligibleAt time.Time, wasSimulated, saveExecPayload bool, profile common.Profile, optimisticSubmission bool, blockValue *uint256.Int) (entry *BuilderBlockSubmissionEntry, err error) GetBlockSubmissionEntry(slot uint64, proposerPubkey, blockHash string) (entry *BuilderBlockSubmissionEntry, err error) GetBuilderSubmissions(filters GetBuilderSubmissionsFilters) ([]*BuilderBlockSubmissionEntry, error) From d5b315d8df4da5df7f889449e51bfa4734a01cb4 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 11:00:31 -0400 Subject: [PATCH 35/70] chore: cleanup mockdb --- database/mockdb.go | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/database/mockdb.go b/database/mockdb.go index d6287f27..277cd7d7 100644 --- a/database/mockdb.go +++ b/database/mockdb.go @@ -195,27 +195,3 @@ func (db MockDB) GetTooLateGetPayload(slot uint64) (entries []*TooLateGetPayload func (db MockDB) InsertTooLateGetPayload(slot uint64, proposerPubkey, blockHash string, slotStart, requestTime, decodeTime, msIntoSlot uint64) error { return nil } - -func (db MockDB) NumValidatorRegistrationRows() (count uint64, err error) { - return 0, nil -} - -func (db MockDB) SaveMevCommitValidatorRegistration(entry MevCommitValidatorEntry) error { - return nil -} - -func (db MockDB) IsMevCommitValidatorRegistered(pubkey string) (bool, error) { - return false, nil -} - -func (db MockDB) RegisterMevCommitValidator(pubkey string) error { - return nil -} - -func (db MockDB) UnregisterMevCommitValidator(pubkey string) error { - return nil -} - -func (db MockDB) GetMevCommitValidatorRegistration(pubkey string) (*MevCommitValidatorEntry, error) { - return nil, nil -} From ecaaba9e0d472a3b41fc2f8261f4edb92cfff10b Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 11:04:00 -0400 Subject: [PATCH 36/70] nit: updates name of registry --- mevcommitclient/mev_commit_client.go | 10 +++++----- mevcommitclient/mev_commit_client_test.go | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 50e5f01d..4ca9a780 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -33,7 +33,7 @@ type MevCommitClient struct { L1Address string MevCommitAddress string ValidatorRouterAddress common.Address - BuilderRegistryAddress common.Address + ProviderRegistryAddress common.Address validatorOptInRouterCaller *validatoroptinrouter.ValidatoroptinrouterCaller builderRegistryCaller *builderRegistry.ProviderregistryCaller builderRegistryFilterer *builderRegistry.ProviderregistryFilterer @@ -46,7 +46,7 @@ const ( abiJSON = `[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"builder","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"blsPublicKey","type":"bytes"}],"name":"BuilderRegistered","type":"event"},{"inputs":[{"internalType":"address","name":"builder","type":"address"}],"name":"isBuilderValid","outputs":[],"stateMutability":"view","type":"function"}]` ) -func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddress, builderRegistryAddress common.Address) (IMevCommitClient, error) { +func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddress, ProviderRegistryAddress common.Address) (IMevCommitClient, error) { l1Client, err := ethclient.Dial(l1MainnetUrl) if err != nil { return nil, fmt.Errorf("failed to connect to L1 Mainnet: %w", err) @@ -62,12 +62,12 @@ func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddres return nil, fmt.Errorf("failed to create ValidatorOptInRouter caller: %w", err) } - builderRegistryCaller, err := builderRegistry.NewProviderregistryCaller(builderRegistryAddress, mevCommitClient) + builderRegistryCaller, err := builderRegistry.NewProviderregistryCaller(ProviderRegistryAddress, mevCommitClient) if err != nil { return nil, fmt.Errorf("failed to create BuilderRegistry caller: %w", err) } - builderRegistryFilterer, err := builderRegistry.NewProviderregistryFilterer(builderRegistryAddress, mevCommitClient) + builderRegistryFilterer, err := builderRegistry.NewProviderregistryFilterer(ProviderRegistryAddress, mevCommitClient) if err != nil { return nil, fmt.Errorf("failed to create BuilderRegistry filterer: %w", err) } @@ -81,7 +81,7 @@ func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddres L1Address: l1MainnetUrl, MevCommitAddress: mevCommitUrl, ValidatorRouterAddress: validatorRouterAddress, - BuilderRegistryAddress: builderRegistryAddress, + ProviderRegistryAddress: ProviderRegistryAddress, validatorOptInRouterCaller: validatorOptInRouter, builderRegistryCaller: builderRegistryCaller, builderRegistryFilterer: builderRegistryFilterer, diff --git a/mevcommitclient/mev_commit_client_test.go b/mevcommitclient/mev_commit_client_test.go index abac0fe4..d05de7cc 100644 --- a/mevcommitclient/mev_commit_client_test.go +++ b/mevcommitclient/mev_commit_client_test.go @@ -31,7 +31,7 @@ func TestNewMevCommitClient(t *testing.T) { assert.Equal(t, ethereumL1RPC, mevClient.L1Address) assert.Equal(t, mevCommitRPC, mevClient.MevCommitAddress) assert.Equal(t, common.HexToAddress(validatorOptInRouterAddr), mevClient.ValidatorRouterAddress) - assert.Equal(t, common.HexToAddress(providerRegistryAddr), mevClient.BuilderRegistryAddress) + assert.Equal(t, common.HexToAddress(providerRegistryAddr), mevClient.ProviderRegistryAddress) } func TestGetOptInStatusForValidators(t *testing.T) { From 0207cbb13569161b0953446e751466ff93cea1ed Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 11:33:02 -0400 Subject: [PATCH 37/70] chore: name variable correctly --- cmd/housekeeper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/housekeeper.go b/cmd/housekeeper.go index b9bf7f57..87a379b8 100644 --- a/cmd/housekeeper.go +++ b/cmd/housekeeper.go @@ -38,7 +38,7 @@ func init() { housekeeperCmd.Flags().BoolVar(&hkPprofEnabled, "pprof", hkDefaultPprofEnabled, "enable pprof API") housekeeperCmd.Flags().StringVar(&hkPprofListenAddr, "pprof-listen-addr", hkDefaultPprofListenAddr, "listen address for pprof server") - housekeeperCmd.Flags().StringVar(&mevCommitRPC, "mev-commit-rpc", defaultMevCommitRPC, "MEV-Commit RPC endpoint") + housekeeperCmd.Flags().StringVar(&mevCommitRPC, "mev-commit-rpc", defaultMevCommitRPC, "mev-commit-chain RPC endpoint") housekeeperCmd.Flags().StringVar(ðereumL1RPC, "ethereum-l1-rpc", defaultEthereumL1RPC, "Ethereum L1 RPC endpoint") housekeeperCmd.Flags().StringVar(&providerRegistryAddr, "provider-registry-addr", defaultProviderRegistryAddr, "MEV-Commit provider registry contract address") housekeeperCmd.Flags().StringVar(&validatorOptInRouterAddr, "validator-optin-router-addr", defaultValidatorOptInRouterAddr, "MEV-Commit validator opt-in router contract address") From 0ea63662bd5d344f86f0dc6e755e843680386ae3 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 15:25:42 -0400 Subject: [PATCH 38/70] feat: restructure builder monitoring for efficency --- datastore/redis.go | 43 ++++++++------- mevcommitclient/mev_commit_client.go | 82 +++++++++++++++++++++------- services/housekeeper/housekeeper.go | 53 +++++++++++++++++- 3 files changed, 135 insertions(+), 43 deletions(-) diff --git a/datastore/redis.go b/datastore/redis.go index ed8e3dfe..6000484c 100644 --- a/datastore/redis.go +++ b/datastore/redis.go @@ -17,6 +17,7 @@ import ( "github.com/attestantio/go-eth2-client/spec/capella" "github.com/flashbots/go-utils/cli" "github.com/flashbots/mev-boost-relay/common" + "github.com/flashbots/mev-boost-relay/mevcommitclient" "github.com/go-redis/redis/v9" ) @@ -246,39 +247,39 @@ func (r *RedisCache) GetValidatorRegistrationTimestamp(proposerPubkey common.Pub return timestamp, err } -func (r *RedisCache) SetMevCommitBlockBuilders(builders [][]byte) error { +func (r *RedisCache) SetMevCommitBlockBuilder(builder mevcommitclient.MevCommitProvider) error { ctx := context.Background() - pipe := r.client.Pipeline() - // Clear existing set - pipe.Del(ctx, r.keyMevCommitBlockBuilder) - - // Add all builders to the set - for _, builder := range builders { - pipe.SAdd(ctx, r.keyMevCommitBlockBuilder, string(builder)) + jsonBuilder, err := json.Marshal(builder) + if err != nil { + return fmt.Errorf("failed to marshal MevCommitProvider: %w", err) } - // Execute pipeline - _, err := pipe.Exec(ctx) + err = r.client.HSet(ctx, r.keyMevCommitBlockBuilder, builder.Pubkey, string(jsonBuilder)).Err() if err != nil { - return fmt.Errorf("failed to set MEV-Commit block builders: %w", err) + return fmt.Errorf("failed to set MEV-Commit block builder: %w", err) } return nil } -func (r *RedisCache) GetMevCommitBlockBuilders() ([]common.PubkeyHex, error) { +func (r *RedisCache) GetMevCommitBlockBuilders() ([]mevcommitclient.MevCommitProvider, error) { ctx := context.Background() - // Retrieve all members of the set - members, err := r.client.SMembers(ctx, r.keyMevCommitBlockBuilder).Result() + // Retrieve all fields and values from the hash + entries, err := r.client.HGetAll(ctx, r.keyMevCommitBlockBuilder).Result() if err != nil { return nil, fmt.Errorf("failed to get MEV-Commit block builders: %w", err) } - // Convert string slice to PubkeyHex slice - builders := make([]common.PubkeyHex, len(members)) - for i, member := range members { - builders[i] = common.PubkeyHex(member) + // Convert map to MevCommitProvider slice + builders := make([]mevcommitclient.MevCommitProvider, 0, len(entries)) + for _, value := range entries { + var builder mevcommitclient.MevCommitProvider + err := json.Unmarshal([]byte(value), &builder) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal MevCommitProvider: %w", err) + } + builders = append(builders, builder) } return builders, nil @@ -287,10 +288,10 @@ func (r *RedisCache) GetMevCommitBlockBuilders() ([]common.PubkeyHex, error) { func (r *RedisCache) IsMevCommitBlockBuilder(builderPubkey common.PubkeyHex) (bool, error) { ctx := context.Background() - // Check if the builder pubkey exists in the set - exists, err := r.client.SIsMember(ctx, r.keyMevCommitBlockBuilder, builderPubkey.String()).Result() + // Check if the builder pubkey exists in the hash + exists, err := r.client.HExists(ctx, r.keyMevCommitBlockBuilder, builderPubkey.String()).Result() if err != nil { - return false, fmt.Errorf("failed to check if builder is in MEV-Commit block builders set: %w", err) + return false, fmt.Errorf("failed to check if builder is in MEV-Commit block builders hash: %w", err) } return exists, nil diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 4ca9a780..2e768eaf 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -1,32 +1,29 @@ package mevcommitclient import ( + "context" "fmt" "math/big" "strings" - "time" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" - builderRegistry "github.com/primev/mev-commit/contracts-abi/clients/ProviderRegistry" + providerRegistry "github.com/primev/mev-commit/contracts-abi/clients/ProviderRegistry" validatoroptinrouter "github.com/primev/mev-commit/contracts-abi/clients/ValidatorOptInRouter" ) -type BuilderRegisteredEvent struct { - Builder common.Address - Value *big.Int - BlsPublicKey []byte - BlockNumber uint64 - TxHash common.Hash - Timestamp time.Time - IsValid bool +type MevCommitProvider struct { + Pubkey []byte + EOAAddress common.Address } type IMevCommitClient interface { GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) - GetActiveBuilders() ([][]byte, error) + GetActiveBuilders() ([]MevCommitProvider, error) + ListenForActiveBuildersEvents() (<-chan MevCommitProvider, error) + IsBuilderValid(builderAddress common.Address) (bool, error) } type MevCommitClient struct { @@ -35,8 +32,8 @@ type MevCommitClient struct { ValidatorRouterAddress common.Address ProviderRegistryAddress common.Address validatorOptInRouterCaller *validatoroptinrouter.ValidatoroptinrouterCaller - builderRegistryCaller *builderRegistry.ProviderregistryCaller - builderRegistryFilterer *builderRegistry.ProviderregistryFilterer + builderRegistryCaller *providerRegistry.ProviderregistryCaller + builderRegistryFilterer *providerRegistry.ProviderregistryFilterer l1Client *ethclient.Client mevCommitClient *ethclient.Client contractAbi abi.ABI @@ -62,12 +59,12 @@ func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddres return nil, fmt.Errorf("failed to create ValidatorOptInRouter caller: %w", err) } - builderRegistryCaller, err := builderRegistry.NewProviderregistryCaller(ProviderRegistryAddress, mevCommitClient) + builderRegistryCaller, err := providerRegistry.NewProviderregistryCaller(ProviderRegistryAddress, mevCommitClient) if err != nil { return nil, fmt.Errorf("failed to create BuilderRegistry caller: %w", err) } - builderRegistryFilterer, err := builderRegistry.NewProviderregistryFilterer(ProviderRegistryAddress, mevCommitClient) + builderRegistryFilterer, err := providerRegistry.NewProviderregistryFilterer(ProviderRegistryAddress, mevCommitClient) if err != nil { return nil, fmt.Errorf("failed to create BuilderRegistry filterer: %w", err) } @@ -105,7 +102,8 @@ func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, return m.validatorOptInRouterCaller.AreValidatorsOptedIn(opts, pubkeys) } -func (m *MevCommitClient) GetActiveBuilders() ([][]byte, error) { + +func (m *MevCommitClient) GetActiveBuilders() ([]MevCommitProvider, error) { opts := &bind.FilterOpts{ Start: 0, End: nil, // Latest block @@ -117,14 +115,17 @@ func (m *MevCommitClient) GetActiveBuilders() ([][]byte, error) { } defer iterator.Close() - activeBuilderKeys := make([][]byte, 0) + activeBuilders := make([]MevCommitProvider, 0) for iterator.Next() { - isValid, err := m.isBuilderValid(iterator.Event.Provider) + isValid, err := m.IsBuilderValid(iterator.Event.Provider) if err != nil { return nil, fmt.Errorf("failed to check if builder is valid: %w", err) } if isValid { - activeBuilderKeys = append(activeBuilderKeys, iterator.Event.BlsPublicKey) + activeBuilders = append(activeBuilders, MevCommitProvider{ + Pubkey: iterator.Event.BlsPublicKey, + EOAAddress: iterator.Event.Provider, + }) } } @@ -132,10 +133,49 @@ func (m *MevCommitClient) GetActiveBuilders() ([][]byte, error) { return nil, fmt.Errorf("error iterating over ProviderRegistered events: %w", err) } - return activeBuilderKeys, nil + return activeBuilders, nil +} +func (m *MevCommitClient) ListenForActiveBuildersEvents() (<-chan MevCommitProvider, error) { + opts := &bind.WatchOpts{ + Start: nil, // Start from the latest block + Context: context.Background(), + } + + buildersChan := make(chan MevCommitProvider) + eventCh := make(chan *providerRegistry.ProviderregistryProviderRegistered) + sub, err := m.builderRegistryFilterer.WatchProviderRegistered(opts, eventCh, nil) + if err != nil { + return nil, fmt.Errorf("failed to watch ProviderRegistered events: %w", err) + } + + go func() { + defer sub.Unsubscribe() + for { + select { + case err := <-sub.Err(): + fmt.Printf("error while watching ProviderRegistered events: %v\n", err) + close(eventCh) + return + case event := <-eventCh: + isValid, err := m.IsBuilderValid(event.Provider) + if err != nil { + fmt.Printf("failed to check if builder is valid: %v\n", err) + continue + } + if isValid { + buildersChan <- MevCommitProvider{ + Pubkey: event.BlsPublicKey, + EOAAddress: event.Provider, + } + } + } + } + }() + + return buildersChan, nil } -func (m *MevCommitClient) isBuilderValid(builderAddress common.Address) (bool, error) { +func (m *MevCommitClient) IsBuilderValid(builderAddress common.Address) (bool, error) { err := m.builderRegistryCaller.IsProviderValid(nil, builderAddress) if err != nil { if err.Error() == "execution reverted" { diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index 21142b98..5dae708b 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -8,6 +8,7 @@ package housekeeper import ( + "context" "errors" "net/http" _ "net/http/pprof" @@ -98,6 +99,7 @@ func (hk *Housekeeper) Start() (err error) { // Start initial tasks go hk.updateValidatorRegistrationsInRedis() + go hk.monitorMevCommitBuilderRegistrations() // Process the current slot hk.processNewSlot(bestSyncStatus.HeadSlot) @@ -148,7 +150,7 @@ func (hk *Housekeeper) processNewSlot(headSlot uint64) { // Update proposer duties go hk.updateProposerDuties(headSlot) go hk.updateMevCommitValidatorRegistrations(headSlot) - go hk.updateMevCommitBuilderRegistrations(headSlot) + go hk.cleanupMevCommitBuilderRegistrations() // Set headSlot in redis (for the website) err := hk.redis.SetStats(datastore.RedisStatsFieldLatestSlot, headSlot) @@ -178,6 +180,55 @@ func (hk *Housekeeper) updateProposerDuties(headSlot uint64) { hk.UpdateProposerDutiesWithoutChecks(headSlot) } +func (hk *Housekeeper) monitorMevCommitBuilderRegistrations() { + newBuilderRegistered, err := hk.mevCommitClient.SubscribeToBuilderRegisteredEvents(context.Background()) + if err != nil { + hk.log.WithError(err).Error("failed to subscribe to MEV-Commit builder registered events") + return + } + + for { + builder := <-newBuilderRegistered + hk.log.WithField("builder", builder).Info("new builder registered") + err := hk.redis.SetMevCommitBlockBuilder(builder) + if err != nil { + hk.log.WithError(err).Error("failed to set MEV-Commit builder registration") + } + } +} + +func (hk *Housekeeper) cleanupMevCommitBuilderRegistrations() { + entries, err := hk.redis.GetMevCommitBlockBuilders() + if err != nil { + hk.log.WithError(err).Error("failed to get MEV-Commit block builders from Redis") + return + } + + pipe := hk.redis.NewPipeline() + for _, builder := range entries { + isRegistered, err := hk.mevCommitClient.IsBuilderValid(builder.EOAAddress) + if err != nil { + hk.log.WithError(err).Errorf("failed to check if builder %s is registered", builder.Pubkey) + continue + } + if !isRegistered { + err := hk.redis.DeleteMevCommitValidatorRegistration(common.PubkeyHex(builder.Pubkey)) + if err != nil { + hk.log.WithError(err).Errorf("failed to delete MEV-Commit validator registration for builder %s", builder.Pubkey) + } else { + hk.log.WithField("builder", builder.Pubkey).Info("deleted MEV-Commit validator registration for inactive builder") + } + } + } + + _, err = pipe.Exec(context.Background()) + if err != nil { + hk.log.WithError(err).Error("failed to execute Redis pipeline for cleanup") + } + + hk.log.Info("completed cleanup of MEV-Commit builder registrations") +} + func (hk *Housekeeper) updateMevCommitBuilderRegistrations(headSlot uint64) { log := hk.log.WithField("headSlot", headSlot) log.Debug("updating MEV-Commit builder registrations...") From 1e1c94d484ffcdda3afcbcf90527757e3d75ec06 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 15:41:59 -0400 Subject: [PATCH 39/70] chore: ensures tests still work --- datastore/redis_test.go | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/datastore/redis_test.go b/datastore/redis_test.go index 13a76e74..887bce93 100644 --- a/datastore/redis_test.go +++ b/datastore/redis_test.go @@ -15,7 +15,9 @@ import ( "github.com/attestantio/go-eth2-client/spec" "github.com/attestantio/go-eth2-client/spec/bellatrix" "github.com/attestantio/go-eth2-client/spec/phase0" + gethCommon "github.com/ethereum/go-ethereum/common" "github.com/flashbots/mev-boost-relay/common" + "github.com/flashbots/mev-boost-relay/mevcommitclient" "github.com/go-redis/redis/v9" "github.com/holiman/uint256" "github.com/stretchr/testify/require" @@ -443,19 +445,24 @@ func TestPipelineNilCheck(t *testing.T) { require.NoError(t, err) require.Equal(t, big.NewInt(0), f) } - func TestSetMevCommitBlockBuilders(t *testing.T) { cache := setupTestRedis(t) builderPubkey := "0xfa1ed37c3553d0ce1e9349b2c5063cf6e394d231c8d3e0df75e9462257c081543086109ffddaacc0aa76f33dc9661c83" // Set a commit block builder - err := cache.SetMevCommitBlockBuilders([][]byte{[]byte(builderPubkey)}) + builder := mevcommitclient.MevCommitProvider{ + Pubkey: []byte(builderPubkey), + EOAAddress: gethCommon.HexToAddress("0x0000000000000000000000000000000000000000"), + } + err := cache.SetMevCommitBlockBuilder(builder) require.NoError(t, err) + // Retrieve the list of MEV-Commit block builders builders, err := cache.GetMevCommitBlockBuilders() require.NoError(t, err) require.Len(t, builders, 1) - require.Equal(t, common.PubkeyHex(builderPubkey), builders[0]) + require.Equal(t, builder, builders[0]) + require.Equal(t, builderPubkey, string(builders[0].Pubkey)) // Check if the commit block builder is set correctly isSet, err := cache.IsMevCommitBlockBuilder(common.PubkeyHex(builderPubkey)) From 0ce89a5da4e6a8b1848e7957904067400bf3f113 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 15:43:20 -0400 Subject: [PATCH 40/70] chore: cleans up old appraoch to monitoring builders --- services/housekeeper/housekeeper.go | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index 5dae708b..ae508f33 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -181,7 +181,7 @@ func (hk *Housekeeper) updateProposerDuties(headSlot uint64) { } func (hk *Housekeeper) monitorMevCommitBuilderRegistrations() { - newBuilderRegistered, err := hk.mevCommitClient.SubscribeToBuilderRegisteredEvents(context.Background()) + newBuilderRegistered, err := hk.mevCommitClient.ListenForActiveBuildersEvents() if err != nil { hk.log.WithError(err).Error("failed to subscribe to MEV-Commit builder registered events") return @@ -229,24 +229,6 @@ func (hk *Housekeeper) cleanupMevCommitBuilderRegistrations() { hk.log.Info("completed cleanup of MEV-Commit builder registrations") } -func (hk *Housekeeper) updateMevCommitBuilderRegistrations(headSlot uint64) { - log := hk.log.WithField("headSlot", headSlot) - log.Debug("updating MEV-Commit builder registrations...") - - // Fetch all registered builders from the MEV-Commit contract - registeredBuilders, err := hk.mevCommitClient.GetActiveBuilders() - if err != nil { - log.WithError(err).Error("failed to get registered builders from MEV-Commit contract") - return - } - err = hk.redis.SetMevCommitBlockBuilders(registeredBuilders) - if err != nil { - log.WithError(err).Error("failed to set MEV-Commit builder registrations") - return - } - log.WithField("count", len(registeredBuilders)).Info("updated MEV-Commit builder registrations") -} - func (hk *Housekeeper) UpdateProposerDutiesWithoutChecks(headSlot uint64) { epoch := headSlot / common.SlotsPerEpoch From 1aa80bb392dddbbc7518440228dffe73a74d5c90 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 15:45:48 -0400 Subject: [PATCH 41/70] nit: cleanup --- services/housekeeper/housekeeper.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index ae508f33..b7fa4036 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -8,7 +8,6 @@ package housekeeper import ( - "context" "errors" "net/http" _ "net/http/pprof" @@ -204,7 +203,6 @@ func (hk *Housekeeper) cleanupMevCommitBuilderRegistrations() { return } - pipe := hk.redis.NewPipeline() for _, builder := range entries { isRegistered, err := hk.mevCommitClient.IsBuilderValid(builder.EOAAddress) if err != nil { @@ -221,11 +219,6 @@ func (hk *Housekeeper) cleanupMevCommitBuilderRegistrations() { } } - _, err = pipe.Exec(context.Background()) - if err != nil { - hk.log.WithError(err).Error("failed to execute Redis pipeline for cleanup") - } - hk.log.Info("completed cleanup of MEV-Commit builder registrations") } From 52410bf0a02f63a73bfc00f8cf4c68c407190c6a Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 16:11:21 -0400 Subject: [PATCH 42/70] chore: move time start for monitoring to top level --- services/api/service.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/services/api/service.go b/services/api/service.go index d59cfb14..a1da7186 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1740,6 +1740,7 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr } if api.opts.MevCommitFiltering { + start := time.Now() // Find the duty for the submission slot api.proposerDutiesLock.RLock() duty := api.proposerDutiesMap[submission.BidTrace.Slot] @@ -1750,8 +1751,6 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr return false } - // Check if validator is registered - start := time.Now() isValidatorRegistered, err := api.datastore.IsMevCommitValidatorRegistered(common.NewPubkeyHex(duty.Entry.Message.Pubkey.String())) if err != nil { log.WithError(err).Error("Failed to check validator registration") From ece5972d0833ef96706cc8d960ec5c91f633dcf4 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 9 Oct 2024 16:11:50 -0400 Subject: [PATCH 43/70] nit: reduce log level --- services/api/service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api/service.go b/services/api/service.go index a1da7186..e62e1c89 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1772,7 +1772,7 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr } } duration := time.Since(start) - log.WithField("duration", duration).Info("MEV-Commit check completed") + log.WithField("duration", duration).Trace("MEV-Commit check completed") } // Timestamp check From 5314d2846aac9f18f81d5733668bb5533f02c159 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Fri, 11 Oct 2024 11:03:47 -0400 Subject: [PATCH 44/70] chore: removes legacy getbuilders --- mevcommitclient/mev_commit_client.go | 33 ----------------------- mevcommitclient/mev_commit_client_test.go | 20 -------------- 2 files changed, 53 deletions(-) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 2e768eaf..ecadd861 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -21,7 +21,6 @@ type MevCommitProvider struct { type IMevCommitClient interface { GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) - GetActiveBuilders() ([]MevCommitProvider, error) ListenForActiveBuildersEvents() (<-chan MevCommitProvider, error) IsBuilderValid(builderAddress common.Address) (bool, error) } @@ -103,38 +102,6 @@ func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, return m.validatorOptInRouterCaller.AreValidatorsOptedIn(opts, pubkeys) } -func (m *MevCommitClient) GetActiveBuilders() ([]MevCommitProvider, error) { - opts := &bind.FilterOpts{ - Start: 0, - End: nil, // Latest block - } - - iterator, err := m.builderRegistryFilterer.FilterProviderRegistered(opts, nil) - if err != nil { - return nil, fmt.Errorf("failed to filter ProviderRegistered events: %w", err) - } - defer iterator.Close() - - activeBuilders := make([]MevCommitProvider, 0) - for iterator.Next() { - isValid, err := m.IsBuilderValid(iterator.Event.Provider) - if err != nil { - return nil, fmt.Errorf("failed to check if builder is valid: %w", err) - } - if isValid { - activeBuilders = append(activeBuilders, MevCommitProvider{ - Pubkey: iterator.Event.BlsPublicKey, - EOAAddress: iterator.Event.Provider, - }) - } - } - - if err := iterator.Error(); err != nil { - return nil, fmt.Errorf("error iterating over ProviderRegistered events: %w", err) - } - - return activeBuilders, nil -} func (m *MevCommitClient) ListenForActiveBuildersEvents() (<-chan MevCommitProvider, error) { opts := &bind.WatchOpts{ Start: nil, // Start from the latest block diff --git a/mevcommitclient/mev_commit_client_test.go b/mevcommitclient/mev_commit_client_test.go index d05de7cc..b02c716a 100644 --- a/mevcommitclient/mev_commit_client_test.go +++ b/mevcommitclient/mev_commit_client_test.go @@ -59,23 +59,3 @@ func TestGetOptInStatusForValidators(t *testing.T) { assert.IsType(t, bool(true), status) } } - -func TestGetActiveBuilders(t *testing.T) { - client, err := NewMevCommitClient( - ethereumL1RPC, - mevCommitRPC, - common.HexToAddress(validatorOptInRouterAddr), - common.HexToAddress(providerRegistryAddr), - ) - require.NoError(t, err) - - builders, err := client.GetActiveBuilders() - require.NoError(t, err) - - assert.NotEmpty(t, builders, "There should be at least one active builder") - for _, builder := range builders { - assert.Len(t, builder, 48, "Builder BLS public key should be 48 bytes long") - } - - assert.IsType(t, [][]byte{}, builders) -} From 550bdcc8b2ad1e3aeed847566bb12dcc6bb314eb Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Fri, 11 Oct 2024 11:38:41 -0400 Subject: [PATCH 45/70] chore: clean up code and fix anti-pattern --- cmd/housekeeper.go | 6 +++--- datastore/datastore.go | 8 ++++---- datastore/redis.go | 16 ++++++++-------- datastore/redis_test.go | 2 +- mevcommitclient/mev_commit_client.go | 2 +- services/api/service.go | 2 +- services/housekeeper/housekeeper.go | 21 +++++++++++---------- 7 files changed, 29 insertions(+), 28 deletions(-) diff --git a/cmd/housekeeper.go b/cmd/housekeeper.go index 87a379b8..4a5f1c1a 100644 --- a/cmd/housekeeper.go +++ b/cmd/housekeeper.go @@ -40,8 +40,8 @@ func init() { housekeeperCmd.Flags().StringVar(&mevCommitRPC, "mev-commit-rpc", defaultMevCommitRPC, "mev-commit-chain RPC endpoint") housekeeperCmd.Flags().StringVar(ðereumL1RPC, "ethereum-l1-rpc", defaultEthereumL1RPC, "Ethereum L1 RPC endpoint") - housekeeperCmd.Flags().StringVar(&providerRegistryAddr, "provider-registry-addr", defaultProviderRegistryAddr, "MEV-Commit provider registry contract address") - housekeeperCmd.Flags().StringVar(&validatorOptInRouterAddr, "validator-optin-router-addr", defaultValidatorOptInRouterAddr, "MEV-Commit validator opt-in router contract address") + housekeeperCmd.Flags().StringVar(&providerRegistryAddr, "provider-registry-addr", defaultProviderRegistryAddr, "mev-commit provider registry contract address") + housekeeperCmd.Flags().StringVar(&validatorOptInRouterAddr, "validator-optin-router-addr", defaultValidatorOptInRouterAddr, "mev-commit validator opt-in router contract address") } var housekeeperCmd = &cobra.Command{ @@ -98,7 +98,7 @@ var housekeeperCmd = &cobra.Command{ gethCommon.HexToAddress(providerRegistryAddr), ) if err != nil { - log.WithError(err).Fatal("Failed to create MEV-Commit client") + log.WithError(err).Fatal("Failed to create mev-commit client") } opts := &housekeeper.HousekeeperOpts{ diff --git a/datastore/datastore.go b/datastore/datastore.go index c2853a53..b773fa30 100644 --- a/datastore/datastore.go +++ b/datastore/datastore.go @@ -184,21 +184,21 @@ func (ds *Datastore) SetKnownValidator(pubkeyHex common.PubkeyHex, index uint64) ds.knownValidatorsByIndex[index] = pubkeyHex } -// SaveMevCommitValidatorRegistration saves a validator registration for MEV-Commit into Redis +// SaveMevCommitValidatorRegistration saves a validator registration for mev-commit into Redis func (ds *Datastore) SaveMevCommitValidatorRegistration(pubkeyHex common.PubkeyHex) error { err := ds.redis.SetMevCommitValidatorRegistration(pubkeyHex) if err != nil { - return errors.Wrap(err, "failed saving MEV-Commit validator registration to redis") + return errors.Wrap(err, "failed saving mev-commit validator registration to redis") } return nil } -// IsMevCommitRegisteredValidator checks if a validator is registered for MEV-Commit +// IsMevCommitRegisteredValidator checks if a validator is registered for mev-commit func (ds *Datastore) IsMevCommitValidatorRegistered(pubkeyHex common.PubkeyHex) (bool, error) { return ds.redis.IsMevCommitValidatorRegistered(pubkeyHex) } -// IsMevCommitBlockBuilder checks if a builder is registered for MEV-Commit +// IsMevCommitBlockBuilder checks if a builder is registered for mev-commit func (ds *Datastore) IsMevCommitBlockBuilder(builderPubkey common.PubkeyHex) (bool, error) { return ds.redis.IsMevCommitBlockBuilder(builderPubkey) } diff --git a/datastore/redis.go b/datastore/redis.go index 6000484c..7b81d8c7 100644 --- a/datastore/redis.go +++ b/datastore/redis.go @@ -98,7 +98,7 @@ type RedisCache struct { // keys keyValidatorRegistrationTimestamp string keyMevCommitValidatorRegistrationHash string - keyMevCommitBlockBuilder string // New key for MEV-Commit block builder array + keyMevCommitBlockBuilder string // New key for mev-commit block builder array keyRelayConfig string keyStats string @@ -140,7 +140,7 @@ func NewRedisCache(prefix, redisURI, readonlyURI string) (*RedisCache, error) { keyValidatorRegistrationTimestamp: fmt.Sprintf("%s/%s:validator-registration-timestamp", redisPrefix, prefix), keyMevCommitValidatorRegistrationHash: fmt.Sprintf("%s/%s:mev-commit-validator-registration", redisPrefix, prefix), - keyMevCommitBlockBuilder: fmt.Sprintf("%s/%s:mev-commit-block-builder", redisPrefix, prefix), // New key for MEV-Commit block builder array + keyMevCommitBlockBuilder: fmt.Sprintf("%s/%s:mev-commit-block-builder", redisPrefix, prefix), // New key for mev-commit block builder array keyRelayConfig: fmt.Sprintf("%s/%s:relay-config", redisPrefix, prefix), keyStats: fmt.Sprintf("%s/%s:stats", redisPrefix, prefix), @@ -256,7 +256,7 @@ func (r *RedisCache) SetMevCommitBlockBuilder(builder mevcommitclient.MevCommitP } err = r.client.HSet(ctx, r.keyMevCommitBlockBuilder, builder.Pubkey, string(jsonBuilder)).Err() if err != nil { - return fmt.Errorf("failed to set MEV-Commit block builder: %w", err) + return fmt.Errorf("failed to set mev-commit block builder: %w", err) } return nil @@ -268,7 +268,7 @@ func (r *RedisCache) GetMevCommitBlockBuilders() ([]mevcommitclient.MevCommitPro // Retrieve all fields and values from the hash entries, err := r.client.HGetAll(ctx, r.keyMevCommitBlockBuilder).Result() if err != nil { - return nil, fmt.Errorf("failed to get MEV-Commit block builders: %w", err) + return nil, fmt.Errorf("failed to get mev-commit block builders: %w", err) } // Convert map to MevCommitProvider slice @@ -291,7 +291,7 @@ func (r *RedisCache) IsMevCommitBlockBuilder(builderPubkey common.PubkeyHex) (bo // Check if the builder pubkey exists in the hash exists, err := r.client.HExists(ctx, r.keyMevCommitBlockBuilder, builderPubkey.String()).Result() if err != nil { - return false, fmt.Errorf("failed to check if builder is in MEV-Commit block builders hash: %w", err) + return false, fmt.Errorf("failed to check if builder is in mev-commit block builders hash: %w", err) } return exists, nil @@ -300,7 +300,7 @@ func (r *RedisCache) IsMevCommitBlockBuilder(builderPubkey common.PubkeyHex) (bo func (r *RedisCache) SetMevCommitValidatorRegistration(proposerPubkey common.PubkeyHex) error { err := r.client.Set(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+proposerPubkey.String(), "1", mevCommitValidatorRegistrationExpiry).Err() if err != nil { - return fmt.Errorf("failed to add validator to MEV-Commit registration: %w", err) + return fmt.Errorf("failed to add validator to mev-commit registration: %w", err) } return nil } @@ -311,7 +311,7 @@ func (r *RedisCache) IsMevCommitValidatorRegistered(proposerPubkey common.Pubkey return false, nil } if err != nil { - return false, fmt.Errorf("failed to check MEV-Commit validator registration: %w", err) + return false, fmt.Errorf("failed to check mev-commit validator registration: %w", err) } return true, nil @@ -320,7 +320,7 @@ func (r *RedisCache) IsMevCommitValidatorRegistered(proposerPubkey common.Pubkey func (r *RedisCache) DeleteMevCommitValidatorRegistration(proposerPubkey common.PubkeyHex) error { err := r.client.Del(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+proposerPubkey.String()).Err() if err != nil { - return fmt.Errorf("failed to remove validator from MEV-Commit registration: %w", err) + return fmt.Errorf("failed to remove validator from mev-commit registration: %w", err) } return nil } diff --git a/datastore/redis_test.go b/datastore/redis_test.go index 887bce93..469882f4 100644 --- a/datastore/redis_test.go +++ b/datastore/redis_test.go @@ -457,7 +457,7 @@ func TestSetMevCommitBlockBuilders(t *testing.T) { err := cache.SetMevCommitBlockBuilder(builder) require.NoError(t, err) - // Retrieve the list of MEV-Commit block builders + // Retrieve the list of mev-commit block builders builders, err := cache.GetMevCommitBlockBuilders() require.NoError(t, err) require.Len(t, builders, 1) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index ecadd861..69f60d98 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -50,7 +50,7 @@ func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddres mevCommitClient, err := ethclient.Dial(mevCommitUrl) if err != nil { - return nil, fmt.Errorf("failed to connect to MEV-Commit EVM: %w", err) + return nil, fmt.Errorf("failed to connect to mev-commit EVM: %w", err) } validatorOptInRouter, err := validatoroptinrouter.NewValidatoroptinrouterCaller(validatorRouterAddress, l1Client) diff --git a/services/api/service.go b/services/api/service.go index e62e1c89..8f1494dd 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1772,7 +1772,7 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr } } duration := time.Since(start) - log.WithField("duration", duration).Trace("MEV-Commit check completed") + log.WithField("duration", duration).Trace("mev-commit check completed") } // Timestamp check diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index b7fa4036..c9c970cb 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -182,24 +182,25 @@ func (hk *Housekeeper) updateProposerDuties(headSlot uint64) { func (hk *Housekeeper) monitorMevCommitBuilderRegistrations() { newBuilderRegistered, err := hk.mevCommitClient.ListenForActiveBuildersEvents() if err != nil { - hk.log.WithError(err).Error("failed to subscribe to MEV-Commit builder registered events") + hk.log.WithError(err).Error("failed to subscribe to mev-commit builder registered events") return } - for { - builder := <-newBuilderRegistered + for builder := range newBuilderRegistered { hk.log.WithField("builder", builder).Info("new builder registered") err := hk.redis.SetMevCommitBlockBuilder(builder) if err != nil { - hk.log.WithError(err).Error("failed to set MEV-Commit builder registration") + hk.log.WithError(err).Error("failed to set mev-commit builder registration") } } + + hk.log.Info("mev-commit builder registration monitoring stopped") } func (hk *Housekeeper) cleanupMevCommitBuilderRegistrations() { entries, err := hk.redis.GetMevCommitBlockBuilders() if err != nil { - hk.log.WithError(err).Error("failed to get MEV-Commit block builders from Redis") + hk.log.WithError(err).Error("failed to get mev-commit block builders from Redis") return } @@ -212,14 +213,14 @@ func (hk *Housekeeper) cleanupMevCommitBuilderRegistrations() { if !isRegistered { err := hk.redis.DeleteMevCommitValidatorRegistration(common.PubkeyHex(builder.Pubkey)) if err != nil { - hk.log.WithError(err).Errorf("failed to delete MEV-Commit validator registration for builder %s", builder.Pubkey) + hk.log.WithError(err).Errorf("failed to delete mev-commit validator registration for builder %s", builder.Pubkey) } else { - hk.log.WithField("builder", builder.Pubkey).Info("deleted MEV-Commit validator registration for inactive builder") + hk.log.WithField("builder", builder.Pubkey).Info("deleted mev-commit validator registration for inactive builder") } } } - hk.log.Info("completed cleanup of MEV-Commit builder registrations") + hk.log.Info("completed cleanup of mev-commit builder registrations") } func (hk *Housekeeper) UpdateProposerDutiesWithoutChecks(headSlot uint64) { @@ -329,7 +330,7 @@ func (hk *Housekeeper) updateMevCommitValidatorRegistrations(headSlot uint64) { registeredValidators, err := hk.mevCommitClient.GetOptInStatusForValidators(pubkeys) if err != nil { - hk.log.WithError(err).Error("failed to get registered validators from MEV-Commit client") + hk.log.WithError(err).Error("failed to get registered validators from mev-commit client") return } for i, registeredValidator := range registeredValidators { @@ -338,7 +339,7 @@ func (hk *Housekeeper) updateMevCommitValidatorRegistrations(headSlot uint64) { } } - hk.log.WithField("numValidators", len(registeredValidators)).Info("updated MEV-Commit registered validators in Redis") + hk.log.WithField("numValidators", len(registeredValidators)).Info("updated mev-commit registered validators in Redis") } // updateValidatorRegistrationsInRedis saves all latest validator registrations from the database to Redis From 03b13c16d2f4f53adc7862f2dace041ff9023523 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Fri, 11 Oct 2024 14:02:02 -0400 Subject: [PATCH 46/70] feat: track slashes --- mevcommitclient/mev_commit_client.go | 54 +++++++++++++++++++++------- services/housekeeper/housekeeper.go | 31 ++++++++++++---- 2 files changed, 67 insertions(+), 18 deletions(-) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 69f60d98..afb0f982 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -21,7 +21,7 @@ type MevCommitProvider struct { type IMevCommitClient interface { GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) - ListenForActiveBuildersEvents() (<-chan MevCommitProvider, error) + ListenForBuildersEvents() (<-chan MevCommitProvider, <-chan common.Address, error) IsBuilderValid(builderAddress common.Address) (bool, error) } @@ -102,35 +102,44 @@ func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, return m.validatorOptInRouterCaller.AreValidatorsOptedIn(opts, pubkeys) } -func (m *MevCommitClient) ListenForActiveBuildersEvents() (<-chan MevCommitProvider, error) { +func (m *MevCommitClient) ListenForBuildersEvents() (<-chan MevCommitProvider, <-chan common.Address, error) { opts := &bind.WatchOpts{ Start: nil, // Start from the latest block Context: context.Background(), } + builderRegistryEventCh := make(chan MevCommitProvider) + builderUnregisteredEventCh := make(chan common.Address) - buildersChan := make(chan MevCommitProvider) - eventCh := make(chan *providerRegistry.ProviderregistryProviderRegistered) - sub, err := m.builderRegistryFilterer.WatchProviderRegistered(opts, eventCh, nil) + providerRegisteredEventCh := make(chan *providerRegistry.ProviderregistryProviderRegistered) + providerSlashedEventCh := make(chan *providerRegistry.ProviderregistryFundsSlashed) + + providerRegisteredSub, err := m.builderRegistryFilterer.WatchProviderRegistered(opts, providerRegisteredEventCh, nil) if err != nil { - return nil, fmt.Errorf("failed to watch ProviderRegistered events: %w", err) + return nil, nil, fmt.Errorf("failed to watch ProviderRegistered events: %w", err) + } + + providerSlashedSub, err := m.builderRegistryFilterer.WatchFundsSlashed(opts, providerSlashedEventCh, nil) + if err != nil { + providerRegisteredSub.Unsubscribe() + return nil, nil, fmt.Errorf("failed to watch ProviderSlashed events: %w", err) } go func() { - defer sub.Unsubscribe() + defer providerRegisteredSub.Unsubscribe() for { select { - case err := <-sub.Err(): + case err := <-providerRegisteredSub.Err(): fmt.Printf("error while watching ProviderRegistered events: %v\n", err) - close(eventCh) + close(builderRegistryEventCh) return - case event := <-eventCh: + case event := <-providerRegisteredEventCh: isValid, err := m.IsBuilderValid(event.Provider) if err != nil { fmt.Printf("failed to check if builder is valid: %v\n", err) continue } if isValid { - buildersChan <- MevCommitProvider{ + builderRegistryEventCh <- MevCommitProvider{ Pubkey: event.BlsPublicKey, EOAAddress: event.Provider, } @@ -139,7 +148,28 @@ func (m *MevCommitClient) ListenForActiveBuildersEvents() (<-chan MevCommitProvi } }() - return buildersChan, nil + go func() { + defer providerSlashedSub.Unsubscribe() + for { + select { + case err := <-providerSlashedSub.Err(): + fmt.Printf("error while watching ProviderSlashed events: %v\n", err) + close(builderUnregisteredEventCh) + return + case event := <-providerSlashedEventCh: + isValid, err := m.IsBuilderValid(event.Provider) + if err != nil { + fmt.Printf("failed to check if builder is valid: %v\n", err) + continue + } + if !isValid { + builderUnregisteredEventCh <- event.Provider + } + } + } + }() + + return builderRegistryEventCh, builderUnregisteredEventCh, nil } func (m *MevCommitClient) IsBuilderValid(builderAddress common.Address) (bool, error) { diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index c9c970cb..2eb0d8a5 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -180,17 +180,36 @@ func (hk *Housekeeper) updateProposerDuties(headSlot uint64) { } func (hk *Housekeeper) monitorMevCommitBuilderRegistrations() { - newBuilderRegistered, err := hk.mevCommitClient.ListenForActiveBuildersEvents() + newBuilderRegistered, builderUnregistered, err := hk.mevCommitClient.ListenForBuildersEvents() if err != nil { hk.log.WithError(err).Error("failed to subscribe to mev-commit builder registered events") return } - for builder := range newBuilderRegistered { - hk.log.WithField("builder", builder).Info("new builder registered") - err := hk.redis.SetMevCommitBlockBuilder(builder) - if err != nil { - hk.log.WithError(err).Error("failed to set mev-commit builder registration") + for { + select { + case builder := <-newBuilderRegistered: + hk.log.WithField("builder", builder).Info("new builder registered") + err := hk.redis.SetMevCommitBlockBuilder(builder) + if err != nil { + hk.log.WithError(err).Error("failed to set mev-commit builder registration") + } + case builderAddress := <-builderUnregistered: + entries, err := hk.redis.GetMevCommitBlockBuilders() + if err != nil { + hk.log.WithError(err).Error("failed to get mev-commit block builders from Redis") + return + } + for _, entry := range entries { + if entry.EOAAddress == builderAddress { + hk.log.WithField("builder", builderAddress).Info("builder unregistered") + err := hk.redis.DeleteMevCommitValidatorRegistration(common.PubkeyHex(entry.Pubkey)) + if err != nil { + hk.log.WithError(err).Errorf("failed to delete mev-commit block builder %s", builderAddress) + } + break + } + } } } From 941ba64496193e6391d18b54145e4b78ebb1e50f Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Fri, 11 Oct 2024 15:04:31 -0400 Subject: [PATCH 47/70] nit: made changes event registration checks --- mevcommitclient/mev_commit_client.go | 16 +++++----------- services/housekeeper/housekeeper.go | 2 -- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index afb0f982..05891386 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -103,8 +103,9 @@ func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, } func (m *MevCommitClient) ListenForBuildersEvents() (<-chan MevCommitProvider, <-chan common.Address, error) { + startBlock := uint64(0) opts := &bind.WatchOpts{ - Start: nil, // Start from the latest block + Start: &startBlock, // Start from the latest block Context: context.Background(), } builderRegistryEventCh := make(chan MevCommitProvider) @@ -133,16 +134,9 @@ func (m *MevCommitClient) ListenForBuildersEvents() (<-chan MevCommitProvider, < close(builderRegistryEventCh) return case event := <-providerRegisteredEventCh: - isValid, err := m.IsBuilderValid(event.Provider) - if err != nil { - fmt.Printf("failed to check if builder is valid: %v\n", err) - continue - } - if isValid { - builderRegistryEventCh <- MevCommitProvider{ - Pubkey: event.BlsPublicKey, - EOAAddress: event.Provider, - } + builderRegistryEventCh <- MevCommitProvider{ + Pubkey: event.BlsPublicKey, + EOAAddress: event.Provider, } } } diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index 2eb0d8a5..72e595d6 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -212,8 +212,6 @@ func (hk *Housekeeper) monitorMevCommitBuilderRegistrations() { } } } - - hk.log.Info("mev-commit builder registration monitoring stopped") } func (hk *Housekeeper) cleanupMevCommitBuilderRegistrations() { From aa56c412a7d0e9a432aa35e4fc785baf3d4f5a92 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 13 Oct 2024 20:35:42 -0400 Subject: [PATCH 48/70] nit: remove gitignore changes --- .gitignore | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index a405d827..68f41fa9 100644 --- a/.gitignore +++ b/.gitignore @@ -24,5 +24,4 @@ .DS_Store /website-index.html /README.internal.md -/internal/_investigations/ -vendor* \ No newline at end of file +/internal/_investigations/ \ No newline at end of file From 6dcb0f54986812441a8112db5512685bc43299e8 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 13 Oct 2024 20:37:24 -0400 Subject: [PATCH 49/70] nit: remove change in database.go --- database/database.go | 1 + 1 file changed, 1 insertion(+) diff --git a/database/database.go b/database/database.go index dbb1b62f..1df6a3dd 100644 --- a/database/database.go +++ b/database/database.go @@ -26,6 +26,7 @@ type IDatabaseService interface { GetLatestValidatorRegistrations(timestampOnly bool) ([]*ValidatorRegistrationEntry, error) GetValidatorRegistration(pubkey string) (*ValidatorRegistrationEntry, error) GetValidatorRegistrationsForPubkeys(pubkeys []string) ([]*ValidatorRegistrationEntry, error) + SaveBuilderBlockSubmission(payload *common.VersionedSubmitBlockRequest, requestError, validationError error, receivedAt, eligibleAt time.Time, wasSimulated, saveExecPayload bool, profile common.Profile, optimisticSubmission bool, blockValue *uint256.Int) (entry *BuilderBlockSubmissionEntry, err error) GetBlockSubmissionEntry(slot uint64, proposerPubkey, blockHash string) (entry *BuilderBlockSubmissionEntry, err error) GetBuilderSubmissions(filters GetBuilderSubmissionsFilters) ([]*BuilderBlockSubmissionEntry, error) From 866c4ac00d01a4eb9667ee0acd3118f568378f7e Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 13 Oct 2024 20:38:21 -0400 Subject: [PATCH 50/70] chore: removes all db related changes --- database/types.go | 6 ------ database/vars/tables.go | 1 - 2 files changed, 7 deletions(-) diff --git a/database/types.go b/database/types.go index 5eda345c..25470141 100644 --- a/database/types.go +++ b/database/types.go @@ -62,12 +62,6 @@ type ValidatorRegistrationEntry struct { Signature string `db:"signature"` } -type MevCommitValidatorEntry struct { - ID int64 `db:"id"` - Pubkey string `db:"pubkey"` - Timestamp time.Time `db:"timestamp"` -} - func (reg ValidatorRegistrationEntry) ToSignedValidatorRegistration() (*builderApiV1.SignedValidatorRegistration, error) { pubkey, err := utils.HexToPubkey(reg.Pubkey) if err != nil { diff --git a/database/vars/tables.go b/database/vars/tables.go index 46d90a6f..68e496cf 100644 --- a/database/vars/tables.go +++ b/database/vars/tables.go @@ -15,5 +15,4 @@ var ( TableBuilderDemotions = tableBase + "_builder_demotions" TableBlockedValidator = tableBase + "_blocked_validator" TableTooLateGetPayload = tableBase + "_too_late_get_payload" - TableMevCommitValidators = tableBase + "_mev_commit_validators" ) From f3cb4f141384beb61a2cc1597eaf421c598e5c11 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 13 Oct 2024 20:39:50 -0400 Subject: [PATCH 51/70] nit: remove redundant todo --- services/api/service.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/api/service.go b/services/api/service.go index 8f1494dd..3a30c7b6 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -2053,7 +2053,7 @@ func (api *RelayAPI) handleSubmitNewBlock(w http.ResponseWriter, req *http.Reque "excessBlobGas": payload.Deneb.ExecutionPayload.ExcessBlobGas, }) } - // TODO: Need to update this endpoint to reject requests with a unregistered builder pubkey for a target slot + ok := api.checkSubmissionSlotDetails(w, log, headSlot, payload, submission) if !ok { return From dd5f08e38e5e38d30a3e8a2ed8aa3cbe6d4b44a3 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 13 Oct 2024 20:59:23 -0400 Subject: [PATCH 52/70] chore: remove redundant validator deletion --- datastore/redis.go | 14 ++++++-------- services/housekeeper/housekeeper.go | 4 ++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/datastore/redis.go b/datastore/redis.go index 7b81d8c7..23ed5e90 100644 --- a/datastore/redis.go +++ b/datastore/redis.go @@ -297,6 +297,12 @@ func (r *RedisCache) IsMevCommitBlockBuilder(builderPubkey common.PubkeyHex) (bo return exists, nil } +func (r *RedisCache) DeleteMevCommitBlockBuilder(builderPubkey common.PubkeyHex) error { + ctx := context.Background() + + return r.client.HDel(ctx, r.keyMevCommitBlockBuilder, builderPubkey.String()).Err() +} + func (r *RedisCache) SetMevCommitValidatorRegistration(proposerPubkey common.PubkeyHex) error { err := r.client.Set(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+proposerPubkey.String(), "1", mevCommitValidatorRegistrationExpiry).Err() if err != nil { @@ -317,14 +323,6 @@ func (r *RedisCache) IsMevCommitValidatorRegistered(proposerPubkey common.Pubkey return true, nil } -func (r *RedisCache) DeleteMevCommitValidatorRegistration(proposerPubkey common.PubkeyHex) error { - err := r.client.Del(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+proposerPubkey.String()).Err() - if err != nil { - return fmt.Errorf("failed to remove validator from mev-commit registration: %w", err) - } - return nil -} - func (r *RedisCache) SetValidatorRegistrationTimestampIfNewer(proposerPubkey common.PubkeyHex, timestamp uint64) error { knownTimestamp, err := r.GetValidatorRegistrationTimestamp(proposerPubkey) if err != nil { diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index 72e595d6..3e972c1d 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -203,7 +203,7 @@ func (hk *Housekeeper) monitorMevCommitBuilderRegistrations() { for _, entry := range entries { if entry.EOAAddress == builderAddress { hk.log.WithField("builder", builderAddress).Info("builder unregistered") - err := hk.redis.DeleteMevCommitValidatorRegistration(common.PubkeyHex(entry.Pubkey)) + err := hk.redis.DeleteMevCommitBlockBuilder(common.PubkeyHex(entry.Pubkey)) if err != nil { hk.log.WithError(err).Errorf("failed to delete mev-commit block builder %s", builderAddress) } @@ -228,7 +228,7 @@ func (hk *Housekeeper) cleanupMevCommitBuilderRegistrations() { continue } if !isRegistered { - err := hk.redis.DeleteMevCommitValidatorRegistration(common.PubkeyHex(builder.Pubkey)) + err := hk.redis.DeleteMevCommitBlockBuilder(common.PubkeyHex(builder.Pubkey)) if err != nil { hk.log.WithError(err).Errorf("failed to delete mev-commit validator registration for builder %s", builder.Pubkey) } else { From d4d63f5c4b65854f0635365972704a24b9dec4ff Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 13 Oct 2024 21:09:50 -0400 Subject: [PATCH 53/70] chore: runs gofumpt --- datastore/redis_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/datastore/redis_test.go b/datastore/redis_test.go index 469882f4..7698e99d 100644 --- a/datastore/redis_test.go +++ b/datastore/redis_test.go @@ -445,6 +445,7 @@ func TestPipelineNilCheck(t *testing.T) { require.NoError(t, err) require.Equal(t, big.NewInt(0), f) } + func TestSetMevCommitBlockBuilders(t *testing.T) { cache := setupTestRedis(t) From 93c336fe90ba2037dffdea9d12252e1e0e94dabb Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 13 Oct 2024 21:16:40 -0400 Subject: [PATCH 54/70] chore: fixes all issues identified by linter (#3) --- datastore/datastore.go | 2 +- mevcommitclient/mev_commit_client.go | 13 ++++++++----- services/api/service.go | 4 +--- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/datastore/datastore.go b/datastore/datastore.go index b773fa30..0cef2712 100644 --- a/datastore/datastore.go +++ b/datastore/datastore.go @@ -193,7 +193,7 @@ func (ds *Datastore) SaveMevCommitValidatorRegistration(pubkeyHex common.PubkeyH return nil } -// IsMevCommitRegisteredValidator checks if a validator is registered for mev-commit +// IsMevCommitValidatorRegistered checks if a validator is registered for mev-commit func (ds *Datastore) IsMevCommitValidatorRegistered(pubkeyHex common.PubkeyHex) (bool, error) { return ds.redis.IsMevCommitValidatorRegistered(pubkeyHex) } diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 05891386..fffacc98 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -1,3 +1,6 @@ +// Package mevcommitclient provides functionality for interacting with the mev-commit protocol. +// It includes interfaces and implementations for querying validator opt-in status, +// monitoring builder events, and validating builder registrations. package mevcommitclient import ( @@ -42,13 +45,13 @@ const ( abiJSON = `[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"builder","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"blsPublicKey","type":"bytes"}],"name":"BuilderRegistered","type":"event"},{"inputs":[{"internalType":"address","name":"builder","type":"address"}],"name":"isBuilderValid","outputs":[],"stateMutability":"view","type":"function"}]` ) -func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddress, ProviderRegistryAddress common.Address) (IMevCommitClient, error) { - l1Client, err := ethclient.Dial(l1MainnetUrl) +func NewMevCommitClient(l1MainnetURL, mevCommitURL string, validatorRouterAddress, ProviderRegistryAddress common.Address) (IMevCommitClient, error) { + l1Client, err := ethclient.Dial(l1MainnetURL) if err != nil { return nil, fmt.Errorf("failed to connect to L1 Mainnet: %w", err) } - mevCommitClient, err := ethclient.Dial(mevCommitUrl) + mevCommitClient, err := ethclient.Dial(mevCommitURL) if err != nil { return nil, fmt.Errorf("failed to connect to mev-commit EVM: %w", err) } @@ -74,8 +77,8 @@ func NewMevCommitClient(l1MainnetUrl, mevCommitUrl string, validatorRouterAddres } return &MevCommitClient{ - L1Address: l1MainnetUrl, - MevCommitAddress: mevCommitUrl, + L1Address: l1MainnetURL, + MevCommitAddress: mevCommitURL, ValidatorRouterAddress: validatorRouterAddress, ProviderRegistryAddress: ProviderRegistryAddress, validatorOptInRouterCaller: validatorOptInRouter, diff --git a/services/api/service.go b/services/api/service.go index 3a30c7b6..f926505e 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -35,7 +35,6 @@ import ( "github.com/flashbots/mev-boost-relay/database" "github.com/flashbots/mev-boost-relay/datastore" "github.com/flashbots/mev-boost-relay/metrics" - "github.com/flashbots/mev-boost-relay/mevcommitclient" "github.com/go-redis/redis/v9" "github.com/gorilla/mux" "github.com/holiman/uint256" @@ -185,8 +184,7 @@ type RelayAPI struct { srvStarted uberatomic.Bool srvShutdown uberatomic.Bool - beaconClient beaconclient.IMultiBeaconClient - mevCommitClient mevcommitclient.IMevCommitClient + beaconClient beaconclient.IMultiBeaconClient datastore *datastore.Datastore redis *datastore.RedisCache From dca4cb5a370878ea424c44282c36ecf0afe70113 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Sun, 13 Oct 2024 21:22:31 -0400 Subject: [PATCH 55/70] chore: simplify blocknumber retrieval --- mevcommitclient/mev_commit_client.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index fffacc98..f14530d7 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -92,14 +92,13 @@ func NewMevCommitClient(l1MainnetURL, mevCommitURL string, validatorRouterAddres func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) { // Get the finalized block number - var finalizedBlockNumber *big.Int - err := m.l1Client.Client().Call(&finalizedBlockNumber, "eth_getBlockByNumber", "finalized", false) + currentBlockNumber, err := m.l1Client.BlockNumber(context.Background()) if err != nil { - return nil, fmt.Errorf("failed to get finalized block: %w", err) + return nil, fmt.Errorf("failed to get current block number: %w", err) } opts := &bind.CallOpts{ - BlockNumber: finalizedBlockNumber, + BlockNumber: big.NewInt(int64(currentBlockNumber - 64)), } return m.validatorOptInRouterCaller.AreValidatorsOptedIn(opts, pubkeys) From 28b69918e435a44ad18172f0f27ff27de65ebbb4 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 14 Oct 2024 11:06:33 -0400 Subject: [PATCH 56/70] nit: remove comment --- datastore/redis.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/datastore/redis.go b/datastore/redis.go index 23ed5e90..e35bfc9c 100644 --- a/datastore/redis.go +++ b/datastore/redis.go @@ -98,7 +98,7 @@ type RedisCache struct { // keys keyValidatorRegistrationTimestamp string keyMevCommitValidatorRegistrationHash string - keyMevCommitBlockBuilder string // New key for mev-commit block builder array + keyMevCommitBlockBuilder string keyRelayConfig string keyStats string @@ -140,7 +140,7 @@ func NewRedisCache(prefix, redisURI, readonlyURI string) (*RedisCache, error) { keyValidatorRegistrationTimestamp: fmt.Sprintf("%s/%s:validator-registration-timestamp", redisPrefix, prefix), keyMevCommitValidatorRegistrationHash: fmt.Sprintf("%s/%s:mev-commit-validator-registration", redisPrefix, prefix), - keyMevCommitBlockBuilder: fmt.Sprintf("%s/%s:mev-commit-block-builder", redisPrefix, prefix), // New key for mev-commit block builder array + keyMevCommitBlockBuilder: fmt.Sprintf("%s/%s:mev-commit-block-builder", redisPrefix, prefix), keyRelayConfig: fmt.Sprintf("%s/%s:relay-config", redisPrefix, prefix), keyStats: fmt.Sprintf("%s/%s:stats", redisPrefix, prefix), From 9dfd417f03853345f7c5d7a64fc2dee61c94c124 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 14 Oct 2024 11:09:09 -0400 Subject: [PATCH 57/70] nit: add more test coverage on redis --- datastore/redis_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/datastore/redis_test.go b/datastore/redis_test.go index 7698e99d..c8c62255 100644 --- a/datastore/redis_test.go +++ b/datastore/redis_test.go @@ -475,6 +475,20 @@ func TestSetMevCommitBlockBuilders(t *testing.T) { isSet, err = cache.IsMevCommitBlockBuilder(common.PubkeyHex(nonExistentBuilderPubkey)) require.NoError(t, err) require.False(t, isSet) + + // Test removing a registered block builder + err = cache.DeleteMevCommitBlockBuilder(common.PubkeyHex(builderPubkey)) + require.NoError(t, err) + + // Check if the removed builder is no longer registered + isSet, err = cache.IsMevCommitBlockBuilder(common.PubkeyHex(builderPubkey)) + require.NoError(t, err) + require.False(t, isSet) + + // Verify the list of mev-commit block builders is now empty + builders, err = cache.GetMevCommitBlockBuilders() + require.NoError(t, err) + require.Empty(t, builders) } // func TestPipeline(t *testing.T) { From 32c96f06bb97ba600e56d0a049f32caf467c5e89 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 14 Oct 2024 12:21:52 -0400 Subject: [PATCH 58/70] nit: make sure filtering is on during all tests --- services/api/optimistic_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/api/optimistic_test.go b/services/api/optimistic_test.go index b000546d..1ecee8d3 100644 --- a/services/api/optimistic_test.go +++ b/services/api/optimistic_test.go @@ -90,6 +90,7 @@ func startTestBackend(t *testing.T) (*phase0.BLSPubKey, *bls.SecretKey, *testBac }, } backend.relay.opts.BlockBuilderAPI = true + backend.relay.opts.MevCommitFiltering = true backend.relay.beaconClient = beaconclient.NewMockMultiBeaconClient() backend.relay.blockSimRateLimiter = &MockBlockSimulationRateLimiter{} backend.relay.blockBuildersCache = map[string]*blockBuilderCacheEntry{ @@ -119,6 +120,7 @@ func startTestBackend(t *testing.T) (*phase0.BLSPubKey, *bls.SecretKey, *testBac redisTestServer, err := miniredis.Run() require.NoError(t, err) mockRedis, err := datastore.NewRedisCache("", redisTestServer.Addr(), "") + require.NoError(t, err) mockDS, err := datastore.NewDatastore(mockRedis, nil, mockDB) require.NoError(t, err) From ae70252f602effe1e7f9b2887faac69b6bb81ace Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 14 Oct 2024 17:29:31 -0400 Subject: [PATCH 59/70] chore: downgrade go --- go.mod | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 71535693..bb95d986 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module github.com/flashbots/mev-boost-relay -go 1.22 - -toolchain go1.23.1 +go 1.21 require ( github.com/NYTimes/gziphandler v1.1.1 From ac5b7599c0bb23c7a8a7555b57c04affa178782b Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Mon, 14 Oct 2024 18:16:58 -0400 Subject: [PATCH 60/70] nit: bump go-ethereum version --- Dockerfile | 2 +- go.mod | 30 +++++++++++++------------- go.sum | 62 ++++++++++++++++++++++++------------------------------ 3 files changed, 44 insertions(+), 50 deletions(-) diff --git a/Dockerfile b/Dockerfile index 44f355c5..713569e8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax=docker/dockerfile:1 -FROM golang:1.21 as builder +FROM golang:1.23 AS builder ARG VERSION WORKDIR /build diff --git a/go.mod b/go.mod index bb95d986..1c6d31e7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/flashbots/mev-boost-relay -go 1.21 +go 1.22 + +toolchain go1.23.1 require ( github.com/NYTimes/gziphandler v1.1.1 @@ -10,12 +12,12 @@ require ( github.com/bradfitz/gomemcache v0.0.0-20230124162541-5f7a7d875746 github.com/btcsuite/btcd/btcutil v1.1.2 github.com/buger/jsonparser v1.1.1 - github.com/ethereum/go-ethereum v1.13.14 + github.com/ethereum/go-ethereum v1.14.11 github.com/flashbots/go-boost-utils v1.8.0 github.com/flashbots/go-utils v0.5.0 github.com/go-redis/redis/v9 v9.0.0-rc.1 github.com/gorilla/mux v1.8.1 - github.com/holiman/uint256 v1.2.4 + github.com/holiman/uint256 v1.3.1 github.com/jmoiron/sqlx v1.3.5 github.com/lib/pq v1.10.8 github.com/pkg/errors v0.9.1 @@ -38,25 +40,25 @@ require ( require ( github.com/DataDog/zstd v1.5.5 // indirect - github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect github.com/StackExchange/wmi v1.2.1 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/bits-and-blooms/bitset v1.10.0 // indirect + github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240616162244-4768e80dfb9a // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v1.1.1 // indirect + github.com/cockroachdb/pebble v1.1.2 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 // indirect - github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect - github.com/deckarep/golang-set/v2 v2.1.0 // indirect - github.com/ethereum/c-kzg-4844 v0.4.0 // indirect + github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect + github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect + github.com/ethereum/c-kzg-4844 v1.0.0 // indirect + github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect github.com/fatih/color v1.16.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect - github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 // indirect github.com/getsentry/sentry-go v0.28.1 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-logr/logr v1.4.1 // indirect @@ -83,12 +85,10 @@ require ( github.com/rivo/uniseg v0.4.2 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect - github.com/supranational/blst v0.3.11 // indirect + github.com/supranational/blst v0.3.13 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect go.opentelemetry.io/otel/trace v1.25.0 // indirect - golang.org/x/mod v0.19.0 // indirect golang.org/x/sync v0.7.0 // indirect - golang.org/x/tools v0.23.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/protobuf v1.34.2 // indirect rsc.io/tmplfunc v0.0.3 // indirect @@ -97,7 +97,7 @@ require ( require ( github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a // indirect github.com/btcsuite/btcd v0.23.0 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect diff --git a/go.sum b/go.sum index 66230a62..15f2cd29 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,13 @@ 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.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= -github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= -github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= @@ -21,8 +21,8 @@ github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= 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.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= -github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= +github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bradfitz/gomemcache v0.0.0-20230124162541-5f7a7d875746 h1:wAIE/kN63Oig1DdOzN7O+k4AbFh2cCJoKMFXrwRJtzk= github.com/bradfitz/gomemcache v0.0.0-20230124162541-5f7a7d875746/go.mod h1:H0wQNHz2YrLsuXOZozoeDmnHXkNCRmMW0gwFWDfEZDA= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= @@ -31,8 +31,8 @@ github.com/btcsuite/btcd v0.23.0 h1:V2/ZgjfDFIygAX3ZapeigkVBoVUtOJKSwrhZdlpSvaA= github.com/btcsuite/btcd v0.23.0/go.mod h1:0QJIIN1wwIXF/3G/m87gIwGniDMDQqjVn4SZgnFpsYY= github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= -github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= -github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= github.com/btcsuite/btcd/btcutil v1.1.2 h1:XLMbX8JQEiwMcYft2EGi8zPUkoa0abKIU6/BJSRsjzQ= @@ -66,8 +66,8 @@ github.com/cockroachdb/fifo v0.0.0-20240616162244-4768e80dfb9a h1:f52TdbU4D5nozM github.com/cockroachdb/fifo v0.0.0-20240616162244-4768e80dfb9a/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v1.1.1 h1:XnKU22oiCLy2Xn8vp1re67cXg4SAasg/WDt1NtcRFaw= -github.com/cockroachdb/pebble v1.1.1/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= +github.com/cockroachdb/pebble v1.1.2 h1:CUh2IPtR4swHlEj48Rhfzw6l/d0qA31fItcIszQVIsA= +github.com/cockroachdb/pebble v1.1.2/go.mod h1:4exszw1r40423ZsmkG/09AFEG83I0uDgfujJdbL6kYU= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= @@ -78,17 +78,17 @@ github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJ github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= -github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= -github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= -github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= +github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= +github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= @@ -98,16 +98,16 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3 github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= -github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.13.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ= -github.com/ethereum/go-ethereum v1.13.14/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU= +github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= +github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.14.11 h1:8nFDCUUE67rPc6AKxFj7JKaOa2W/W1Rse3oS6LvvxEY= +github.com/ethereum/go-ethereum v1.14.11/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= +github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= 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.3 h1:ZI+z3JH05h4kgmFXdHuR1aWYsgrg7o+Fw7/NCzM16Mo= github.com/ferranbt/fastssz v0.1.3/go.mod h1:0Y9TEd/9XuFlh7mskMPfXiI2Dkw4Ddg9EyXt1W7MRvE= -github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA= -github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/flashbots/go-boost-utils v1.8.0 h1:z3K1hw+Fbl9AGMNQKnK7Bvf0M/rKgjfruAEvra+Z8Mg= github.com/flashbots/go-boost-utils v1.8.0/go.mod h1:Ry1Rw8Lx5v1rpAR0+IvR4sV10jYAeQaGVM3vRD8mYdM= github.com/flashbots/go-utils v0.5.0 h1:ldjWta9B9//DJU2QcwRbErez3+1aKhSn6EoFc6d5kPY= @@ -118,8 +118,6 @@ github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4 github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= -github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= -github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/getsentry/sentry-go v0.28.1 h1:zzaSm/vHmGllRM6Tpx1492r0YDzauArdBfkJRtY6P5k= github.com/getsentry/sentry-go v0.28.1/go.mod h1:1fQZ+7l7eeJ3wYi82q5Hg8GqAPgefRq+FP/QhafYVgg= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= @@ -188,8 +186,8 @@ github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6w github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= -github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= +github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/go-clone v1.6.0 h1:HMo5uvg4wgfiy5FoGOqlFLQED/VGRm2D9Pi8g1FXPGc= github.com/huandu/go-clone v1.6.0/go.mod h1:ReGivhG6op3GYr+UY3lS6mxjKp7MIGTknuU5TbTVaXE= @@ -323,8 +321,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= -github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= +github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tdewolff/minify v2.3.6+incompatible h1:2hw5/9ZvxhWLvBUnHE06gElGYz+Jv9R4Eys0XUzItYo= @@ -381,8 +379,6 @@ golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= -golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -433,8 +429,6 @@ golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= -golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -455,8 +449,8 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From 3ea3e16398788022b1a8468e8a2f2b1e0c5036a6 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 15 Oct 2024 14:15:01 -0400 Subject: [PATCH 61/70] feat: faster filtering and more test coverage --- datastore/redis_test.go | 3 +- mevcommitclient/mev_commit_client.go | 69 ++++++++++++++++++++--- mevcommitclient/mev_commit_client_test.go | 28 +++++++++ services/housekeeper/housekeeper.go | 1 + 4 files changed, 92 insertions(+), 9 deletions(-) diff --git a/datastore/redis_test.go b/datastore/redis_test.go index c8c62255..eb912b34 100644 --- a/datastore/redis_test.go +++ b/datastore/redis_test.go @@ -453,7 +453,7 @@ func TestSetMevCommitBlockBuilders(t *testing.T) { // Set a commit block builder builder := mevcommitclient.MevCommitProvider{ Pubkey: []byte(builderPubkey), - EOAAddress: gethCommon.HexToAddress("0x0000000000000000000000000000000000000000"), + EOAAddress: gethCommon.HexToAddress("0x0000000000000000000000000000000000000001"), } err := cache.SetMevCommitBlockBuilder(builder) require.NoError(t, err) @@ -464,6 +464,7 @@ func TestSetMevCommitBlockBuilders(t *testing.T) { require.Len(t, builders, 1) require.Equal(t, builder, builders[0]) require.Equal(t, builderPubkey, string(builders[0].Pubkey)) + require.Equal(t, gethCommon.HexToAddress("0x0000000000000000000000000000000000000001"), builders[0].EOAAddress) // Check if the commit block builder is set correctly isSet, err := cache.IsMevCommitBlockBuilder(common.PubkeyHex(builderPubkey)) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index f14530d7..770c2493 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -105,34 +105,70 @@ func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, } func (m *MevCommitClient) ListenForBuildersEvents() (<-chan MevCommitProvider, <-chan common.Address, error) { - startBlock := uint64(0) - opts := &bind.WatchOpts{ - Start: &startBlock, // Start from the latest block + // Get the latest block number from mev-commit-geth + latestBlock, err := m.mevCommitClient.BlockNumber(context.Background()) + if err != nil { + return nil, nil, fmt.Errorf("failed to get latest block number from mev-commit-geth: %w", err) + } + filterOpts := &bind.FilterOpts{ + Start: 0, + End: &latestBlock, // Latest block + Context: context.Background(), + } + watchOpts := &bind.WatchOpts{ + Start: &latestBlock, Context: context.Background(), } builderRegistryEventCh := make(chan MevCommitProvider) builderUnregisteredEventCh := make(chan common.Address) - providerRegisteredEventCh := make(chan *providerRegistry.ProviderregistryProviderRegistered) - providerSlashedEventCh := make(chan *providerRegistry.ProviderregistryFundsSlashed) + providerRegisteredIterator, err := m.builderRegistryFilterer.FilterProviderRegistered(filterOpts, nil) + if err != nil { + return nil, nil, fmt.Errorf("failed to filter ProviderRegistered events: %w", err) + } - providerRegisteredSub, err := m.builderRegistryFilterer.WatchProviderRegistered(opts, providerRegisteredEventCh, nil) + providerRegisteredEventCh := make(chan *providerRegistry.ProviderregistryProviderRegistered) + providerRegisteredSub, err := m.builderRegistryFilterer.WatchProviderRegistered(watchOpts, providerRegisteredEventCh, nil) if err != nil { + providerRegisteredIterator.Close() return nil, nil, fmt.Errorf("failed to watch ProviderRegistered events: %w", err) } - providerSlashedSub, err := m.builderRegistryFilterer.WatchFundsSlashed(opts, providerSlashedEventCh, nil) + providerSlashedIterator, err := m.builderRegistryFilterer.FilterFundsSlashed(filterOpts, nil) + if err != nil { + providerRegisteredIterator.Close() + providerRegisteredSub.Unsubscribe() + return nil, nil, fmt.Errorf("failed to filter FundsSlashed events: %w", err) + } + + providerSlashedEventCh := make(chan *providerRegistry.ProviderregistryFundsSlashed) + providerSlashedSub, err := m.builderRegistryFilterer.WatchFundsSlashed(watchOpts, providerSlashedEventCh, nil) if err != nil { + providerRegisteredIterator.Close() + providerSlashedIterator.Close() providerRegisteredSub.Unsubscribe() return nil, nil, fmt.Errorf("failed to watch ProviderSlashed events: %w", err) } go func() { + defer providerRegisteredIterator.Close() defer providerRegisteredSub.Unsubscribe() + + for providerRegisteredIterator.Next() { + event := providerRegisteredIterator.Event + builderRegistryEventCh <- MevCommitProvider{ + Pubkey: event.BlsPublicKey, + EOAAddress: event.Provider, + } + } + if err := providerRegisteredIterator.Error(); err != nil { + fmt.Printf("error while iterating ProviderRegistered events: %v\n", err) + } + for { select { case err := <-providerRegisteredSub.Err(): - fmt.Printf("error while watching ProviderRegistered events: %v\n", err) + fmt.Printf("error in ProviderRegistered subscription: %v\n", err) close(builderRegistryEventCh) return case event := <-providerRegisteredEventCh: @@ -146,6 +182,23 @@ func (m *MevCommitClient) ListenForBuildersEvents() (<-chan MevCommitProvider, < go func() { defer providerSlashedSub.Unsubscribe() + defer providerSlashedIterator.Close() + + for providerSlashedIterator.Next() { + event := providerSlashedIterator.Event + isValid, err := m.IsBuilderValid(event.Provider) + if err != nil { + fmt.Printf("failed to check if builder is valid: %v\n", err) + continue + } + if !isValid { + builderUnregisteredEventCh <- event.Provider + } + } + if err := providerSlashedIterator.Error(); err != nil { + fmt.Printf("error while iterating FundsSlashed events: %v\n", err) + } + for { select { case err := <-providerSlashedSub.Err(): diff --git a/mevcommitclient/mev_commit_client_test.go b/mevcommitclient/mev_commit_client_test.go index b02c716a..e405cbea 100644 --- a/mevcommitclient/mev_commit_client_test.go +++ b/mevcommitclient/mev_commit_client_test.go @@ -2,6 +2,7 @@ package mevcommitclient import ( "testing" + "time" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/assert" @@ -59,3 +60,30 @@ func TestGetOptInStatusForValidators(t *testing.T) { assert.IsType(t, bool(true), status) } } + +func TestListenForBuildersEvents(t *testing.T) { + client, err := NewMevCommitClient( + ethereumL1RPC, + "wss://chainrpc-wss.testnet.mev-commit.xyz", + common.HexToAddress(validatorOptInRouterAddr), + common.HexToAddress(providerRegistryAddr), + ) + require.NoError(t, err) + + builderRegisteredCh, _, err := client.ListenForBuildersEvents() + require.NoError(t, err) + + // Start a goroutine to listen for events + go func() { + select { + case _ = <-builderRegisteredCh: + + case <-time.After(10 * time.Second): + t.Log("No events received after 10 seconds") + t.Fail() // Add this line to fail the test if no events are received + } + }() + + time.Sleep(15 * time.Second) + +} diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index 3e972c1d..02f027d6 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -73,6 +73,7 @@ func NewHousekeeper(opts *HousekeeperOpts) *Housekeeper { pprofAPI: opts.PprofAPI, pprofListenAddress: opts.PprofListenAddress, proposersAlreadySaved: make(map[uint64]string), + mevCommitClient: opts.MevCommitClient, } return server From c50bce5dd718697798f905a8ae8348ed8fcd6b09 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 15 Oct 2024 14:21:48 -0400 Subject: [PATCH 62/70] nit: comment cleanup --- mevcommitclient/mev_commit_client.go | 3 +-- mevcommitclient/mev_commit_client_test.go | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 770c2493..aa4d2a62 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -105,14 +105,13 @@ func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, } func (m *MevCommitClient) ListenForBuildersEvents() (<-chan MevCommitProvider, <-chan common.Address, error) { - // Get the latest block number from mev-commit-geth latestBlock, err := m.mevCommitClient.BlockNumber(context.Background()) if err != nil { return nil, nil, fmt.Errorf("failed to get latest block number from mev-commit-geth: %w", err) } filterOpts := &bind.FilterOpts{ Start: 0, - End: &latestBlock, // Latest block + End: &latestBlock, Context: context.Background(), } watchOpts := &bind.WatchOpts{ diff --git a/mevcommitclient/mev_commit_client_test.go b/mevcommitclient/mev_commit_client_test.go index e405cbea..6c19bb97 100644 --- a/mevcommitclient/mev_commit_client_test.go +++ b/mevcommitclient/mev_commit_client_test.go @@ -77,10 +77,9 @@ func TestListenForBuildersEvents(t *testing.T) { go func() { select { case _ = <-builderRegisteredCh: - case <-time.After(10 * time.Second): t.Log("No events received after 10 seconds") - t.Fail() // Add this line to fail the test if no events are received + t.Fail() } }() From 89402c7382120594b29ca02aa02c985166e7a41a Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 15 Oct 2024 14:22:53 -0400 Subject: [PATCH 63/70] chore: replace http with ws connection --- mevcommitclient/mev_commit_client_test.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/mevcommitclient/mev_commit_client_test.go b/mevcommitclient/mev_commit_client_test.go index 6c19bb97..f00100c9 100644 --- a/mevcommitclient/mev_commit_client_test.go +++ b/mevcommitclient/mev_commit_client_test.go @@ -10,7 +10,7 @@ import ( ) const ( - mevCommitRPC = "https://chainrpc.testnet.mev-commit.xyz/" + mevCommitRPC = "wss://chainrpc-wss.testnet.mev-commit.xyz" ethereumL1RPC = "https://ethereum-holesky-rpc.publicnode.com" providerRegistryAddr = "0xf4F10e18244d836311508917A3B04694D88999Dd" validatorOptInRouterAddr = "0xCae46e1013D33587180Db5933Abd75D977c2d7ab" @@ -64,7 +64,7 @@ func TestGetOptInStatusForValidators(t *testing.T) { func TestListenForBuildersEvents(t *testing.T) { client, err := NewMevCommitClient( ethereumL1RPC, - "wss://chainrpc-wss.testnet.mev-commit.xyz", + mevCommitRPC, common.HexToAddress(validatorOptInRouterAddr), common.HexToAddress(providerRegistryAddr), ) @@ -73,7 +73,6 @@ func TestListenForBuildersEvents(t *testing.T) { builderRegisteredCh, _, err := client.ListenForBuildersEvents() require.NoError(t, err) - // Start a goroutine to listen for events go func() { select { case _ = <-builderRegisteredCh: From 422eb7c70efb997a01ef3f7a0bf24e0213c00e74 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 15 Oct 2024 14:23:24 -0400 Subject: [PATCH 64/70] nit: cleanup test --- mevcommitclient/mev_commit_client_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mevcommitclient/mev_commit_client_test.go b/mevcommitclient/mev_commit_client_test.go index f00100c9..c5dbb4a1 100644 --- a/mevcommitclient/mev_commit_client_test.go +++ b/mevcommitclient/mev_commit_client_test.go @@ -75,7 +75,7 @@ func TestListenForBuildersEvents(t *testing.T) { go func() { select { - case _ = <-builderRegisteredCh: + case <-builderRegisteredCh: case <-time.After(10 * time.Second): t.Log("No events received after 10 seconds") t.Fail() From 03542375aed6edbf5eaf9f1ab1dbd544018fc964 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 15 Oct 2024 18:12:19 -0400 Subject: [PATCH 65/70] feat: adds LRU cache for mevcommit registrations --- datastore/datastore.go | 34 ++++++++++++++++++++++++++++------ datastore/datastore_test.go | 35 +++++++++++++++++++++++++++++++++++ go.mod | 1 + go.sum | 2 ++ 4 files changed, 66 insertions(+), 6 deletions(-) diff --git a/datastore/datastore.go b/datastore/datastore.go index 0cef2712..0e8e0438 100644 --- a/datastore/datastore.go +++ b/datastore/datastore.go @@ -15,6 +15,7 @@ import ( "github.com/flashbots/mev-boost-relay/common" "github.com/flashbots/mev-boost-relay/database" "github.com/go-redis/redis/v9" + lru "github.com/hashicorp/golang-lru" "github.com/pkg/errors" "github.com/sirupsen/logrus" uberatomic "go.uber.org/atomic" @@ -40,6 +41,8 @@ type Datastore struct { memcached *Memcached db database.IDatabaseService + isMevCommitValidatorRegistered *lru.Cache + knownValidatorsByPubkey map[common.PubkeyHex]uint64 knownValidatorsByIndex map[uint64]common.PubkeyHex knownValidatorsLock sync.RWMutex @@ -51,12 +54,17 @@ type Datastore struct { } func NewDatastore(redisCache *RedisCache, memcached *Memcached, db database.IDatabaseService) (ds *Datastore, err error) { + mevCommitValidatorRegistrationCache, err := lru.New(5) + if err != nil { + return nil, err + } ds = &Datastore{ - db: db, - memcached: memcached, - redis: redisCache, - knownValidatorsByPubkey: make(map[common.PubkeyHex]uint64), - knownValidatorsByIndex: make(map[uint64]common.PubkeyHex), + db: db, + memcached: memcached, + redis: redisCache, + knownValidatorsByPubkey: make(map[common.PubkeyHex]uint64), + knownValidatorsByIndex: make(map[uint64]common.PubkeyHex), + isMevCommitValidatorRegistered: mevCommitValidatorRegistrationCache, } return ds, err @@ -195,7 +203,21 @@ func (ds *Datastore) SaveMevCommitValidatorRegistration(pubkeyHex common.PubkeyH // IsMevCommitValidatorRegistered checks if a validator is registered for mev-commit func (ds *Datastore) IsMevCommitValidatorRegistered(pubkeyHex common.PubkeyHex) (bool, error) { - return ds.redis.IsMevCommitValidatorRegistered(pubkeyHex) + // Check the LRU cache first + if registered, ok := ds.isMevCommitValidatorRegistered.Get(pubkeyHex); ok { + return registered.(bool), nil + } + + // If not in cache, check Redis + registered, err := ds.redis.IsMevCommitValidatorRegistered(pubkeyHex) + if err != nil { + return false, err + } + + // Update the LRU cache with the result + ds.isMevCommitValidatorRegistered.Add(pubkeyHex, registered) + + return registered, nil } // IsMevCommitBlockBuilder checks if a builder is registered for mev-commit diff --git a/datastore/datastore_test.go b/datastore/datastore_test.go index 97361510..20b7f932 100644 --- a/datastore/datastore_test.go +++ b/datastore/datastore_test.go @@ -73,3 +73,38 @@ func TestGetPayloadDatabaseFallback(t *testing.T) { }) } } + +func TestMevCommitValidatorRegistration(t *testing.T) { + mockDB := &database.MockDB{} + ds := setupTestDatastore(t, mockDB) + pubkeys := []common.PubkeyHex{ + common.NewPubkeyHex("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"), + common.NewPubkeyHex("0x2345678901abcdef2345678901abcdef2345678901abcdef2345678901abcdef"), + common.NewPubkeyHex("0x3456789012abcdef3456789012abcdef3456789012abcdef3456789012abcdef"), + common.NewPubkeyHex("0x4567890123abcdef4567890123abcdef4567890123abcdef4567890123abcdef"), + common.NewPubkeyHex("0x5678901234abcdef5678901234abcdef5678901234abcdef5678901234abcdef"), + common.NewPubkeyHex("0x6789012345abcdef6789012345abcdef6789012345abcdef6789012345abcdef"), + } + + isRegistered, _ := ds.IsMevCommitValidatorRegistered(pubkeys[0]) + require.False(t, isRegistered) + + // Test saving a validator registration + err := ds.SaveMevCommitValidatorRegistration(pubkeys[0]) + require.NoError(t, err) + + isRegistered, err = ds.IsMevCommitValidatorRegistered(pubkeys[0]) + require.NoError(t, err) + // Stale check should fail since we recently cached the value + require.False(t, isRegistered) + + // Add all pubkeys to the cache - this will evict the stale value + for _, pubkey := range pubkeys { + ds.isMevCommitValidatorRegistered.Add(pubkey.String(), true) + } + + // Make sure it's coming from recently cached value + isRegistered, err = ds.IsMevCommitValidatorRegistered(pubkeys[0]) + require.NoError(t, err) + require.True(t, isRegistered) +} diff --git a/go.mod b/go.mod index 1c6d31e7..7f034769 100644 --- a/go.mod +++ b/go.mod @@ -70,6 +70,7 @@ require ( github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect diff --git a/go.sum b/go.sum index 15f2cd29..54d47c70 100644 --- a/go.sum +++ b/go.sum @@ -182,6 +182,8 @@ 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/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= From b9dcb96eaebc306358e457c4302aed69be3eb471 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Wed, 16 Oct 2024 12:15:46 -0400 Subject: [PATCH 66/70] feat: stores validator opted in status in proposer duties map (#4) * feat: stores validator opted in status in proposer duties map * feat: clean up mevcommit validator redis keys * feat: verifies correct encoding * chore: ensures we trim prefix to adhere to contract format * feat: also removes redundant builder cleanup --- common/types.go | 7 +- datastore/datastore.go | 47 ++----------- datastore/datastore_test.go | 35 ---------- datastore/redis.go | 35 ++-------- datastore/redis_test.go | 4 ++ mevcommitclient/mev_commit_client.go | 10 ++- mevcommitclient/mev_commit_client_test.go | 31 +++++++-- services/api/service.go | 9 +-- services/housekeeper/housekeeper.go | 85 +++-------------------- 9 files changed, 66 insertions(+), 197 deletions(-) diff --git a/common/types.go b/common/types.go index 0cb139be..d4dd3cff 100644 --- a/common/types.go +++ b/common/types.go @@ -188,9 +188,10 @@ func (p PubkeyHex) String() string { } type BuilderGetValidatorsResponseEntry struct { - Slot uint64 `json:"slot,string"` - ValidatorIndex uint64 `json:"validator_index,string"` - Entry *builderApiV1.SignedValidatorRegistration `json:"entry"` + Slot uint64 `json:"slot,string"` + ValidatorIndex uint64 `json:"validator_index,string"` + Entry *builderApiV1.SignedValidatorRegistration `json:"entry"` + IsMevCommitValidator bool `json:"is_mev_commit"` } type BidTraceV2 struct { diff --git a/datastore/datastore.go b/datastore/datastore.go index 0e8e0438..cc0430a0 100644 --- a/datastore/datastore.go +++ b/datastore/datastore.go @@ -15,7 +15,6 @@ import ( "github.com/flashbots/mev-boost-relay/common" "github.com/flashbots/mev-boost-relay/database" "github.com/go-redis/redis/v9" - lru "github.com/hashicorp/golang-lru" "github.com/pkg/errors" "github.com/sirupsen/logrus" uberatomic "go.uber.org/atomic" @@ -41,8 +40,6 @@ type Datastore struct { memcached *Memcached db database.IDatabaseService - isMevCommitValidatorRegistered *lru.Cache - knownValidatorsByPubkey map[common.PubkeyHex]uint64 knownValidatorsByIndex map[uint64]common.PubkeyHex knownValidatorsLock sync.RWMutex @@ -54,17 +51,13 @@ type Datastore struct { } func NewDatastore(redisCache *RedisCache, memcached *Memcached, db database.IDatabaseService) (ds *Datastore, err error) { - mevCommitValidatorRegistrationCache, err := lru.New(5) - if err != nil { - return nil, err - } + ds = &Datastore{ - db: db, - memcached: memcached, - redis: redisCache, - knownValidatorsByPubkey: make(map[common.PubkeyHex]uint64), - knownValidatorsByIndex: make(map[uint64]common.PubkeyHex), - isMevCommitValidatorRegistered: mevCommitValidatorRegistrationCache, + db: db, + memcached: memcached, + redis: redisCache, + knownValidatorsByPubkey: make(map[common.PubkeyHex]uint64), + knownValidatorsByIndex: make(map[uint64]common.PubkeyHex), } return ds, err @@ -192,34 +185,6 @@ func (ds *Datastore) SetKnownValidator(pubkeyHex common.PubkeyHex, index uint64) ds.knownValidatorsByIndex[index] = pubkeyHex } -// SaveMevCommitValidatorRegistration saves a validator registration for mev-commit into Redis -func (ds *Datastore) SaveMevCommitValidatorRegistration(pubkeyHex common.PubkeyHex) error { - err := ds.redis.SetMevCommitValidatorRegistration(pubkeyHex) - if err != nil { - return errors.Wrap(err, "failed saving mev-commit validator registration to redis") - } - return nil -} - -// IsMevCommitValidatorRegistered checks if a validator is registered for mev-commit -func (ds *Datastore) IsMevCommitValidatorRegistered(pubkeyHex common.PubkeyHex) (bool, error) { - // Check the LRU cache first - if registered, ok := ds.isMevCommitValidatorRegistered.Get(pubkeyHex); ok { - return registered.(bool), nil - } - - // If not in cache, check Redis - registered, err := ds.redis.IsMevCommitValidatorRegistered(pubkeyHex) - if err != nil { - return false, err - } - - // Update the LRU cache with the result - ds.isMevCommitValidatorRegistered.Add(pubkeyHex, registered) - - return registered, nil -} - // IsMevCommitBlockBuilder checks if a builder is registered for mev-commit func (ds *Datastore) IsMevCommitBlockBuilder(builderPubkey common.PubkeyHex) (bool, error) { return ds.redis.IsMevCommitBlockBuilder(builderPubkey) diff --git a/datastore/datastore_test.go b/datastore/datastore_test.go index 20b7f932..97361510 100644 --- a/datastore/datastore_test.go +++ b/datastore/datastore_test.go @@ -73,38 +73,3 @@ func TestGetPayloadDatabaseFallback(t *testing.T) { }) } } - -func TestMevCommitValidatorRegistration(t *testing.T) { - mockDB := &database.MockDB{} - ds := setupTestDatastore(t, mockDB) - pubkeys := []common.PubkeyHex{ - common.NewPubkeyHex("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"), - common.NewPubkeyHex("0x2345678901abcdef2345678901abcdef2345678901abcdef2345678901abcdef"), - common.NewPubkeyHex("0x3456789012abcdef3456789012abcdef3456789012abcdef3456789012abcdef"), - common.NewPubkeyHex("0x4567890123abcdef4567890123abcdef4567890123abcdef4567890123abcdef"), - common.NewPubkeyHex("0x5678901234abcdef5678901234abcdef5678901234abcdef5678901234abcdef"), - common.NewPubkeyHex("0x6789012345abcdef6789012345abcdef6789012345abcdef6789012345abcdef"), - } - - isRegistered, _ := ds.IsMevCommitValidatorRegistered(pubkeys[0]) - require.False(t, isRegistered) - - // Test saving a validator registration - err := ds.SaveMevCommitValidatorRegistration(pubkeys[0]) - require.NoError(t, err) - - isRegistered, err = ds.IsMevCommitValidatorRegistered(pubkeys[0]) - require.NoError(t, err) - // Stale check should fail since we recently cached the value - require.False(t, isRegistered) - - // Add all pubkeys to the cache - this will evict the stale value - for _, pubkey := range pubkeys { - ds.isMevCommitValidatorRegistered.Add(pubkey.String(), true) - } - - // Make sure it's coming from recently cached value - isRegistered, err = ds.IsMevCommitValidatorRegistered(pubkeys[0]) - require.NoError(t, err) - require.True(t, isRegistered) -} diff --git a/datastore/redis.go b/datastore/redis.go index e35bfc9c..6b8d3c67 100644 --- a/datastore/redis.go +++ b/datastore/redis.go @@ -25,8 +25,7 @@ var ( redisScheme = "redis://" redisPrefix = "boost-relay" - mevCommitValidatorRegistrationExpiry = 1 * time.Hour - expiryBidCache = 45 * time.Second + expiryBidCache = 45 * time.Second RedisConfigFieldPubkey = "pubkey" RedisStatsFieldLatestSlot = "latest-slot" @@ -96,9 +95,8 @@ type RedisCache struct { prefixFloorBidValue string // keys - keyValidatorRegistrationTimestamp string - keyMevCommitValidatorRegistrationHash string - keyMevCommitBlockBuilder string + keyValidatorRegistrationTimestamp string + keyMevCommitBlockBuilder string keyRelayConfig string keyStats string @@ -138,10 +136,9 @@ func NewRedisCache(prefix, redisURI, readonlyURI string) (*RedisCache, error) { prefixFloorBid: fmt.Sprintf("%s/%s:bid-floor", redisPrefix, prefix), // prefix:slot_parentHash_proposerPubkey prefixFloorBidValue: fmt.Sprintf("%s/%s:bid-floor-value", redisPrefix, prefix), // prefix:slot_parentHash_proposerPubkey - keyValidatorRegistrationTimestamp: fmt.Sprintf("%s/%s:validator-registration-timestamp", redisPrefix, prefix), - keyMevCommitValidatorRegistrationHash: fmt.Sprintf("%s/%s:mev-commit-validator-registration", redisPrefix, prefix), - keyMevCommitBlockBuilder: fmt.Sprintf("%s/%s:mev-commit-block-builder", redisPrefix, prefix), - keyRelayConfig: fmt.Sprintf("%s/%s:relay-config", redisPrefix, prefix), + keyValidatorRegistrationTimestamp: fmt.Sprintf("%s/%s:validator-registration-timestamp", redisPrefix, prefix), + keyMevCommitBlockBuilder: fmt.Sprintf("%s/%s:mev-commit-block-builder", redisPrefix, prefix), + keyRelayConfig: fmt.Sprintf("%s/%s:relay-config", redisPrefix, prefix), keyStats: fmt.Sprintf("%s/%s:stats", redisPrefix, prefix), keyProposerDuties: fmt.Sprintf("%s/%s:proposer-duties", redisPrefix, prefix), @@ -303,26 +300,6 @@ func (r *RedisCache) DeleteMevCommitBlockBuilder(builderPubkey common.PubkeyHex) return r.client.HDel(ctx, r.keyMevCommitBlockBuilder, builderPubkey.String()).Err() } -func (r *RedisCache) SetMevCommitValidatorRegistration(proposerPubkey common.PubkeyHex) error { - err := r.client.Set(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+proposerPubkey.String(), "1", mevCommitValidatorRegistrationExpiry).Err() - if err != nil { - return fmt.Errorf("failed to add validator to mev-commit registration: %w", err) - } - return nil -} - -func (r *RedisCache) IsMevCommitValidatorRegistered(proposerPubkey common.PubkeyHex) (bool, error) { - _, err := r.client.Get(context.Background(), r.keyMevCommitValidatorRegistrationHash+":"+proposerPubkey.String()).Result() - if err == redis.Nil { - return false, nil - } - if err != nil { - return false, fmt.Errorf("failed to check mev-commit validator registration: %w", err) - } - - return true, nil -} - func (r *RedisCache) SetValidatorRegistrationTimestampIfNewer(proposerPubkey common.PubkeyHex, timestamp uint64) error { knownTimestamp, err := r.GetValidatorRegistrationTimestamp(proposerPubkey) if err != nil { diff --git a/datastore/redis_test.go b/datastore/redis_test.go index eb912b34..197a6c99 100644 --- a/datastore/redis_test.go +++ b/datastore/redis_test.go @@ -103,6 +103,7 @@ func TestRedisProposerDuties(t *testing.T) { Pubkey: phase0.BLSPubKey{}, }, }, + IsMevCommitValidator: true, }, } err := cache.SetProposerDuties(duties) @@ -113,6 +114,9 @@ func TestRedisProposerDuties(t *testing.T) { require.Len(t, duties2, 1) require.Equal(t, duties[0].Entry.Message.FeeRecipient, duties2[0].Entry.Message.FeeRecipient) + require.Equal(t, duties[0].IsMevCommitValidator, duties2[0].IsMevCommitValidator) + require.Equal(t, duties[0].IsMevCommitValidator, true) + } func TestBuilderBids(t *testing.T) { diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index aa4d2a62..943822c2 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -23,7 +23,7 @@ type MevCommitProvider struct { } type IMevCommitClient interface { - GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) + GetOptInStatusForValidators(pubkeys []string) ([]bool, error) ListenForBuildersEvents() (<-chan MevCommitProvider, <-chan common.Address, error) IsBuilderValid(builderAddress common.Address) (bool, error) } @@ -90,7 +90,7 @@ func NewMevCommitClient(l1MainnetURL, mevCommitURL string, validatorRouterAddres }, nil } -func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, error) { +func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys []string) ([]bool, error) { // Get the finalized block number currentBlockNumber, err := m.l1Client.BlockNumber(context.Background()) if err != nil { @@ -100,8 +100,12 @@ func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys [][]byte) ([]bool, opts := &bind.CallOpts{ BlockNumber: big.NewInt(int64(currentBlockNumber - 64)), } + pubkeysBytes := make([][]byte, len(pubkeys)) + for i, pubkey := range pubkeys { + pubkeysBytes[i] = common.Hex2Bytes(strings.TrimPrefix(pubkey, "0x")) + } - return m.validatorOptInRouterCaller.AreValidatorsOptedIn(opts, pubkeys) + return m.validatorOptInRouterCaller.AreValidatorsOptedIn(opts, pubkeysBytes) } func (m *MevCommitClient) ListenForBuildersEvents() (<-chan MevCommitProvider, <-chan common.Address, error) { diff --git a/mevcommitclient/mev_commit_client_test.go b/mevcommitclient/mev_commit_client_test.go index c5dbb4a1..976a3a66 100644 --- a/mevcommitclient/mev_commit_client_test.go +++ b/mevcommitclient/mev_commit_client_test.go @@ -43,11 +43,10 @@ func TestGetOptInStatusForValidators(t *testing.T) { common.HexToAddress(providerRegistryAddr), ) require.NoError(t, err) - // Test with some sample public keys - pubkeys := [][]byte{ - {0x01, 0x02, 0x03}, - {0x04, 0x05, 0x06}, + pubkeys := []string{ + "010203", + "040506", } statuses, err := client.GetOptInStatusForValidators(pubkeys) @@ -85,3 +84,27 @@ func TestListenForBuildersEvents(t *testing.T) { time.Sleep(15 * time.Second) } + +func TestGetOptInStatusForSpecificValidator(t *testing.T) { + client, err := NewMevCommitClient( + ethereumL1RPC, + mevCommitRPC, + common.HexToAddress(validatorOptInRouterAddr), + common.HexToAddress(providerRegistryAddr), + ) + require.NoError(t, err) + + // Specific validator public key we know is opted in + pubkey := "0xa7884bb9b06b912ec80d14e408cd88282f813547082b7a86bc1dd9c1881e29a781314f1f9108d6059a7ec10852e14028" + statuses, err := client.GetOptInStatusForValidators([]string{pubkey}) + require.NoError(t, err) + require.Len(t, statuses, 1) + assert.True(t, statuses[0], "Expected opt-in status to be true") + + pubkeyWithoutPrefix := "a7884bb9b06b912ec80d14e408cd88282f813547082b7a86bc1dd9c1881e29a781314f1f9108d6059a7ec10852e14028" + statuses, err = client.GetOptInStatusForValidators([]string{pubkeyWithoutPrefix}) + require.NoError(t, err) + require.Len(t, statuses, 1) + assert.True(t, statuses[0], "Expected opt-in status to be true") + +} diff --git a/services/api/service.go b/services/api/service.go index f926505e..74f84427 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -1749,14 +1749,7 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr return false } - isValidatorRegistered, err := api.datastore.IsMevCommitValidatorRegistered(common.NewPubkeyHex(duty.Entry.Message.Pubkey.String())) - if err != nil { - log.WithError(err).Error("Failed to check validator registration") - api.RespondError(w, http.StatusInternalServerError, "Internal server error") - return false - } - - if isValidatorRegistered { + if duty.IsMevCommitValidator { isBuilderRegistered, err := api.datastore.IsMevCommitBlockBuilder(common.NewPubkeyHex(submission.BidTrace.BuilderPubkey.String())) if err != nil { log.WithError(err).Error("Failed to check builder registration") diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index 02f027d6..881bbb74 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -149,8 +149,6 @@ func (hk *Housekeeper) processNewSlot(headSlot uint64) { // Update proposer duties go hk.updateProposerDuties(headSlot) - go hk.updateMevCommitValidatorRegistrations(headSlot) - go hk.cleanupMevCommitBuilderRegistrations() // Set headSlot in redis (for the website) err := hk.redis.SetStats(datastore.RedisStatsFieldLatestSlot, headSlot) @@ -215,32 +213,6 @@ func (hk *Housekeeper) monitorMevCommitBuilderRegistrations() { } } -func (hk *Housekeeper) cleanupMevCommitBuilderRegistrations() { - entries, err := hk.redis.GetMevCommitBlockBuilders() - if err != nil { - hk.log.WithError(err).Error("failed to get mev-commit block builders from Redis") - return - } - - for _, builder := range entries { - isRegistered, err := hk.mevCommitClient.IsBuilderValid(builder.EOAAddress) - if err != nil { - hk.log.WithError(err).Errorf("failed to check if builder %s is registered", builder.Pubkey) - continue - } - if !isRegistered { - err := hk.redis.DeleteMevCommitBlockBuilder(common.PubkeyHex(builder.Pubkey)) - if err != nil { - hk.log.WithError(err).Errorf("failed to delete mev-commit validator registration for builder %s", builder.Pubkey) - } else { - hk.log.WithField("builder", builder.Pubkey).Info("deleted mev-commit validator registration for inactive builder") - } - } - } - - hk.log.Info("completed cleanup of mev-commit builder registrations") -} - func (hk *Housekeeper) UpdateProposerDutiesWithoutChecks(headSlot uint64) { epoch := headSlot / common.SlotsPerEpoch @@ -288,15 +260,22 @@ func (hk *Housekeeper) UpdateProposerDutiesWithoutChecks(headSlot uint64) { signedValidatorRegistrations[regEntry.Pubkey] = signedEntry } + booleanValidatorRegistrationsArray, err := hk.mevCommitClient.GetOptInStatusForValidators(pubkeys) + if err != nil { + hk.log.WithError(err).Error("failed to get registered validators from mev-commit client") + return + } + // Prepare proposer duties proposerDuties := []common.BuilderGetValidatorsResponseEntry{} - for _, duty := range entries { + for i, duty := range entries { reg := signedValidatorRegistrations[duty.Pubkey] if reg != nil { proposerDuties = append(proposerDuties, common.BuilderGetValidatorsResponseEntry{ - Slot: duty.Slot, - ValidatorIndex: duty.ValidatorIndex, - Entry: reg, + Slot: duty.Slot, + ValidatorIndex: duty.ValidatorIndex, + Entry: reg, + IsMevCommitValidator: booleanValidatorRegistrationsArray[i], }) } } @@ -318,48 +297,6 @@ func (hk *Housekeeper) UpdateProposerDutiesWithoutChecks(headSlot uint64) { log.WithField("numDuties", len(_duties)).Infof("proposer duties updated: %s", strings.Join(_duties, ", ")) } -// When the update is triggered, we store registered validators in Redis for an the current and next epoch. -// This allows us to maintain 1 epoch in advance, which is enough to check if a validator is registered for a given epoch. -func (hk *Housekeeper) updateMevCommitValidatorRegistrations(headSlot uint64) { - // Only update once per epoch - at the epoch start of the epoch - if headSlot%common.SlotsPerEpoch != 0 { - return - } - - epoch := headSlot / common.SlotsPerEpoch - - duties, err := hk.beaconClient.GetProposerDuties(epoch) - if err != nil { - hk.log.WithError(err).Error("failed to get proposer duties for epoch") - return - } - nextDuties, err := hk.beaconClient.GetProposerDuties(epoch + 1) - if err != nil { - hk.log.WithError(err).Error("failed to get proposer duties for next epoch") - return - } - // Combine duties from current and next epoch into a single array - duties.Data = append(duties.Data, nextDuties.Data...) - - pubkeys := [][]byte{} - for _, duty := range duties.Data { - pubkeys = append(pubkeys, []byte(duty.Pubkey)) - } - - registeredValidators, err := hk.mevCommitClient.GetOptInStatusForValidators(pubkeys) - if err != nil { - hk.log.WithError(err).Error("failed to get registered validators from mev-commit client") - return - } - for i, registeredValidator := range registeredValidators { - if registeredValidator { - hk.redis.SetMevCommitValidatorRegistration(common.NewPubkeyHex(duties.Data[i].Pubkey)) - } - } - - hk.log.WithField("numValidators", len(registeredValidators)).Info("updated mev-commit registered validators in Redis") -} - // updateValidatorRegistrationsInRedis saves all latest validator registrations from the database to Redis func (hk *Housekeeper) updateValidatorRegistrationsInRedis() { regs, err := hk.db.GetLatestValidatorRegistrations(true) From 63b4b42b1db7594b645e754efd375b33473fa6d7 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Thu, 17 Oct 2024 11:14:00 -0400 Subject: [PATCH 67/70] feat: Reduces critical path latency by caching builder info in runtime memory (#5) * feat: first checks builder cache for opt in status * nit: clean up * nit: fix bracket order * chore: remove dupe not ok * nit: adds testing * feat: adds builder pubkey to test * nit: remove todo as implmentation is complete --- services/api/service.go | 34 ++++++++++++++++++++++------------ services/api/service_test.go | 28 ++++++++++++++++++++++------ 2 files changed, 44 insertions(+), 18 deletions(-) diff --git a/services/api/service.go b/services/api/service.go index 74f84427..6621c6aa 100644 --- a/services/api/service.go +++ b/services/api/service.go @@ -160,8 +160,9 @@ type blockSimOptions struct { } type blockBuilderCacheEntry struct { - status common.BuilderStatus - collateral *big.Int + status common.BuilderStatus + collateral *big.Int + mevCommitOptInStatus bool } type blockSimResult struct { @@ -883,12 +884,17 @@ func (api *RelayAPI) prepareBuildersForSlot(headSlot uint64) { newCache := make(map[string]*blockBuilderCacheEntry) for _, v := range builders { + isOptedIntoMevCommit, err := api.datastore.IsMevCommitBlockBuilder(common.PubkeyHex(v.BuilderPubkey)) + if err != nil { + api.log.WithError(err).Errorf("error getting mev-commit opt-in status for builder %s", v.BuilderPubkey) + } entry := &blockBuilderCacheEntry{ //nolint:exhaustruct status: common.BuilderStatus{ IsHighPrio: v.IsHighPrio, IsBlacklisted: v.IsBlacklisted, IsOptimistic: v.IsOptimistic, }, + mevCommitOptInStatus: isOptedIntoMevCommit, } // Try to parse builder collateral string to big int. builderCollateral, ok := big.NewInt(0).SetString(v.Collateral, 10) @@ -1748,17 +1754,21 @@ func (api *RelayAPI) checkSubmissionSlotDetails(w http.ResponseWriter, log *logr api.RespondError(w, http.StatusBadRequest, "no duty found for submission slot") return false } - if duty.IsMevCommitValidator { - isBuilderRegistered, err := api.datastore.IsMevCommitBlockBuilder(common.NewPubkeyHex(submission.BidTrace.BuilderPubkey.String())) - if err != nil { - log.WithError(err).Error("Failed to check builder registration") - api.RespondError(w, http.StatusInternalServerError, "Internal server error") - return false - } - if !isBuilderRegistered { - // TODO: Implement caching strategy for builder registration status - api.RespondError(w, http.StatusBadRequest, "Builder pubkey is not registered under mev-commit") + builderCacheEntry, ok := api.blockBuildersCache[submission.BidTrace.BuilderPubkey.String()] + if !ok { + isBuilderRegistered, err := api.datastore.IsMevCommitBlockBuilder(common.NewPubkeyHex(submission.BidTrace.BuilderPubkey.String())) + if err != nil { + log.WithError(err).Error("Failed to check builder registration") + api.RespondError(w, http.StatusInternalServerError, "Internal server error") + return false + } + if !isBuilderRegistered { + api.RespondError(w, http.StatusBadRequest, "Builder pubkey is not registered under mev-commit") + return false + } + } else if !builderCacheEntry.mevCommitOptInStatus { + api.RespondError(w, http.StatusBadRequest, "Builder pubkey is not opted into mev-commit") return false } } diff --git a/services/api/service_test.go b/services/api/service_test.go index d326f1bd..8058f3f3 100644 --- a/services/api/service_test.go +++ b/services/api/service_test.go @@ -904,6 +904,9 @@ func TestCheckSubmissionPayloadAttrs(t *testing.T) { backend.relay.payloadAttributesLock.RLock() backend.relay.payloadAttributes[getPayloadAttributesKey(testParentHash, testSlot)] = tc.attrs backend.relay.payloadAttributesLock.RUnlock() + backend.relay.blockBuildersCache[testBuilderPubkey] = &blockBuilderCacheEntry{ + mevCommitOptInStatus: true, + } w := httptest.NewRecorder() logger := logrus.New() @@ -917,10 +920,13 @@ func TestCheckSubmissionPayloadAttrs(t *testing.T) { } func TestCheckSubmissionSlotDetails(t *testing.T) { + builderPubkey, err := utils.HexToPubkey(testBuilderPubkey) + require.NoError(t, err) cases := []struct { - description string - payload *common.VersionedSubmitBlockRequest - expectOk bool + description string + payload *common.VersionedSubmitBlockRequest + expectOk bool + mevCommitOptInStatus bool }{ { description: "success", @@ -932,12 +938,14 @@ func TestCheckSubmissionSlotDetails(t *testing.T) { Timestamp: testSlot * common.SecondsPerSlot, }, Message: &builderApiV1.BidTrace{ - Slot: testSlot, + Slot: testSlot, + BuilderPubkey: builderPubkey, }, }, }, }, - expectOk: true, + expectOk: true, + mevCommitOptInStatus: true, }, { description: "non_capella_slot", @@ -1027,6 +1035,10 @@ func TestCheckSubmissionSlotDetails(t *testing.T) { Pubkey: validatorPubKey, }, }, + IsMevCommitValidator: tc.mevCommitOptInStatus, + } + backend.relay.blockBuildersCache[testBuilderPubkey] = &blockBuilderCacheEntry{ + mevCommitOptInStatus: tc.mevCommitOptInStatus, } ok := backend.relay.checkSubmissionSlotDetails(w, log, headSlot, tc.payload, submission) require.Equal(t, tc.expectOk, ok) @@ -1051,6 +1063,7 @@ func TestCheckBuilderEntry(t *testing.T) { status: common.BuilderStatus{ IsHighPrio: true, }, + mevCommitOptInStatus: true, }, pk: builderPubkey, expectOk: true, @@ -1090,8 +1103,11 @@ func TestCheckBuilderEntry(t *testing.T) { w := httptest.NewRecorder() logger := logrus.New() log := logrus.NewEntry(logger) - _, ok := backend.relay.checkBuilderEntry(w, log, builderPubkey) + entry, ok := backend.relay.checkBuilderEntry(w, log, builderPubkey) require.Equal(t, tc.expectOk, ok) + if ok { + require.Equal(t, tc.entry.mevCommitOptInStatus, entry.mevCommitOptInStatus) + } }) } } From f3c6bd991fe51c1aefd45de742ab756b16baf381 Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 7 Jan 2025 13:35:01 -0500 Subject: [PATCH 68/70] feat: minor update to event names in relay (#7) * chore: remove break as multibls keys * chore: update relay contracts-abi to v1.0.0 --- go.mod | 23 ++++++----- go.sum | 57 ++++++++++++++-------------- mevcommitclient/mev_commit_client.go | 18 +++++++-- services/housekeeper/housekeeper.go | 1 - 4 files changed, 53 insertions(+), 46 deletions(-) diff --git a/go.mod b/go.mod index 7f034769..3246ffd7 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/flashbots/mev-boost-relay -go 1.22 +go 1.23 toolchain go1.23.1 @@ -21,7 +21,7 @@ require ( github.com/jmoiron/sqlx v1.3.5 github.com/lib/pq v1.10.8 github.com/pkg/errors v0.9.1 - github.com/primev/mev-commit/contracts-abi v0.0.0-20240924081916-a1d9f63df193 + github.com/primev/mev-commit/contracts-abi v0.0.0-20241231214357-bfdb117ff3bc github.com/prometheus/client_golang v1.19.1 github.com/r3labs/sse/v2 v2.10.0 github.com/sirupsen/logrus v1.9.3 @@ -35,7 +35,7 @@ require ( go.opentelemetry.io/otel/sdk/metric v1.25.0 go.uber.org/atomic v1.11.0 golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 - golang.org/x/text v0.16.0 + golang.org/x/text v0.17.0 ) require ( @@ -58,7 +58,7 @@ require ( github.com/ethereum/c-kzg-4844 v1.0.0 // indirect github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect github.com/fatih/color v1.16.0 // indirect - github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/getsentry/sentry-go v0.28.1 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-logr/logr v1.4.1 // indirect @@ -70,7 +70,6 @@ require ( github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect - github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -83,13 +82,13 @@ require ( github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7 // indirect - github.com/rivo/uniseg v0.4.2 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/supranational/blst v0.3.13 // indirect github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect go.opentelemetry.io/otel/trace v1.25.0 // indirect - golang.org/x/sync v0.7.0 // indirect + golang.org/x/sync v0.8.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/protobuf v1.34.2 // indirect rsc.io/tmplfunc v0.0.3 // indirect @@ -101,16 +100,16 @@ require ( github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/ferranbt/fastssz v0.1.3 github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/klauspost/cpuid/v2 v2.2.7 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/rubenv/sql-migrate v1.5.2 github.com/spf13/pflag v1.0.5 // indirect github.com/tdewolff/parse v2.3.4+incompatible // indirect @@ -120,9 +119,9 @@ require ( github.com/yuin/gopher-lua v1.1.1 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.25.0 // indirect - golang.org/x/crypto v0.25.0 // indirect + golang.org/x/crypto v0.26.0 // indirect golang.org/x/net v0.27.0 // indirect - golang.org/x/sys v0.22.0 // indirect + golang.org/x/sys v0.26.0 // indirect gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 54d47c70..1ec46efb 100644 --- a/go.sum +++ b/go.sum @@ -85,8 +85,9 @@ github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXk github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= @@ -114,8 +115,8 @@ github.com/flashbots/go-utils v0.5.0 h1:ldjWta9B9//DJU2QcwRbErez3+1aKhSn6EoFc6d5 github.com/flashbots/go-utils v0.5.0/go.mod h1:LauDwifaRdSK0mS5X34GR59pJtUu1T/lOFNdff1BqtI= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= -github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/getsentry/sentry-go v0.28.1 h1:zzaSm/vHmGllRM6Tpx1492r0YDzauArdBfkJRtY6P5k= @@ -182,8 +183,6 @@ 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/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= -github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= -github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= @@ -240,8 +239,8 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= @@ -278,12 +277,13 @@ github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTw github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/poy/onpar v1.1.2 h1:QaNrNiZx0+Nar5dLgTVp5mXkyoVFIbepjyEoGSnhbAY= github.com/poy/onpar v1.1.2/go.mod h1:6X8FLNoxyr9kkmnlqpK6LSoiOtrO6MICtWwEuWkLjzg= -github.com/primev/mev-commit/contracts-abi v0.0.0-20240924081916-a1d9f63df193 h1:XF8Dyvm4wocRgkfqr9jDYYz065HITOgZ/D3rUgR1ZDQ= -github.com/primev/mev-commit/contracts-abi v0.0.0-20240924081916-a1d9f63df193/go.mod h1:TcPhQiI7UmkDTzVGlXlwMq+fmrQ5Sj1xDSSzePZ/rq0= +github.com/primev/mev-commit/contracts-abi v0.0.0-20241231214357-bfdb117ff3bc h1:WMZegHNIPDf2q0SjR3+JVh/rugu7uwZsGEe96prWBrQ= +github.com/primev/mev-commit/contracts-abi v0.0.0-20241231214357-bfdb117ff3bc/go.mod h1:mL/bQJ/w9iESK/eWYJSbgiZxMlg1o+w3WfbRVSHEbZs= github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= @@ -297,13 +297,13 @@ github.com/prysmaticlabs/go-bitfield v0.0.0-20210809151128-385d8c5e3fb7/go.mod h github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0= github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= -github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= -github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= +github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rubenv/sql-migrate v1.5.2 h1:bMDqOnrJVV/6JQgQ/MxOpU+AdO8uzYYA/TxFUBzFtS0= github.com/rubenv/sql-migrate v1.5.2/go.mod h1:H38GW8Vqf8F0Su5XignRyaRcbXbJunSWxs+kmzlg0Is= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -343,10 +343,10 @@ github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2n github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10 h1:CQh33pStIp/E30b7TxDlXfM0145bn2e8boI30IxAhTg= github.com/umbracle/gohashtree v0.0.2-alpha.0.20230207094856-5b775a815c10/go.mod h1:x/Pa0FF5Te9kdrlZKJK82YmAkvL8+f989USgz6Jiw7M= -github.com/urfave/cli/v2 v2.27.1 h1:8xSQ6szndafKVRmfyeUMxkNUJQMjL1F2zmsZ+qHpfho= -github.com/urfave/cli/v2 v2.27.1/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= -github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e h1:+SOyEddqYF09QP7vr7CgJ1eti3pY9Fn3LHO1M1r/0sI= -github.com/xrash/smetrics v0.0.0-20231213231151-1d8dd44e695e/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/urfave/cli/v2 v2.27.4 h1:o1owoI+02Eb+K107p27wEX9Bb8eqIoZCfLXloLUSWJ8= +github.com/urfave/cli/v2 v2.27.4/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M= @@ -375,8 +375,8 @@ golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30= -golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -396,8 +396,8 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -412,19 +412,18 @@ golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.22.0 h1:BbsgPEJULsl2fV/AT3v15Mjva5yXKQDyKf+TbDz7QJk= -golang.org/x/term v0.22.0/go.mod h1:F3qCibpT5AMpCRfhfT53vVJwhLtIVHhB9XDjfFvnMI4= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 943822c2..4ded7c61 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -105,7 +105,17 @@ func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys []string) ([]bool, pubkeysBytes[i] = common.Hex2Bytes(strings.TrimPrefix(pubkey, "0x")) } - return m.validatorOptInRouterCaller.AreValidatorsOptedIn(opts, pubkeysBytes) + optInStatuses, err := m.validatorOptInRouterCaller.AreValidatorsOptedIn(opts, pubkeysBytes) + if err != nil { + return nil, fmt.Errorf("failed to get opt-in status: %w", err) + } + + isOptedIn := make([]bool, len(optInStatuses)) + for i, status := range optInStatuses { + isOptedIn[i] = status.IsAvsOptedIn || status.IsVanillaOptedIn || status.IsMiddlewareOptedIn + } + + return isOptedIn, nil } func (m *MevCommitClient) ListenForBuildersEvents() (<-chan MevCommitProvider, <-chan common.Address, error) { @@ -125,13 +135,13 @@ func (m *MevCommitClient) ListenForBuildersEvents() (<-chan MevCommitProvider, < builderRegistryEventCh := make(chan MevCommitProvider) builderUnregisteredEventCh := make(chan common.Address) - providerRegisteredIterator, err := m.builderRegistryFilterer.FilterProviderRegistered(filterOpts, nil) + providerRegisteredIterator, err := m.builderRegistryFilterer.FilterBLSKeyAdded(filterOpts, nil) if err != nil { return nil, nil, fmt.Errorf("failed to filter ProviderRegistered events: %w", err) } - providerRegisteredEventCh := make(chan *providerRegistry.ProviderregistryProviderRegistered) - providerRegisteredSub, err := m.builderRegistryFilterer.WatchProviderRegistered(watchOpts, providerRegisteredEventCh, nil) + providerRegisteredEventCh := make(chan *providerRegistry.ProviderregistryBLSKeyAdded) + providerRegisteredSub, err := m.builderRegistryFilterer.WatchBLSKeyAdded(watchOpts, providerRegisteredEventCh, nil) if err != nil { providerRegisteredIterator.Close() return nil, nil, fmt.Errorf("failed to watch ProviderRegistered events: %w", err) diff --git a/services/housekeeper/housekeeper.go b/services/housekeeper/housekeeper.go index 881bbb74..9ba7174a 100644 --- a/services/housekeeper/housekeeper.go +++ b/services/housekeeper/housekeeper.go @@ -206,7 +206,6 @@ func (hk *Housekeeper) monitorMevCommitBuilderRegistrations() { if err != nil { hk.log.WithError(err).Errorf("failed to delete mev-commit block builder %s", builderAddress) } - break } } } From 2a6a1bf7cc70355e106130d3e52bd82e6ff2274d Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 7 Jan 2025 15:26:34 -0500 Subject: [PATCH 69/70] chore: bump contract addresses --- mevcommitclient/mev_commit_client_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mevcommitclient/mev_commit_client_test.go b/mevcommitclient/mev_commit_client_test.go index 976a3a66..bcce2e94 100644 --- a/mevcommitclient/mev_commit_client_test.go +++ b/mevcommitclient/mev_commit_client_test.go @@ -12,8 +12,8 @@ import ( const ( mevCommitRPC = "wss://chainrpc-wss.testnet.mev-commit.xyz" ethereumL1RPC = "https://ethereum-holesky-rpc.publicnode.com" - providerRegistryAddr = "0xf4F10e18244d836311508917A3B04694D88999Dd" - validatorOptInRouterAddr = "0xCae46e1013D33587180Db5933Abd75D977c2d7ab" + providerRegistryAddr = "0x1C2a592950E5dAd49c0E2F3A402DCF496bdf7b67" + validatorOptInRouterAddr = "0x251Fbc993f58cBfDA8Ad7b0278084F915aCE7fc3" ) func TestNewMevCommitClient(t *testing.T) { From 1af722effc6ed0d57d35dad7411c4c19e0c1549f Mon Sep 17 00:00:00 2001 From: Kartik Chopra Date: Tue, 14 Jan 2025 16:18:49 -0500 Subject: [PATCH 70/70] feat: graceful handling of RPC disconnect plus log improvements (#8) * feat: adds graceful handling of event processing * nit: fix client type * chore: updates client for iterated filtering * chore: remove nit log * chore: passes log into client --- cmd/housekeeper.go | 1 + mevcommitclient/mev_commit_client.go | 214 +++++++++++++--------- mevcommitclient/mev_commit_client_test.go | 86 ++++++++- 3 files changed, 204 insertions(+), 97 deletions(-) diff --git a/cmd/housekeeper.go b/cmd/housekeeper.go index 4a5f1c1a..a1b13a4a 100644 --- a/cmd/housekeeper.go +++ b/cmd/housekeeper.go @@ -96,6 +96,7 @@ var housekeeperCmd = &cobra.Command{ mevCommitRPC, gethCommon.HexToAddress(validatorOptInRouterAddr), gethCommon.HexToAddress(providerRegistryAddr), + log, ) if err != nil { log.WithError(err).Fatal("Failed to create mev-commit client") diff --git a/mevcommitclient/mev_commit_client.go b/mevcommitclient/mev_commit_client.go index 4ded7c61..55fc235c 100644 --- a/mevcommitclient/mev_commit_client.go +++ b/mevcommitclient/mev_commit_client.go @@ -6,8 +6,11 @@ package mevcommitclient import ( "context" "fmt" + "math" "math/big" + "math/rand/v2" "strings" + "time" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -15,6 +18,7 @@ import ( "github.com/ethereum/go-ethereum/ethclient" providerRegistry "github.com/primev/mev-commit/contracts-abi/clients/ProviderRegistry" validatoroptinrouter "github.com/primev/mev-commit/contracts-abi/clients/ValidatorOptInRouter" + "github.com/sirupsen/logrus" ) type MevCommitProvider struct { @@ -39,19 +43,24 @@ type MevCommitClient struct { l1Client *ethclient.Client mevCommitClient *ethclient.Client contractAbi abi.ABI + log *logrus.Entry } const ( abiJSON = `[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"builder","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"blsPublicKey","type":"bytes"}],"name":"BuilderRegistered","type":"event"},{"inputs":[{"internalType":"address","name":"builder","type":"address"}],"name":"isBuilderValid","outputs":[],"stateMutability":"view","type":"function"}]` ) -func NewMevCommitClient(l1MainnetURL, mevCommitURL string, validatorRouterAddress, ProviderRegistryAddress common.Address) (IMevCommitClient, error) { +func NewMevCommitClient(l1MainnetURL, mevCommitURL string, validatorRouterAddress, ProviderRegistryAddress common.Address, log *logrus.Entry) (IMevCommitClient, error) { l1Client, err := ethclient.Dial(l1MainnetURL) if err != nil { return nil, fmt.Errorf("failed to connect to L1 Mainnet: %w", err) } - - mevCommitClient, err := ethclient.Dial(mevCommitURL) + var mevCommitClient *ethclient.Client + if strings.HasPrefix(mevCommitURL, "ws") { + mevCommitClient, err = ethclient.DialContext(context.Background(), mevCommitURL) + } else { + mevCommitClient, err = ethclient.Dial(mevCommitURL) + } if err != nil { return nil, fmt.Errorf("failed to connect to mev-commit EVM: %w", err) } @@ -87,6 +96,7 @@ func NewMevCommitClient(l1MainnetURL, mevCommitURL string, validatorRouterAddres l1Client: l1Client, mevCommitClient: mevCommitClient, contractAbi: contractAbi, + log: log, }, nil } @@ -119,119 +129,141 @@ func (m *MevCommitClient) GetOptInStatusForValidators(pubkeys []string) ([]bool, } func (m *MevCommitClient) ListenForBuildersEvents() (<-chan MevCommitProvider, <-chan common.Address, error) { - latestBlock, err := m.mevCommitClient.BlockNumber(context.Background()) - if err != nil { - return nil, nil, fmt.Errorf("failed to get latest block number from mev-commit-geth: %w", err) - } - filterOpts := &bind.FilterOpts{ - Start: 0, - End: &latestBlock, - Context: context.Background(), - } - watchOpts := &bind.WatchOpts{ - Start: &latestBlock, - Context: context.Background(), - } builderRegistryEventCh := make(chan MevCommitProvider) builderUnregisteredEventCh := make(chan common.Address) + var blockRangeSize uint64 = 50000 + + // Create a context with cancellation for cleanup + ctx, cancel := context.WithCancel(context.Background()) + + // Start a polling goroutine + go func() { + defer close(builderRegistryEventCh) + defer close(builderUnregisteredEventCh) + defer cancel() + + backoff := time.Second + maxBackoff := time.Minute * 2 + + // Start from block 0 + lastProcessedBlock := uint64(0) + var processingError bool + var caughtUp bool + + for { + select { + case <-ctx.Done(): + return + default: + if caughtUp { + blockRangeSize = 5000 + } + if err := m.filterEvents(ctx, builderRegistryEventCh, builderUnregisteredEventCh, lastProcessedBlock, lastProcessedBlock+blockRangeSize); err != nil { + m.log.WithError(err).Error("Filter error") + // Mark that we had an error so we reprocess this chunk + processingError = true + // Exponential backoff with jitter + jitter := time.Duration(rand.Float64() * float64(backoff/4)) + time.Sleep(backoff + jitter) + backoff = time.Duration(math.Min(float64(backoff*2), float64(maxBackoff))) + continue + } + + // Only advance the block range if we successfully processed without errors + if !processingError { + lastProcessedBlock += blockRangeSize + } + processingError = false + + // Get current block to ensure we don't process future blocks + currentBlock, err := m.mevCommitClient.BlockNumber(context.Background()) + if err != nil { + m.log.WithError(err).Error("Failed to get current block number") + processingError = true + continue + } + // If we've caught up to the current block, wait before polling again + if lastProcessedBlock >= currentBlock { + m.log.WithField("currentBlock", currentBlock).Info("Caught up to current block, waiting before next poll") + lastProcessedBlock = currentBlock - blockRangeSize // Roll back to reprocess last chunk + caughtUp = true + time.Sleep(time.Second * 12) // Roughly one block time + } + // Reset backoff on successful filtering + backoff = time.Second + } + } + }() + + return builderRegistryEventCh, builderUnregisteredEventCh, nil +} - providerRegisteredIterator, err := m.builderRegistryFilterer.FilterBLSKeyAdded(filterOpts, nil) +func (m *MevCommitClient) filterEvents(ctx context.Context, builderRegistryEventCh chan MevCommitProvider, builderUnregisteredEventCh chan common.Address, fromBlock uint64, toBlock uint64) error { + // Calculate block range + currentBlock, err := m.mevCommitClient.BlockNumber(context.Background()) if err != nil { - return nil, nil, fmt.Errorf("failed to filter ProviderRegistered events: %w", err) + return fmt.Errorf("failed to get current block number: %w", err) + } + if toBlock > currentBlock { + toBlock = currentBlock } - providerRegisteredEventCh := make(chan *providerRegistry.ProviderregistryBLSKeyAdded) - providerRegisteredSub, err := m.builderRegistryFilterer.WatchBLSKeyAdded(watchOpts, providerRegisteredEventCh, nil) - if err != nil { - providerRegisteredIterator.Close() - return nil, nil, fmt.Errorf("failed to watch ProviderRegistered events: %w", err) + filterOpts := &bind.FilterOpts{ + Start: fromBlock, + End: &toBlock, + Context: ctx, } - providerSlashedIterator, err := m.builderRegistryFilterer.FilterFundsSlashed(filterOpts, nil) + m.log.WithFields(logrus.Fields{ + "fromBlock": fromBlock, + "toBlock": toBlock, + }).Debug("Filtering events") + + // Filter BLSKeyAdded events + blsKeyEvents, err := m.builderRegistryFilterer.FilterBLSKeyAdded(filterOpts, nil) if err != nil { - providerRegisteredIterator.Close() - providerRegisteredSub.Unsubscribe() - return nil, nil, fmt.Errorf("failed to filter FundsSlashed events: %w", err) + return fmt.Errorf("failed to filter BLSKeyAdded events: %w", err) } + defer blsKeyEvents.Close() - providerSlashedEventCh := make(chan *providerRegistry.ProviderregistryFundsSlashed) - providerSlashedSub, err := m.builderRegistryFilterer.WatchFundsSlashed(watchOpts, providerSlashedEventCh, nil) + // Filter FundsSlashed events + fundsSlashedEvents, err := m.builderRegistryFilterer.FilterFundsSlashed(filterOpts, nil) if err != nil { - providerRegisteredIterator.Close() - providerSlashedIterator.Close() - providerRegisteredSub.Unsubscribe() - return nil, nil, fmt.Errorf("failed to watch ProviderSlashed events: %w", err) + return fmt.Errorf("failed to filter FundsSlashed events: %w", err) } + defer fundsSlashedEvents.Close() - go func() { - defer providerRegisteredIterator.Close() - defer providerRegisteredSub.Unsubscribe() - - for providerRegisteredIterator.Next() { - event := providerRegisteredIterator.Event + // Process BLSKeyAdded events + for blsKeyEvents.Next() { + select { + case <-ctx.Done(): + return nil + default: builderRegistryEventCh <- MevCommitProvider{ - Pubkey: event.BlsPublicKey, - EOAAddress: event.Provider, - } - } - if err := providerRegisteredIterator.Error(); err != nil { - fmt.Printf("error while iterating ProviderRegistered events: %v\n", err) - } - - for { - select { - case err := <-providerRegisteredSub.Err(): - fmt.Printf("error in ProviderRegistered subscription: %v\n", err) - close(builderRegistryEventCh) - return - case event := <-providerRegisteredEventCh: - builderRegistryEventCh <- MevCommitProvider{ - Pubkey: event.BlsPublicKey, - EOAAddress: event.Provider, - } + Pubkey: blsKeyEvents.Event.BlsPublicKey, + EOAAddress: blsKeyEvents.Event.Provider, } } - }() - - go func() { - defer providerSlashedSub.Unsubscribe() - defer providerSlashedIterator.Close() + } - for providerSlashedIterator.Next() { - event := providerSlashedIterator.Event - isValid, err := m.IsBuilderValid(event.Provider) + // Process FundsSlashed events + for fundsSlashedEvents.Next() { + select { + case <-ctx.Done(): + return nil + default: + isValid, err := m.IsBuilderValid(fundsSlashedEvents.Event.Provider) if err != nil { - fmt.Printf("failed to check if builder is valid: %v\n", err) + m.log.WithError(err).Error("Failed to check if builder is valid") continue } if !isValid { - builderUnregisteredEventCh <- event.Provider - } - } - if err := providerSlashedIterator.Error(); err != nil { - fmt.Printf("error while iterating FundsSlashed events: %v\n", err) - } - - for { - select { - case err := <-providerSlashedSub.Err(): - fmt.Printf("error while watching ProviderSlashed events: %v\n", err) - close(builderUnregisteredEventCh) - return - case event := <-providerSlashedEventCh: - isValid, err := m.IsBuilderValid(event.Provider) - if err != nil { - fmt.Printf("failed to check if builder is valid: %v\n", err) - continue - } - if !isValid { - builderUnregisteredEventCh <- event.Provider - } + builderUnregisteredEventCh <- fundsSlashedEvents.Event.Provider } } - }() + } - return builderRegistryEventCh, builderUnregisteredEventCh, nil + return nil } func (m *MevCommitClient) IsBuilderValid(builderAddress common.Address) (bool, error) { diff --git a/mevcommitclient/mev_commit_client_test.go b/mevcommitclient/mev_commit_client_test.go index bcce2e94..6fc58fb7 100644 --- a/mevcommitclient/mev_commit_client_test.go +++ b/mevcommitclient/mev_commit_client_test.go @@ -1,10 +1,12 @@ package mevcommitclient import ( + "context" "testing" "time" "github.com/ethereum/go-ethereum/common" + "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -16,12 +18,20 @@ const ( validatorOptInRouterAddr = "0x251Fbc993f58cBfDA8Ad7b0278084F915aCE7fc3" ) +func setupTestLogger() *logrus.Entry { + logger := logrus.New() + logger.SetLevel(logrus.DebugLevel) + return logger.WithField("test", true) +} + func TestNewMevCommitClient(t *testing.T) { + log := setupTestLogger() client, err := NewMevCommitClient( ethereumL1RPC, mevCommitRPC, common.HexToAddress(validatorOptInRouterAddr), common.HexToAddress(providerRegistryAddr), + log, ) require.NoError(t, err) require.NotNil(t, client) @@ -33,14 +43,17 @@ func TestNewMevCommitClient(t *testing.T) { assert.Equal(t, mevCommitRPC, mevClient.MevCommitAddress) assert.Equal(t, common.HexToAddress(validatorOptInRouterAddr), mevClient.ValidatorRouterAddress) assert.Equal(t, common.HexToAddress(providerRegistryAddr), mevClient.ProviderRegistryAddress) + assert.NotNil(t, mevClient.log) } func TestGetOptInStatusForValidators(t *testing.T) { + log := setupTestLogger() client, err := NewMevCommitClient( ethereumL1RPC, mevCommitRPC, common.HexToAddress(validatorOptInRouterAddr), common.HexToAddress(providerRegistryAddr), + log, ) require.NoError(t, err) // Test with some sample public keys @@ -60,37 +73,98 @@ func TestGetOptInStatusForValidators(t *testing.T) { } } +func TestListenForBuildersEventsForever(t *testing.T) { + if testing.Short() { + t.Skip("Skipping long-running test in short mode") + } + + log := setupTestLogger() + client, err := NewMevCommitClient( + ethereumL1RPC, + mevCommitRPC, + common.HexToAddress(validatorOptInRouterAddr), + common.HexToAddress(providerRegistryAddr), + log, + ) + require.NoError(t, err) + + builderRegisteredCh, builderUnregisteredCh, err := client.ListenForBuildersEvents() + require.NoError(t, err) + + // Create a context with cancel to allow clean shutdown + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // Create channels to track events + registeredBuilders := make(map[common.Address][]byte) + unregisteredBuilders := make(map[common.Address]bool) + + // Start goroutine to handle events + go func() { + for { + select { + case builder := <-builderRegisteredCh: + t.Logf("Builder registered - Address: %v, BLS Key: %x", builder.EOAAddress, builder.Pubkey) + registeredBuilders[builder.EOAAddress] = builder.Pubkey + case address := <-builderUnregisteredCh: + t.Logf("Builder unregistered - Address: %v", address) + unregisteredBuilders[address] = true + case <-ctx.Done(): + return + } + } + }() + + // Let it run for a while + time.Sleep(1200 * time.Second) + + t.Logf("Total registered builders: %d", len(registeredBuilders)) + t.Logf("Total unregistered builders: %d", len(unregisteredBuilders)) +} + func TestListenForBuildersEvents(t *testing.T) { + log := setupTestLogger() client, err := NewMevCommitClient( ethereumL1RPC, mevCommitRPC, common.HexToAddress(validatorOptInRouterAddr), common.HexToAddress(providerRegistryAddr), + log, ) require.NoError(t, err) - builderRegisteredCh, _, err := client.ListenForBuildersEvents() + builderRegisteredCh, builderUnregisteredCh, err := client.ListenForBuildersEvents() require.NoError(t, err) + // Create a channel to signal when we receive an event + eventReceived := make(chan struct{}) + go func() { select { - case <-builderRegisteredCh: + case builder := <-builderRegisteredCh: + t.Logf("Builder registered - Address: %v", builder) + eventReceived <- struct{}{} + case address := <-builderUnregisteredCh: + t.Logf("Builder unregistered - Address: %v", address) + eventReceived <- struct{}{} case <-time.After(10 * time.Second): - t.Log("No events received after 10 seconds") - t.Fail() + t.Error("Timeout waiting for builder event") + eventReceived <- struct{}{} } }() - time.Sleep(15 * time.Second) - + // Wait for one event + <-eventReceived } func TestGetOptInStatusForSpecificValidator(t *testing.T) { + log := setupTestLogger() client, err := NewMevCommitClient( ethereumL1RPC, mevCommitRPC, common.HexToAddress(validatorOptInRouterAddr), common.HexToAddress(providerRegistryAddr), + log, ) require.NoError(t, err)