diff --git a/infrastructure/nomad/playbooks/templates/jobs/mev-commit.nomad.j2 b/infrastructure/nomad/playbooks/templates/jobs/mev-commit.nomad.j2 index c238c43fc..5a0843a3e 100644 --- a/infrastructure/nomad/playbooks/templates/jobs/mev-commit.nomad.j2 +++ b/infrastructure/nomad/playbooks/templates/jobs/mev-commit.nomad.j2 @@ -83,6 +83,7 @@ job "{{ job.name }}" { data = <<-EOH MEV_COMMIT_LOG_FMT="{{ job.env.get('log-format', 'json') }}" MEV_COMMIT_LOG_TAGS="{{ 'service.name:' + job.name + '-{{ env "NOMAD_ALLOC_INDEX" }}' + ',service.version:' + version }}" + MEV_COMMIT_LAGGARD_MODE="{{ job.env.get('laggard-mode', '10') }}" MEV_COMMIT_OTEL_COLLECTOR_ENDPOINT_URL="{{ job.env.get('otel_collector_endpoint_url', '') }}" {%- raw %} MEV_COMMIT_KEYSTORE_PATH="/local/data-{{ env "NOMAD_ALLOC_INDEX" }}/keystore" diff --git a/p2p/cmd/main.go b/p2p/cmd/main.go index 64b71a980..be7d81eba 100644 --- a/p2p/cmd/main.go +++ b/p2p/cmd/main.go @@ -430,6 +430,14 @@ var ( Value: 30 * time.Second, Category: categoryProvider, }) + + optionLaggardMode = altsrc.NewIntFlag(&cli.IntFlag{ + Name: "laggard-mode", + Usage: "No of blocks to lag behind for L1 chain when fetching validator duties", + EnvVars: []string{"MEV_COMMIT_LAGGARD_MODE"}, + Value: 10, + Category: categoryEthRPC, + }) ) func main() { @@ -649,6 +657,7 @@ func launchNodeWithConfig(c *cli.Context) (err error) { OracleWindowOffset: big.NewInt(defaultOracleWindowOffset), BeaconAPIURL: c.String(optionBeaconAPIURL.Name), L1RPCURL: c.String(optionL1RPCURL.Name), + LaggardMode: big.NewInt(int64(c.Int(optionLaggardMode.Name))), BidderBidTimeout: c.Duration(optionBidderBidTimeout.Name), ProviderDecisionTimeout: c.Duration(optionProviderDecisionTimeout.Name), }) diff --git a/p2p/pkg/node/node.go b/p2p/pkg/node/node.go index 6102284a6..d5e7bd0d1 100644 --- a/p2p/pkg/node/node.go +++ b/p2p/pkg/node/node.go @@ -101,6 +101,7 @@ type Options struct { OracleWindowOffset *big.Int BeaconAPIURL string L1RPCURL string + LaggardMode *big.Int BidderBidTimeout time.Duration ProviderDecisionTimeout time.Duration } @@ -416,17 +417,24 @@ func NewNode(opts *Options) (*Node, error) { return nil, err } - validatorRouterSession := &validatorrouter.ValidatoroptinrouterCallerSession{ - Contract: validatorRouterCaller, - CallOpts: bind.CallOpts{ - From: opts.KeySigner.GetAddress(), - }, + callOptsGetter := func() (*bind.CallOpts, error) { + blkNum, err := l1ContractRPC.BlockNumber(context.Background()) + if err != nil { + return nil, err + } + currentBlkNum := big.NewInt(0).SetUint64(blkNum) + queryBlkNum := big.NewInt(0).Sub(currentBlkNum, opts.LaggardMode) + return &bind.CallOpts{ + From: opts.KeySigner.GetAddress(), + BlockNumber: queryBlkNum, + }, nil } validatorAPI := validatorapi.NewService( opts.BeaconAPIURL, - validatorRouterSession, + validatorRouterCaller, opts.Logger.With("component", "validatorapi"), + callOptsGetter, ) validatorapiv1.RegisterValidatorServer(grpcServer, validatorAPI) diff --git a/p2p/pkg/rpc/validator/service.go b/p2p/pkg/rpc/validator/service.go index 80c1d99af..1c40f3d83 100644 --- a/p2p/pkg/rpc/validator/service.go +++ b/p2p/pkg/rpc/validator/service.go @@ -10,6 +10,7 @@ import ( "strconv" "strings" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common/hexutil" validatoroptinrouter "github.com/primev/mev-commit/contracts-abi/clients/ValidatorOptInRouter" validatorapiv1 "github.com/primev/mev-commit/p2p/gen/go/validatorapi/v1" @@ -18,7 +19,7 @@ import ( ) type ValidatorRouterContract interface { - AreValidatorsOptedIn(valBLSPubKeys [][]byte) ([]validatoroptinrouter.IValidatorOptInRouterOptInStatus, error) + AreValidatorsOptedIn(opts *bind.CallOpts, valBLSPubKeys [][]byte) ([]validatoroptinrouter.IValidatorOptInRouterOptInStatus, error) } type Service struct { @@ -27,14 +28,21 @@ type Service struct { validatorRouter ValidatorRouterContract logger *slog.Logger metrics *metrics + optsGetter func() (*bind.CallOpts, error) } -func NewService(apiURL string, validatorRouter ValidatorRouterContract, logger *slog.Logger) *Service { +func NewService( + apiURL string, + validatorRouter ValidatorRouterContract, + logger *slog.Logger, + optsGetter func() (*bind.CallOpts, error), +) *Service { return &Service{ apiURL: apiURL, validatorRouter: validatorRouter, logger: logger, metrics: newMetrics(), + optsGetter: optsGetter, } } @@ -177,7 +185,17 @@ func (s *Service) processValidators(dutiesResp *ProposerDutiesResponse) (map[uin validatorsKeys = append(validatorsKeys, pubkeyBytes) } - areValidatorsOptedIn, err := s.validatorRouter.AreValidatorsOptedIn(validatorsKeys) + if len(validatorsKeys) == 0 { + return validators, nil + } + + opts, err := s.optsGetter() + if err != nil { + s.logger.Error("getting call opts", "error", err) + return nil, status.Errorf(codes.Internal, "getting call opts: %v", err) + } + + areValidatorsOptedIn, err := s.validatorRouter.AreValidatorsOptedIn(opts, validatorsKeys) if err != nil { s.logger.Error("checking if validators are opted in", "error", err) return nil, status.Errorf(codes.Internal, "checking if validators are opted in: %v", err) diff --git a/p2p/pkg/rpc/validator/service_test.go b/p2p/pkg/rpc/validator/service_test.go index 0b6e65794..e6b0fd45b 100644 --- a/p2p/pkg/rpc/validator/service_test.go +++ b/p2p/pkg/rpc/validator/service_test.go @@ -9,6 +9,7 @@ import ( "os" "testing" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common/hexutil" validatoroptinrouter "github.com/primev/mev-commit/contracts-abi/clients/ValidatorOptInRouter" validatorapiv1 "github.com/primev/mev-commit/p2p/gen/go/validatorapi/v1" @@ -22,7 +23,7 @@ type MockValidatorRouterContract struct { ExpectedCalls map[string]interface{} } -func (m *MockValidatorRouterContract) AreValidatorsOptedIn(valBLSPubKeys [][]byte) ([]validatoroptinrouter.IValidatorOptInRouterOptInStatus, error) { +func (m *MockValidatorRouterContract) AreValidatorsOptedIn(_ *bind.CallOpts, valBLSPubKeys [][]byte) ([]validatoroptinrouter.IValidatorOptInRouterOptInStatus, error) { results := make([]validatoroptinrouter.IValidatorOptInRouterOptInStatus, len(valBLSPubKeys)) for i, key := range valBLSPubKeys { if m.ExpectedCalls[string(key)] == nil { @@ -56,8 +57,12 @@ func TestGetValidators(t *testing.T) { }, } + optsGetter := func() (*bind.CallOpts, error) { + return &bind.CallOpts{}, nil + } + logger := util.NewTestLogger(os.Stdout) - service := validatorapi.NewService(mockServer.URL, mockValidatorRouter, logger) + service := validatorapi.NewService(mockServer.URL, mockValidatorRouter, logger, optsGetter) req := &validatorapiv1.GetValidatorsRequest{Epoch: 123} resp, err := service.GetValidators(context.Background(), req) @@ -85,9 +90,13 @@ func TestGetValidators_HTTPError(t *testing.T) { })) defer mockServer.Close() + optsGetter := func() (*bind.CallOpts, error) { + return &bind.CallOpts{}, nil + } + mockValidatorRouter := &MockValidatorRouterContract{} logger := util.NewTestLogger(os.Stdout) - service := validatorapi.NewService(mockServer.URL, mockValidatorRouter, logger) + service := validatorapi.NewService(mockServer.URL, mockValidatorRouter, logger, optsGetter) req := &validatorapiv1.GetValidatorsRequest{Epoch: 123} _, err := service.GetValidators(context.Background(), req) @@ -125,8 +134,12 @@ func TestGetValidators_EpochZero(t *testing.T) { }, } + optsGetter := func() (*bind.CallOpts, error) { + return &bind.CallOpts{}, nil + } + logger := util.NewTestLogger(os.Stdout) - service := validatorapi.NewService(mockServer.URL, mockValidatorRouter, logger) + service := validatorapi.NewService(mockServer.URL, mockValidatorRouter, logger, optsGetter) req := &validatorapiv1.GetValidatorsRequest{Epoch: 0} resp, err := service.GetValidators(context.Background(), req)