From 846adf1eaa3e0a28e4b78585ebba9fa56e351126 Mon Sep 17 00:00:00 2001 From: Marcelo Politzer <251334+mpolitzer@users.noreply.github.com> Date: Wed, 13 Nov 2024 15:35:02 -0300 Subject: [PATCH] feat(claimer): Make claim submission optional. --- Makefile | 1 + cmd/cartesi-rollups-claimer/root/root.go | 9 +++++- cmd/cartesi-rollups-node/root/root.go | 18 +++++++++++ internal/claimer/claimer.go | 16 ++++++---- internal/claimer/claimer_test.go | 40 ++++++++++++++++++++++++ internal/config/config.go | 4 ++- internal/config/generate/Config.toml | 6 ++++ internal/config/generated.go | 12 +++++++ 8 files changed, 98 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index 20940c8fb..781500d5c 100644 --- a/Makefile +++ b/Makefile @@ -78,6 +78,7 @@ env: @echo export CARTESI_POSTGRES_ENDPOINT="postgres://postgres:password@localhost:5432/rollupsdb?sslmode=disable" @echo export CARTESI_TEST_POSTGRES_ENDPOINT="postgres://test_user:password@localhost:5432/test_rollupsdb?sslmode=disable" @echo export CARTESI_TEST_MACHINE_IMAGES_PATH=\"$(CARTESI_TEST_MACHINE_IMAGES_PATH)\" + @echo export CARTESI_FEATURE_CLAIMER_SUBMISSION_ENABLED=true @echo export PATH=$(CURDIR):$$PATH # ============================================================================= diff --git a/cmd/cartesi-rollups-claimer/root/root.go b/cmd/cartesi-rollups-claimer/root/root.go index 836726af5..bd290756d 100644 --- a/cmd/cartesi-rollups-claimer/root/root.go +++ b/cmd/cartesi-rollups-claimer/root/root.go @@ -26,6 +26,7 @@ var ( TelemetryAddress: ":8081", Impl: &claimerService, }, + EnableSubmission: true, } ) @@ -38,7 +39,6 @@ var Cmd = &cobra.Command{ func init() { c := config.FromEnv() - createInfo.Auth = c.Auth createInfo.BlockchainHttpEndpoint = c.BlockchainHttpEndpoint createInfo.PostgresEndpoint = c.PostgresEndpoint createInfo.PollInterval = c.ClaimerPollingInterval @@ -48,6 +48,10 @@ func init() { slog.LevelWarn: "warn", slog.LevelError: "error", }[c.LogLevel] + createInfo.EnableSubmission = c.FeatureClaimerSubmissionEnabled + if createInfo.EnableSubmission { + createInfo.Auth = c.Auth + } Cmd.Flags().StringVar(&createInfo.TelemetryAddress, "telemetry-address", createInfo.TelemetryAddress, @@ -61,6 +65,9 @@ func init() { Cmd.Flags().StringVar(&createInfo.LogLevel, "log-level", createInfo.LogLevel, "log level: debug, info, warn, error.") + Cmd.Flags().BoolVar(&createInfo.EnableSubmission, + "enable-submission", createInfo.EnableSubmission, + "enable submission in addition to verification.") } func run(cmd *cobra.Command, args []string) { diff --git a/cmd/cartesi-rollups-node/root/root.go b/cmd/cartesi-rollups-node/root/root.go index 91e96282b..f9241df84 100644 --- a/cmd/cartesi-rollups-node/root/root.go +++ b/cmd/cartesi-rollups-node/root/root.go @@ -30,14 +30,32 @@ var ( Long: "Runs the Cartesi Rollups Node as a single process", RunE: run, } + enableClaimSubmissionOverride bool ) +func init() { + Cmd.Flags().BoolVar(&enableClaimSubmissionOverride, + "enable-submission", true, + "enable submission in addition to verification.") +} + func run(cmd *cobra.Command, args []string) error { startTime := time.Now() ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM) defer stop() + // hack: change the environment variable according to the command line flag + // such that auth only gets loaded when claimer submission is enabled. + if cmd.Flags().Lookup("enable-submission").Changed { + var value string + if enableClaimSubmissionOverride { + value = "1" + } else { + value = "0" + } + os.Setenv("CARTESI_FEATURE_CLAIMER_SUBMISSION_ENABLED", value) + } config := config.FromEnv() // setup log diff --git a/internal/claimer/claimer.go b/internal/claimer/claimer.go index f50a2fc0b..f111d6a60 100644 --- a/internal/claimer/claimer.go +++ b/internal/claimer/claimer.go @@ -28,6 +28,8 @@ type CreateInfo struct { PostgresEndpoint Redacted[string] DBConn *Database + + EnableSubmission bool } type claimKey struct { @@ -38,10 +40,11 @@ type claimKey struct { type Service struct { service.Service - DBConn *Database - EthConn *ethclient.Client - Signer *bind.TransactOpts - ClaimsInFlight map[claimKey]Hash // -> txHash + submissionEnabled bool + DBConn *Database + EthConn *ethclient.Client + Signer *bind.TransactOpts + ClaimsInFlight map[claimKey]Hash // -> txHash } func Create(ci CreateInfo, s *Service) error { @@ -52,6 +55,7 @@ func Create(ci CreateInfo, s *Service) error { return err } + s.submissionEnabled = ci.EnableSubmission if s.EthConn == nil { if ci.EthConn == nil { ci.EthConn, err = ethclient.Dial(ci.BlockchainHttpEndpoint.Value) @@ -76,7 +80,7 @@ func Create(ci CreateInfo, s *Service) error { s.ClaimsInFlight = map[claimKey]Hash{} } - if s.Signer == nil { + if s.Signer == nil && s.submissionEnabled { if ci.Signer == nil { ci.Signer, err = CreateSignerFromAuth(ci.Auth, s.Context, s.EthConn) if err != nil { @@ -234,7 +238,7 @@ func (s *Service) submitClaimsAndUpdateDatabase(se SideEffects) error { } // submit if not found in the logs (fetch from hash again, can be stale) - if claim, ok := computedClaimsMap[key]; ok { + if claim, ok := computedClaimsMap[key]; ok && s.submissionEnabled { s.Logger.Info("Submitting claim to blockchain", "app", claim.AppContractAddress, "claim", claim.Hash, diff --git a/internal/claimer/claimer_test.go b/internal/claimer/claimer_test.go index 7345938ee..ea4559e79 100644 --- a/internal/claimer/claimer_test.go +++ b/internal/claimer/claimer_test.go @@ -80,6 +80,7 @@ func newServiceMock() *ServiceMock { Service: service.Service{ Logger: slog.Default(), }, + submissionEnabled: true, }, } } @@ -162,6 +163,45 @@ func TestSubmitNewClaim(t *testing.T) { m.AssertNumberOfCalls(t, "updateEpochWithSubmittedClaim", 0) } +// Got a claim, don't submit. +func TestSubmitNewClaimDisabled(t *testing.T) { + m := newServiceMock() + m.submissionEnabled = false + + newClaimHash := HexToHash("0x01") + newClaimTxHash := HexToHash("0x10") + newClaim := ComputedClaim{ + Hash: newClaimHash, + } + m.ClaimsInFlight = map[claimKey]Hash{} + m.On("selectComputedClaims").Return([]ComputedClaim{ + newClaim, + }, nil) + m.On("submitClaimToBlockchain", nil, nil, &newClaim). + Return(newClaimTxHash, nil) + + itMock := &ClaimSubmissionIteratorMock{} + itMock.On("Next").Return(false) + itMock.On("Error").Return(nil) + + m.On("enumerateSubmitClaimEventsSince"). + Return(itMock, &iconsensus.IConsensus{}, nil) + m.On("pollTransaction", newClaimTxHash). + Return(false, &types.Receipt{}, nil) + assert.Equal(t, len(m.ClaimsInFlight), 0) + + err := m.submitClaimsAndUpdateDatabase(m) + assert.Nil(t, err) + + assert.Equal(t, len(m.ClaimsInFlight), 0) + m.AssertNumberOfCalls(t, "enumerateSubmitClaimEventsSince", 1) + m.AssertNumberOfCalls(t, "pollTransaction", 0) + m.AssertNumberOfCalls(t, "selectComputedClaims", 1) + m.AssertNumberOfCalls(t, "submitClaimToBlockchain", 0) + m.AssertNumberOfCalls(t, "updateEpochWithSubmittedClaim", 0) +} + + // Query the blockchain for the submitClaim transaction, it may not be ready yet func TestClaimInFlightNotReadyDoesNothing(t *testing.T) { m := newServiceMock() diff --git a/internal/config/config.go b/internal/config/config.go index d4610121c..415cc7dc1 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -33,6 +33,7 @@ type NodeConfig struct { HttpAddress string HttpPort int FeatureClaimerEnabled bool + FeatureClaimerSubmissionEnabled bool FeatureMachineHashCheckEnabled bool Auth Auth AdvancerPollingInterval Duration @@ -92,8 +93,9 @@ func FromEnv() NodeConfig { config.HttpAddress = GetHttpAddress() config.HttpPort = GetHttpPort() config.FeatureClaimerEnabled = GetFeatureClaimerEnabled() + config.FeatureClaimerSubmissionEnabled = GetFeatureClaimerSubmissionEnabled() config.FeatureMachineHashCheckEnabled = GetFeatureMachineHashCheckEnabled() - if config.FeatureClaimerEnabled { + if config.FeatureClaimerEnabled && config.FeatureClaimerSubmissionEnabled { config.Auth = authFromEnv() } config.AdvancerPollingInterval = GetAdvancerPollingInterval() diff --git a/internal/config/generate/Config.toml b/internal/config/generate/Config.toml index b1112d755..bd8591282 100644 --- a/internal/config/generate/Config.toml +++ b/internal/config/generate/Config.toml @@ -25,6 +25,12 @@ go-type = "bool" description = """ If set to false, the node will not make claims.""" +[features.CARTESI_FEATURE_CLAIMER_SUBMISSION_ENABLED] +default = "true" +go-type = "bool" +description = """ +If set to false, the node will not submit claims.""" + [features.CARTESI_FEATURE_MACHINE_HASH_CHECK_ENABLED] default = "true" go-type = "bool" diff --git a/internal/config/generated.go b/internal/config/generated.go index b5f011102..21c52dd49 100644 --- a/internal/config/generated.go +++ b/internal/config/generated.go @@ -336,6 +336,18 @@ func GetFeatureClaimerEnabled() bool { return val } +func GetFeatureClaimerSubmissionEnabled() bool { + s, ok := os.LookupEnv("CARTESI_FEATURE_CLAIMER_SUBMISSION_ENABLED") + if !ok { + s = "true" + } + val, err := toBool(s) + if err != nil { + panic(fmt.Sprintf("failed to parse CARTESI_FEATURE_CLAIMER_SUBMISSION_ENABLED: %v", err)) + } + return val +} + func GetFeatureMachineHashCheckEnabled() bool { s, ok := os.LookupEnv("CARTESI_FEATURE_MACHINE_HASH_CHECK_ENABLED") if !ok {