From e35d472eb30978f32a071d0d4c58503443afcbe1 Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Tue, 8 Apr 2025 17:20:31 +0000 Subject: [PATCH 1/9] Add backup ability to run with repl console --- .github/workflows/test.yml | 1 + aggregator/aggregator.go | 4 +- aggregator/repl.go | 37 +++++++++++++ config/operator_sample.yaml | 5 ++ core/backup/backup.go | 105 ++++++++++++++++++++++++++++++++++++ core/backup/backup_test.go | 83 ++++++++++++++++++++++++++++ core/config/config.go | 20 +++++++ storage/db.go | 13 +++++ 8 files changed, 267 insertions(+), 1 deletion(-) create mode 100644 core/backup/backup.go create mode 100644 core/backup/backup_test.go diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cb0bbd44..e89cb93b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -20,6 +20,7 @@ jobs: - pkg/graphql - pkg/byte4 - pkg/erc4337/preset + - core/backup steps: - uses: actions/checkout@v4 diff --git a/aggregator/aggregator.go b/aggregator/aggregator.go index 64f71ca8..9b0216b8 100644 --- a/aggregator/aggregator.go +++ b/aggregator/aggregator.go @@ -234,11 +234,12 @@ func (agg *Aggregator) Start(ctx context.Context) error { agg.init() - agg.logger.Infof("Initialize Storagre") + agg.logger.Infof("Initialize Storage") if err := agg.initDB(ctx); err != nil { agg.logger.Fatalf("failed to initialize storage", "error", err) } + agg.logger.Infof("Starting Task engine") agg.startTaskEngine(ctx) @@ -268,6 +269,7 @@ func (agg *Aggregator) Start(ctx context.Context) error { agg.status = shutdownStatus agg.stopRepl() agg.stopTaskEngine() + agg.db.Close() return nil diff --git a/aggregator/repl.go b/aggregator/repl.go index 81b4fc89..2601076c 100644 --- a/aggregator/repl.go +++ b/aggregator/repl.go @@ -2,11 +2,14 @@ package aggregator import ( "bufio" + "context" "fmt" "log" "net" "os" + "path/filepath" "strings" + "time" ) var ( @@ -140,6 +143,40 @@ func handleConnection(agg *Aggregator, conn net.Conn) { case "trigger": fmt.Fprintln(conn, "about to trigger on server") //agg.engine.TriggerWith + + case "backup": + if len(parts) == 2 { + backupDir := parts[1] + fmt.Fprintf(conn, "Starting backup to directory: %s\n", backupDir) + + timestamp := fmt.Sprintf("%s", time.Now().Format("06-01-02-15-04")) + backupPath := filepath.Join(backupDir, timestamp) + + if err := os.MkdirAll(backupPath, 0755); err != nil { + fmt.Fprintf(conn, "Failed to create backup directory: %v\n", err) + break + } + + backupFile := filepath.Join(backupPath, "badger.backup") + f, err := os.Create(backupFile) + if err != nil { + fmt.Fprintf(conn, "Failed to create backup file: %v\n", err) + break + } + + fmt.Fprintf(conn, "Running backup to %s\n", backupFile) + since := uint64(0) // Full backup + _, err = agg.db.Backup(context.Background(), f, since) + f.Close() + + if err != nil { + fmt.Fprintf(conn, "Backup failed: %v\n", err) + } else { + fmt.Fprintf(conn, "Backup completed successfully to %s\n", backupFile) + } + } else { + fmt.Fprintln(conn, "Usage: backup ") + } default: fmt.Fprintln(conn, "Unknown command:", command) diff --git a/config/operator_sample.yaml b/config/operator_sample.yaml index 290d854b..c6a5c08b 100644 --- a/config/operator_sample.yaml +++ b/config/operator_sample.yaml @@ -32,6 +32,11 @@ enable_node_api: true db_path: /tmp/ap-avs-operator +backup: + enabled: false + interval_minutes: 60 + backup_dir: "./backup" + # Destination chain where the task run, relace with your actualy target chain target_chain: eth_rpc_url: diff --git a/core/backup/backup.go b/core/backup/backup.go new file mode 100644 index 00000000..08e6ed9c --- /dev/null +++ b/core/backup/backup.go @@ -0,0 +1,105 @@ +package backup + +import ( + "context" + "fmt" + "os" + "path/filepath" + "time" + + "github.com/AvaProtocol/ap-avs/storage" + "github.com/Layr-Labs/eigensdk-go/logging" +) + +type Service struct { + logger logging.Logger + db storage.Storage + backupDir string + backupEnabled bool + interval time.Duration + stop chan struct{} +} + +func NewService(logger logging.Logger, db storage.Storage, backupDir string) *Service { + return &Service{ + logger: logger, + db: db, + backupDir: backupDir, + backupEnabled: false, + stop: make(chan struct{}), + } +} + +func (s *Service) StartPeriodicBackup(interval time.Duration) error { + if s.backupEnabled { + return fmt.Errorf("backup service already running") + } + + if err := os.MkdirAll(s.backupDir, 0755); err != nil { + return fmt.Errorf("failed to create backup directory: %v", err) + } + + s.interval = interval + s.backupEnabled = true + + if err := s.PerformBackup(); err != nil { + s.logger.Errorf("Initial backup failed: %v", err) + } + + go s.backupLoop() + + s.logger.Infof("Started periodic backup every %v to %s", interval, s.backupDir) + return nil +} + +func (s *Service) StopPeriodicBackup() { + if !s.backupEnabled { + return + } + + s.backupEnabled = false + close(s.stop) + s.logger.Infof("Stopped periodic backup") +} + +func (s *Service) backupLoop() { + ticker := time.NewTicker(s.interval) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + if err := s.PerformBackup(); err != nil { + s.logger.Errorf("Periodic backup failed: %v", err) + } + case <-s.stop: + return + } + } +} + +func (s *Service) PerformBackup() error { + timestamp := time.Now().Format("06-01-02-15-04") + backupPath := filepath.Join(s.backupDir, timestamp) + + if err := os.MkdirAll(backupPath, 0755); err != nil { + return fmt.Errorf("failed to create backup timestamp directory: %v", err) + } + + backupFile := filepath.Join(backupPath, "badger.backup") + f, err := os.Create(backupFile) + if err != nil { + return fmt.Errorf("failed to create backup file: %v", err) + } + defer f.Close() + + s.logger.Infof("Running backup to %s", backupFile) + since := uint64(0) // Full backup + _, err = s.db.Backup(context.Background(), f, since) + if err != nil { + return fmt.Errorf("backup operation failed: %v", err) + } + + s.logger.Infof("Backup completed successfully to %s", backupFile) + return nil +} diff --git a/core/backup/backup_test.go b/core/backup/backup_test.go new file mode 100644 index 00000000..f561d833 --- /dev/null +++ b/core/backup/backup_test.go @@ -0,0 +1,83 @@ +package backup + +import ( + "testing" + "time" + "os" + + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" +) + +func TestBackup(t *testing.T) { + // Test cases for backup service + t.Run("StartPeriodicBackup", func(t *testing.T) { + // Setup + logger := testutil.GetLogger() + db := testutil.TestMustDB() + tempDir := t.TempDir() + + service := NewService(logger, db, tempDir) + + // Test starting backup service + err := service.StartPeriodicBackup(1 * time.Hour) + if err != nil { + t.Fatalf("Failed to start periodic backup: %v", err) + } + + if !service.backupEnabled { + t.Error("Backup service should be enabled after starting") + } + + // Test starting again should fail + err = service.StartPeriodicBackup(1 * time.Hour) + if err == nil { + t.Error("Starting backup service twice should return an error") + } + + // Cleanup + service.StopPeriodicBackup() + }) + + t.Run("StopPeriodicBackup", func(t *testing.T) { + // Setup + logger := testutil.GetLogger() + db := testutil.TestMustDB() + tempDir := t.TempDir() + + service := NewService(logger, db, tempDir) + + // Start and then stop + _ = service.StartPeriodicBackup(1 * time.Hour) + service.StopPeriodicBackup() + + if service.backupEnabled { + t.Error("Backup service should be disabled after stopping") + } + + // Test stopping when not running (should be a no-op) + service.StopPeriodicBackup() + }) + + t.Run("PerformBackup", func(t *testing.T) { + // Setup + logger := testutil.GetLogger() + db := testutil.TestMustDB() + tempDir := t.TempDir() + + service := NewService(logger, db, tempDir) + + // Test performing a backup + backupFile, err := service.PerformBackup() + if err != nil { + t.Fatalf("Failed to perform backup: %v", err) + } + + // Verify backup file exists + if _, err := os.Stat(backupFile); os.IsNotExist(err) { + t.Errorf("Backup file %s does not exist", backupFile) + } + }) +} + +// Mock implementations for testing + diff --git a/core/config/config.go b/core/config/config.go index 2d8e2fd7..9937dd2c 100644 --- a/core/config/config.go +++ b/core/config/config.go @@ -52,6 +52,8 @@ type Config struct { // Account abstraction config SmartWallet *SmartWalletConfig + BackupConfig BackupConfig + SocketPath string Environment sdklogging.LogLevel @@ -72,6 +74,12 @@ type SmartWalletConfig struct { PaymasterAddress common.Address } +type BackupConfig struct { + Enabled bool // Whether periodic backups are enabled + IntervalMinutes int // Interval between backups in minutes + BackupDir string // Directory to store backups +} + // These are read from configPath type ConfigRaw struct { EcdsaPrivateKey string `yaml:"ecdsa_private_key"` @@ -97,6 +105,12 @@ type ConfigRaw struct { PaymasterAddress string `yaml:"paymaster_address"` } `yaml:"smart_wallet"` + Backup struct { + Enabled bool `yaml:"enabled"` + IntervalMinutes int `yaml:"interval_minutes"` + BackupDir string `yaml:"backup_dir"` + } `yaml:"backup"` + SocketPath string `yaml:"socket_path"` Macros map[string]map[string]string `yaml:"macros"` @@ -205,6 +219,12 @@ func NewConfig(configFilePath string) (*Config, error) { ControllerPrivateKey: controllerPrivateKey, }, + BackupConfig: BackupConfig{ + Enabled: configRaw.Backup.Enabled, + IntervalMinutes: configRaw.Backup.IntervalMinutes, + BackupDir: configRaw.Backup.BackupDir, + }, + SocketPath: configRaw.SocketPath, MacroVars: configRaw.Macros["vars"], MacroSecrets: configRaw.Macros["secrets"], diff --git a/storage/db.go b/storage/db.go index 42bc8602..41275a2c 100644 --- a/storage/db.go +++ b/storage/db.go @@ -1,7 +1,9 @@ package storage import ( + "context" "fmt" + "io" "os" "strconv" "strings" @@ -48,6 +50,9 @@ type Storage interface { SetCounter(key []byte, value uint64) error Vacuum() error + Backup(ctx context.Context, w io.Writer, since uint64) (uint64, error) + Load(ctx context.Context, r io.Reader) error + DbPath() string } @@ -488,3 +493,11 @@ func (a *BadgerStorage) SetCounter(key []byte, value uint64) error { return txn.Set(key, []byte(counterStr)) }) } + +func (bs *BadgerStorage) Backup(ctx context.Context, w io.Writer, since uint64) (uint64, error) { + return bs.db.Backup(w, since) +} + +func (bs *BadgerStorage) Load(ctx context.Context, r io.Reader) error { + return bs.db.Load(r, 16) // 16 is a good default for the number of concurrent threads +} From 5c02641f0228b7be977d0553a6a279aac13c18f6 Mon Sep 17 00:00:00 2001 From: Vinh Date: Thu, 10 Apr 2025 02:31:48 -0700 Subject: [PATCH 2/9] add a migration framework, create second -> ms converted --- Makefile | 2 +- aggregator/aggregator.go | 40 +++- aggregator/auth.go | 6 +- aggregator/auth_test.go | 8 +- aggregator/http_server.go | 2 +- aggregator/key.go | 4 +- aggregator/pool.go | 6 +- aggregator/repl.go | 9 + aggregator/rpc_server.go | 12 +- aggregator/task_engine.go | 6 +- cmd/createAdminKey.go | 2 +- cmd/createAliasKey.go | 2 +- cmd/declareAlias.go | 2 +- cmd/deregister.go | 2 +- cmd/register.go | 2 +- cmd/removeAlias.go | 2 +- cmd/runAggregator.go | 2 +- cmd/runOperator.go | 2 +- cmd/status.go | 2 +- cmd/version.go | 2 +- core/apqueue/queue.go | 2 +- core/apqueue/worker.go | 2 +- core/auth/operator.go | 2 +- core/auth/server.go | 2 +- core/backup/backup.go | 22 +- core/chainio/aa/aa.go | 2 +- core/chainio/avs_reader.go | 4 +- core/chainio/avs_writer.go | 4 +- core/chainio/bindings.go | 4 +- core/config/config.go | 9 + core/migrator/migrator.go | 108 +++++++++ core/migrator/migrator_test.go | 107 +++++++++ core/taskengine/engine.go | 12 +- core/taskengine/engine_test.go | 12 +- core/taskengine/executor.go | 10 +- core/taskengine/executor_test.go | 10 +- core/taskengine/schema.go | 4 +- core/taskengine/secret.go | 4 +- core/taskengine/secret_test.go | 8 +- core/taskengine/stats.go | 6 +- core/taskengine/stats_test.go | 8 +- core/taskengine/trigger/block.go | 2 +- core/taskengine/trigger/event.go | 4 +- core/taskengine/trigger/event_test.go | 12 +- core/taskengine/trigger/time.go | 2 +- core/taskengine/utils.go | 2 +- core/taskengine/validation.go | 4 +- core/taskengine/validation_test.go | 6 +- core/taskengine/vm.go | 19 +- core/taskengine/vm_runner_branch.go | 2 +- core/taskengine/vm_runner_branch_test.go | 8 +- core/taskengine/vm_runner_contract_read.go | 6 +- .../vm_runner_contract_read_test.go | 8 +- core/taskengine/vm_runner_contract_write.go | 8 +- .../vm_runner_contract_write_test.go | 10 +- ...r_contract_write_transaction_limit_test.go | 14 +- core/taskengine/vm_runner_customcode.go | 4 +- core/taskengine/vm_runner_customcode_test.go | 8 +- core/taskengine/vm_runner_filter.go | 4 +- core/taskengine/vm_runner_filter_test.go | 8 +- core/taskengine/vm_runner_graphql_query.go | 4 +- .../vm_runner_graphql_query_test.go | 8 +- core/taskengine/vm_runner_rest.go | 2 +- core/taskengine/vm_runner_rest_test.go | 8 +- core/taskengine/vm_test.go | 8 +- core/testutil/utils.go | 8 +- core/utils.go | 2 +- dockerfiles/operator.Dockerfile | 4 +- go.mod | 5 +- go.sum | 2 - main.go | 2 +- .../20250405-232000-change-epoch-to-ms.go | 134 +++++++++++ ...20250405-232000-change-epoch-to-ms_test.go | 218 ++++++++++++++++++ migrations/README.md | 52 +++++ migrations/migrations.go | 17 ++ model/task.go | 2 +- model/user.go | 2 +- operator/alias.go | 2 +- operator/operator.go | 26 +-- operator/worker_loop.go | 10 +- pkg/erc4337/bundler/client.go | 2 +- pkg/erc4337/preset/builder.go | 6 +- pkg/erc4337/preset/builder_test.go | 10 +- 83 files changed, 897 insertions(+), 225 deletions(-) create mode 100644 core/migrator/migrator.go create mode 100644 core/migrator/migrator_test.go create mode 100644 migrations/20250405-232000-change-epoch-to-ms.go create mode 100644 migrations/20250405-232000-change-epoch-to-ms_test.go create mode 100644 migrations/README.md create mode 100644 migrations/migrations.go diff --git a/Makefile b/Makefile index 657be6ee..8c6944ae 100644 --- a/Makefile +++ b/Makefile @@ -112,7 +112,7 @@ dev-build: mkdir out || true go build \ -o ./out/ap \ - -ldflags "-X github.com/AvaProtocol/ap-avs/version.revision=$(shell git rev-parse HEAD)" + -ldflags "-X github.com/AvaProtocol/EigenLayer-AVS/version.revision=$(shell git rev-parse HEAD)" ## dev-agg: run aggregator locally with dev build dev-agg: diff --git a/aggregator/aggregator.go b/aggregator/aggregator.go index 9b0216b8..5fe8fa5a 100644 --- a/aggregator/aggregator.go +++ b/aggregator/aggregator.go @@ -13,22 +13,28 @@ import ( "github.com/Layr-Labs/eigensdk-go/logging" "github.com/ethereum/go-ethereum/ethclient" - "github.com/AvaProtocol/ap-avs/aggregator/types" - "github.com/AvaProtocol/ap-avs/core" - "github.com/AvaProtocol/ap-avs/core/apqueue" - "github.com/AvaProtocol/ap-avs/core/chainio" - "github.com/AvaProtocol/ap-avs/core/chainio/aa" - "github.com/AvaProtocol/ap-avs/core/config" - "github.com/AvaProtocol/ap-avs/core/taskengine" - "github.com/AvaProtocol/ap-avs/version" sdkclients "github.com/Layr-Labs/eigensdk-go/chainio/clients" blsagg "github.com/Layr-Labs/eigensdk-go/services/bls_aggregation" sdktypes "github.com/Layr-Labs/eigensdk-go/types" "github.com/allegro/bigcache/v3" - "github.com/AvaProtocol/ap-avs/storage" - - cstaskmanager "github.com/AvaProtocol/ap-avs/contracts/bindings/AutomationTaskManager" + + cstaskmanager "github.com/AvaProtocol/EigenLayer-AVS/contracts/bindings/AutomationTaskManager" + + "github.com/AvaProtocol/EigenLayer-AVS/storage" + + "github.com/AvaProtocol/EigenLayer-AVS/aggregator/types" + "github.com/AvaProtocol/EigenLayer-AVS/core" + "github.com/AvaProtocol/EigenLayer-AVS/core/apqueue" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/aa" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" + "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine" + "github.com/AvaProtocol/EigenLayer-AVS/version" + + "github.com/AvaProtocol/EigenLayer-AVS/core/backup" + "github.com/AvaProtocol/EigenLayer-AVS/core/migrator" + "github.com/AvaProtocol/EigenLayer-AVS/migrations" ) const ( @@ -93,6 +99,9 @@ type Aggregator struct { status AggregatorStatus cache *bigcache.BigCache + + backup *backup.Service + migrator *migrator.Migrator } // NewAggregator creates a new Aggregator with the provided config. @@ -229,6 +238,14 @@ func (agg *Aggregator) init() { aa.SetEntrypointAddress(agg.config.SmartWallet.EntrypointAddress) } +func (agg *Aggregator) migrate() { + agg.backup = backup.NewService(agg.logger, agg.db, agg.config.BackupDir) + agg.migrator = migrator.NewMigrator(agg.db, agg.backup, migrations.Migrations) + if err := agg.migrator.Run(); err != nil { + agg.logger.Fatalf("failed to run migrations", "error", err) + } +} + func (agg *Aggregator) Start(ctx context.Context) error { agg.logger.Infof("Starting aggregator %s", version.Get()) @@ -239,6 +256,7 @@ func (agg *Aggregator) Start(ctx context.Context) error { agg.logger.Fatalf("failed to initialize storage", "error", err) } + agg.migrate() agg.logger.Infof("Starting Task engine") agg.startTaskEngine(ctx) diff --git a/aggregator/auth.go b/aggregator/auth.go index f090db8c..5d5d0f16 100644 --- a/aggregator/auth.go +++ b/aggregator/auth.go @@ -5,9 +5,9 @@ import ( "fmt" "strings" - "github.com/AvaProtocol/ap-avs/core/auth" - "github.com/AvaProtocol/ap-avs/model" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/core/auth" + "github.com/AvaProtocol/EigenLayer-AVS/model" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" "github.com/ethereum/go-ethereum/accounts" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" diff --git a/aggregator/auth_test.go b/aggregator/auth_test.go index ebaa921f..b4c569ae 100644 --- a/aggregator/auth_test.go +++ b/aggregator/auth_test.go @@ -6,15 +6,15 @@ import ( "testing" "time" - "github.com/AvaProtocol/ap-avs/core/auth" - "github.com/AvaProtocol/ap-avs/core/config" + "github.com/AvaProtocol/EigenLayer-AVS/core/auth" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/golang-jwt/jwt/v5" timestamppb "google.golang.org/protobuf/types/known/timestamppb" - "github.com/AvaProtocol/ap-avs/core/chainio/signer" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/signer" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" sdklogging "github.com/Layr-Labs/eigensdk-go/logging" ) diff --git a/aggregator/http_server.go b/aggregator/http_server.go index 0c82b005..5b25b081 100644 --- a/aggregator/http_server.go +++ b/aggregator/http_server.go @@ -8,7 +8,7 @@ import ( "context" "net/http" - "github.com/AvaProtocol/ap-avs/version" + "github.com/AvaProtocol/EigenLayer-AVS/version" "github.com/labstack/echo/v4" ) diff --git a/aggregator/key.go b/aggregator/key.go index c0e001e9..b7d85d74 100644 --- a/aggregator/key.go +++ b/aggregator/key.go @@ -4,8 +4,8 @@ import ( "fmt" "time" - "github.com/AvaProtocol/ap-avs/core/auth" - "github.com/AvaProtocol/ap-avs/core/config" + "github.com/AvaProtocol/EigenLayer-AVS/core/auth" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" "github.com/golang-jwt/jwt/v5" ) diff --git a/aggregator/pool.go b/aggregator/pool.go index aec89fde..7c1b99d9 100644 --- a/aggregator/pool.go +++ b/aggregator/pool.go @@ -8,9 +8,9 @@ import ( timestamppb "google.golang.org/protobuf/types/known/timestamppb" - "github.com/AvaProtocol/ap-avs/core/config" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) type OperatorNode struct { diff --git a/aggregator/repl.go b/aggregator/repl.go index 2601076c..b924bae8 100644 --- a/aggregator/repl.go +++ b/aggregator/repl.go @@ -100,6 +100,15 @@ func handleConnection(agg *Aggregator, conn net.Conn) { } else { fmt.Fprintln(conn, "Usage: list * or list *") } + case "rm": + if keys, err := agg.db.ListKeys(parts[1]); err == nil { + for _, k := range keys { + fmt.Fprintln(conn, k) + if err := agg.db.Delete([]byte(k)); err == nil { + fmt.Fprintln(conn, "deleted "+k) + } + } + } case "get": if len(parts) == 2 { if key, err := agg.db.GetKey([]byte(parts[1])); err == nil { diff --git a/aggregator/rpc_server.go b/aggregator/rpc_server.go index 243f7c37..948c97de 100644 --- a/aggregator/rpc_server.go +++ b/aggregator/rpc_server.go @@ -18,12 +18,12 @@ import ( timestamppb "google.golang.org/protobuf/types/known/timestamppb" wrapperspb "google.golang.org/protobuf/types/known/wrapperspb" - "github.com/AvaProtocol/ap-avs/core/auth" - "github.com/AvaProtocol/ap-avs/core/chainio/aa" - "github.com/AvaProtocol/ap-avs/core/config" - "github.com/AvaProtocol/ap-avs/core/taskengine" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/core/auth" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/aa" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" + "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) // RpcServer is our grpc sever struct hold the entry point of request handler diff --git a/aggregator/task_engine.go b/aggregator/task_engine.go index 6c598805..a39d552f 100644 --- a/aggregator/task_engine.go +++ b/aggregator/task_engine.go @@ -3,9 +3,9 @@ package aggregator import ( "context" - "github.com/AvaProtocol/ap-avs/core/apqueue" - "github.com/AvaProtocol/ap-avs/core/taskengine" - "github.com/AvaProtocol/ap-avs/core/taskengine/macros" + "github.com/AvaProtocol/EigenLayer-AVS/core/apqueue" + "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine" + "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine/macros" ) func (agg *Aggregator) stopTaskEngine() { diff --git a/cmd/createAdminKey.go b/cmd/createAdminKey.go index 094aecc3..b30c9122 100644 --- a/cmd/createAdminKey.go +++ b/cmd/createAdminKey.go @@ -1,7 +1,7 @@ package cmd import ( - "github.com/AvaProtocol/ap-avs/aggregator" + "github.com/AvaProtocol/EigenLayer-AVS/aggregator" "github.com/spf13/cobra" ) diff --git a/cmd/createAliasKey.go b/cmd/createAliasKey.go index dcbca2af..4f364c12 100644 --- a/cmd/createAliasKey.go +++ b/cmd/createAliasKey.go @@ -6,7 +6,7 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/AvaProtocol/ap-avs/operator" + "github.com/AvaProtocol/EigenLayer-AVS/operator" ) var ( diff --git a/cmd/declareAlias.go b/cmd/declareAlias.go index 2ff24b60..603dc4d3 100644 --- a/cmd/declareAlias.go +++ b/cmd/declareAlias.go @@ -6,7 +6,7 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/AvaProtocol/ap-avs/operator" + "github.com/AvaProtocol/EigenLayer-AVS/operator" ) // declareAliasCmd represents the declareAlias command diff --git a/cmd/deregister.go b/cmd/deregister.go index e3957ee6..1f83595f 100644 --- a/cmd/deregister.go +++ b/cmd/deregister.go @@ -6,7 +6,7 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/AvaProtocol/ap-avs/operator" + "github.com/AvaProtocol/EigenLayer-AVS/operator" ) var ( diff --git a/cmd/register.go b/cmd/register.go index 875eb19a..2cf62e7e 100644 --- a/cmd/register.go +++ b/cmd/register.go @@ -3,7 +3,7 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/AvaProtocol/ap-avs/operator" + "github.com/AvaProtocol/EigenLayer-AVS/operator" ) var ( diff --git a/cmd/removeAlias.go b/cmd/removeAlias.go index 1a3b9cd6..9a8c2880 100644 --- a/cmd/removeAlias.go +++ b/cmd/removeAlias.go @@ -6,7 +6,7 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/AvaProtocol/ap-avs/operator" + "github.com/AvaProtocol/EigenLayer-AVS/operator" ) // removeAliasCmd represents the removeAlias command diff --git a/cmd/runAggregator.go b/cmd/runAggregator.go index a8205cc2..efce0004 100644 --- a/cmd/runAggregator.go +++ b/cmd/runAggregator.go @@ -1,7 +1,7 @@ package cmd import ( - "github.com/AvaProtocol/ap-avs/aggregator" + "github.com/AvaProtocol/EigenLayer-AVS/aggregator" "github.com/spf13/cobra" ) diff --git a/cmd/runOperator.go b/cmd/runOperator.go index b0cc2676..8e3f2a3c 100644 --- a/cmd/runOperator.go +++ b/cmd/runOperator.go @@ -6,7 +6,7 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/AvaProtocol/ap-avs/operator" + "github.com/AvaProtocol/EigenLayer-AVS/operator" ) var ( diff --git a/cmd/status.go b/cmd/status.go index b8886997..2148afc6 100644 --- a/cmd/status.go +++ b/cmd/status.go @@ -6,7 +6,7 @@ package cmd import ( "github.com/spf13/cobra" - "github.com/AvaProtocol/ap-avs/operator" + "github.com/AvaProtocol/EigenLayer-AVS/operator" ) var ( diff --git a/cmd/version.go b/cmd/version.go index af8b61ec..d0b1f469 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -8,7 +8,7 @@ import ( "github.com/spf13/cobra" - "github.com/AvaProtocol/ap-avs/version" + "github.com/AvaProtocol/EigenLayer-AVS/version" ) // versionCmd represents the version command diff --git a/core/apqueue/queue.go b/core/apqueue/queue.go index 62d0c3d9..e79bfc6c 100644 --- a/core/apqueue/queue.go +++ b/core/apqueue/queue.go @@ -5,7 +5,7 @@ import ( "fmt" "sync" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/storage" sdklogging "github.com/Layr-Labs/eigensdk-go/logging" ) diff --git a/core/apqueue/worker.go b/core/apqueue/worker.go index 0bb476c1..b34e236b 100644 --- a/core/apqueue/worker.go +++ b/core/apqueue/worker.go @@ -1,7 +1,7 @@ package apqueue import ( - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/storage" sdklogging "github.com/Layr-Labs/eigensdk-go/logging" ) diff --git a/core/auth/operator.go b/core/auth/operator.go index 4772e1db..9b900a60 100644 --- a/core/auth/operator.go +++ b/core/auth/operator.go @@ -6,7 +6,7 @@ import ( "fmt" "time" - "github.com/AvaProtocol/ap-avs/core/chainio/signer" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/signer" "github.com/ethereum/go-ethereum/common" ) diff --git a/core/auth/server.go b/core/auth/server.go index ddf55c51..f991f5cd 100644 --- a/core/auth/server.go +++ b/core/auth/server.go @@ -6,7 +6,7 @@ import ( "strings" "time" - "github.com/AvaProtocol/ap-avs/core/chainio/signer" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/signer" ) // VerifyOperator checks and confirm that the auth header is indeed signed by diff --git a/core/backup/backup.go b/core/backup/backup.go index 08e6ed9c..cdb6842d 100644 --- a/core/backup/backup.go +++ b/core/backup/backup.go @@ -7,7 +7,7 @@ import ( "path/filepath" "time" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/storage" "github.com/Layr-Labs/eigensdk-go/logging" ) @@ -42,10 +42,6 @@ func (s *Service) StartPeriodicBackup(interval time.Duration) error { s.interval = interval s.backupEnabled = true - if err := s.PerformBackup(); err != nil { - s.logger.Errorf("Initial backup failed: %v", err) - } - go s.backupLoop() s.logger.Infof("Started periodic backup every %v to %s", interval, s.backupDir) @@ -69,8 +65,10 @@ func (s *Service) backupLoop() { for { select { case <-ticker.C: - if err := s.PerformBackup(); err != nil { + if backupFile, err := s.PerformBackup(); err != nil { s.logger.Errorf("Periodic backup failed: %v", err) + } else { + s.logger.Infof("Periodic backup completed successfully to %s", backupFile) } case <-s.stop: return @@ -78,18 +76,18 @@ func (s *Service) backupLoop() { } } -func (s *Service) PerformBackup() error { +func (s *Service) PerformBackup() (string, error) { timestamp := time.Now().Format("06-01-02-15-04") backupPath := filepath.Join(s.backupDir, timestamp) if err := os.MkdirAll(backupPath, 0755); err != nil { - return fmt.Errorf("failed to create backup timestamp directory: %v", err) + return "", fmt.Errorf("failed to create backup timestamp directory: %v", err) } - backupFile := filepath.Join(backupPath, "badger.backup") + backupFile := filepath.Join(backupPath, "full-backup.db") f, err := os.Create(backupFile) if err != nil { - return fmt.Errorf("failed to create backup file: %v", err) + return "", fmt.Errorf("failed to create backup file: %v", err) } defer f.Close() @@ -97,9 +95,9 @@ func (s *Service) PerformBackup() error { since := uint64(0) // Full backup _, err = s.db.Backup(context.Background(), f, since) if err != nil { - return fmt.Errorf("backup operation failed: %v", err) + return "", fmt.Errorf("backup operation failed: %v", err) } s.logger.Infof("Backup completed successfully to %s", backupFile) - return nil + return backupFile, nil } diff --git a/core/chainio/aa/aa.go b/core/chainio/aa/aa.go index 601a30de..9e894c13 100644 --- a/core/chainio/aa/aa.go +++ b/core/chainio/aa/aa.go @@ -5,7 +5,7 @@ import ( "math/big" "strings" - "github.com/AvaProtocol/ap-avs/core/chainio/aa/simpleaccount" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/aa/simpleaccount" "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" diff --git a/core/chainio/avs_reader.go b/core/chainio/avs_reader.go index aae8d43c..2fae23eb 100644 --- a/core/chainio/avs_reader.go +++ b/core/chainio/avs_reader.go @@ -10,8 +10,8 @@ import ( "github.com/Layr-Labs/eigensdk-go/chainio/clients/eth" logging "github.com/Layr-Labs/eigensdk-go/logging" - cstaskmanager "github.com/AvaProtocol/ap-avs/contracts/bindings/AutomationTaskManager" - "github.com/AvaProtocol/ap-avs/core/config" + cstaskmanager "github.com/AvaProtocol/EigenLayer-AVS/contracts/bindings/AutomationTaskManager" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" ) type AvsReader struct { diff --git a/core/chainio/avs_writer.go b/core/chainio/avs_writer.go index 46e1f635..126346ea 100644 --- a/core/chainio/avs_writer.go +++ b/core/chainio/avs_writer.go @@ -13,8 +13,8 @@ import ( logging "github.com/Layr-Labs/eigensdk-go/logging" sdktypes "github.com/Layr-Labs/eigensdk-go/types" - cstaskmanager "github.com/AvaProtocol/ap-avs/contracts/bindings/AutomationTaskManager" - "github.com/AvaProtocol/ap-avs/core/config" + cstaskmanager "github.com/AvaProtocol/EigenLayer-AVS/contracts/bindings/AutomationTaskManager" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" ) type AvsWriter struct { diff --git a/core/chainio/bindings.go b/core/chainio/bindings.go index a8044966..748689d5 100644 --- a/core/chainio/bindings.go +++ b/core/chainio/bindings.go @@ -7,8 +7,8 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi/bind" gethcommon "github.com/ethereum/go-ethereum/common" - csservicemanager "github.com/AvaProtocol/ap-avs/contracts/bindings/AutomationServiceManager" - cstaskmanager "github.com/AvaProtocol/ap-avs/contracts/bindings/AutomationTaskManager" + csservicemanager "github.com/AvaProtocol/EigenLayer-AVS/contracts/bindings/AutomationServiceManager" + cstaskmanager "github.com/AvaProtocol/EigenLayer-AVS/contracts/bindings/AutomationTaskManager" regcoord "github.com/Layr-Labs/eigensdk-go/contracts/bindings/RegistryCoordinator" ) diff --git a/core/config/config.go b/core/config/config.go index 9937dd2c..0e6e965a 100644 --- a/core/config/config.go +++ b/core/config/config.go @@ -47,6 +47,8 @@ type Config struct { AggregatorAddress common.Address DbPath string + BackupDir string + JwtSecret []byte // Account abstraction config @@ -93,6 +95,7 @@ type ConfigRaw struct { AVSRegistryCoordinatorAddr string `yaml:"avs_registry_coordinator_address"` DbPath string `yaml:"db_path"` + BackupDir string `yaml:"backup_dir"` JwtSecret string `yaml:"jwt_secret"` SmartWallet struct { @@ -191,6 +194,11 @@ func NewConfig(configFilePath string) (*Config, error) { panic(err) } + if configRaw.BackupDir == "" { + // If backup dir is not set, use the default path, usually this path will be mount from our docker compose host + configRaw.BackupDir = "/tmp/ap-avs-backup" + } + config := &Config{ EcdsaPrivateKey: ecdsaPrivateKey, Logger: logger, @@ -208,6 +216,7 @@ func NewConfig(configFilePath string) (*Config, error) { AggregatorAddress: aggregatorAddr, DbPath: configRaw.DbPath, + BackupDir: configRaw.BackupDir, JwtSecret: []byte(configRaw.JwtSecret), SmartWallet: &SmartWalletConfig{ diff --git a/core/migrator/migrator.go b/core/migrator/migrator.go new file mode 100644 index 00000000..c4fbc22b --- /dev/null +++ b/core/migrator/migrator.go @@ -0,0 +1,108 @@ +package migrator + +import ( + "time" + + "github.com/AvaProtocol/EigenLayer-AVS/storage" + "github.com/AvaProtocol/EigenLayer-AVS/core/backup" +) + +import ( + "fmt" + "log" + "sync" +) + +// MigrationFunc is a function that performs a database migration. The migration functions need to follow this signature +// and return the number of records updated and an error if the migration fails +type MigrationFunc func(db storage.Storage) (int, error) + +// Migration represents a database migration function +type Migration struct { + Name string + Function MigrationFunc +} + +// Migrator handles database migrations +type Migrator struct { + db storage.Storage + migrations []Migration + backup *backup.Service + mu sync.Mutex +} + +// NewMigrator creates a new migrator instance +func NewMigrator(db storage.Storage, backup *backup.Service, migrations []Migration) *Migrator { + return &Migrator{ + db: db, + migrations: migrations, + backup: backup, + } +} + + + +// Register adds a new migration to the list +func (m *Migrator) Register(name string, fn MigrationFunc) { + m.mu.Lock() + defer m.mu.Unlock() + + m.migrations = append(m.migrations, Migration{ + Name: name, + Function: fn, + }) +} + +// Run executes all registered migrations that haven't been run yet +func (m *Migrator) Run() error { + m.mu.Lock() + defer m.mu.Unlock() + + // Check if we have any migrations to run + hasPendingMigrations := false + for _, migration := range m.migrations { + key := fmt.Sprintf("migration:%s", migration.Name) + exists, err := m.db.Exist([]byte(key)) + if err != nil || !exists { + hasPendingMigrations = true + break + } + } + + // If we have migrations to run, take a backup first + if hasPendingMigrations { + log.Printf("Pending migrations found, creating database backup before proceeding") + if backupFile, err := m.backup.PerformBackup(); err != nil { + return fmt.Errorf("failed to create backup before migrations: %w", err) + } else { + log.Printf("Database backup created at %s", backupFile) + } + } + + + for _, migration := range m.migrations { + // Check if migration has already been run + key := fmt.Sprintf("migration:%s", migration.Name) + exists, err := m.db.Exist([]byte(key)) + if exists && err == nil { + log.Printf("Migration %s already applied, skipping", migration.Name) + continue + } + + // Run the migration + log.Printf("Running migration: %s", migration.Name) + recordsUpdated, err := migration.Function(m.db) + if err != nil { + return fmt.Errorf("migration %s failed: %w", migration.Name, err) + } else { + log.Printf("Migration %s completed successfully. %d records updated.", migration.Name, recordsUpdated) + } + + // Mark migration as complete in the database + if err := m.db.Set([]byte(key), []byte(fmt.Sprintf("records=%d,ts=%d", recordsUpdated, time.Now().UnixMilli()))); err != nil { + return fmt.Errorf("failed to mark migration as complete in database: %w", err) + } + } + + return nil +} diff --git a/core/migrator/migrator_test.go b/core/migrator/migrator_test.go new file mode 100644 index 00000000..45563b0d --- /dev/null +++ b/core/migrator/migrator_test.go @@ -0,0 +1,107 @@ +package migrator + +import ( + "strings" + "testing" + + "github.com/AvaProtocol/EigenLayer-AVS/core/backup" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/storage" +) + +func TestMigrator(t *testing.T) { + // Setup test database + logger := testutil.GetLogger() + db := testutil.TestMustDB() + defer db.Close() + + // Create backup service + backupDir := t.TempDir() + backup := backup.NewService(logger, db, backupDir) + + // Test migration function that updates records + testMigration := func(db storage.Storage) (int, error) { + return 5, db.Set([]byte("test:key"), []byte("migrated")) + } + + // Create migrator with test migration + migrations := []Migration{} // Initialize with empty slice + migrator := NewMigrator(db, backup, migrations) + migrator.Register("test_migration", testMigration) + + // Run migrations + err := migrator.Run() + if err != nil { + t.Fatalf("Failed to run migrations: %v", err) + } + + // Verify migration was marked as complete + migrationKey := []byte("migration:test_migration") + exists, err := db.Exist(migrationKey) + if err != nil { + t.Fatalf("Failed to check if migration exists: %v", err) + } + if !exists { + t.Fatalf("Migration was not marked as complete") + } + + // Verify migration record format (should contain records count and timestamp) + migrationData, err := db.GetKey(migrationKey) + if err != nil { + t.Fatalf("Failed to get migration data: %v", err) + } + + migrationRecord := string(migrationData) + if !strings.Contains(migrationRecord, "records=5") { + t.Errorf("Migration record doesn't contain correct record count: %s", migrationRecord) + } + if !strings.Contains(migrationRecord, "ts=") { + t.Errorf("Migration record doesn't contain timestamp: %s", migrationRecord) + } + + // Test that migrations aren't run twice + // Create a counter to track if migration is called + migrationCounter := 0 + countingMigration := func(db storage.Storage) (int, error) { + migrationCounter++ + return 0, nil + } + + // Register a new migration that we've already run + migrator.Register("test_migration", countingMigration) + + // Run migrations again + err = migrator.Run() + if err != nil { + t.Fatalf("Failed to run migrations second time: %v", err) + } + + // Verify the migration wasn't executed again + if migrationCounter > 0 { + t.Errorf("Migration was executed again when it should have been skipped") + } + + // Test new migration gets executed + migrator.Register("second_migration", countingMigration) + + // Run migrations again + err = migrator.Run() + if err != nil { + t.Fatalf("Failed to run migrations third time: %v", err) + } + + // Verify the new migration was executed + if migrationCounter != 1 { + t.Errorf("New migration was not executed") + } + + // Verify second migration was marked as complete + secondMigrationKey := []byte("migration:second_migration") + exists, err = db.Exist(secondMigrationKey) + if err != nil { + t.Fatalf("Failed to check if second migration exists: %v", err) + } + if !exists { + t.Fatalf("Second migration was not marked as complete") + } +} \ No newline at end of file diff --git a/core/taskengine/engine.go b/core/taskengine/engine.go index a3fec6e2..2cfca52e 100644 --- a/core/taskengine/engine.go +++ b/core/taskengine/engine.go @@ -11,11 +11,11 @@ import ( "sync" "time" - "github.com/AvaProtocol/ap-avs/core/apqueue" - "github.com/AvaProtocol/ap-avs/core/chainio/aa" - "github.com/AvaProtocol/ap-avs/core/config" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/core/apqueue" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/aa" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/storage" sdklogging "github.com/Layr-Labs/eigensdk-go/logging" "github.com/allegro/bigcache/v3" "github.com/ethereum/go-ethereum/common" @@ -27,7 +27,7 @@ import ( grpcstatus "google.golang.org/grpc/status" "google.golang.org/protobuf/encoding/protojson" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) const ( diff --git a/core/taskengine/engine_test.go b/core/taskengine/engine_test.go index c3b8d7e5..92753dc9 100644 --- a/core/taskengine/engine_test.go +++ b/core/taskengine/engine_test.go @@ -5,12 +5,12 @@ import ( "strings" "testing" - "github.com/AvaProtocol/ap-avs/core/apqueue" - "github.com/AvaProtocol/ap-avs/core/testutil" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/pkg/gow" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/core/apqueue" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/gow" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) func TestCreateTaskReturnErrorWhenEmptyNodes(t *testing.T) { diff --git a/core/taskengine/executor.go b/core/taskengine/executor.go index c3795fbb..a0844c1d 100644 --- a/core/taskengine/executor.go +++ b/core/taskengine/executor.go @@ -7,13 +7,13 @@ import ( "google.golang.org/protobuf/encoding/protojson" - "github.com/AvaProtocol/ap-avs/model" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/model" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" sdklogging "github.com/Layr-Labs/eigensdk-go/logging" - "github.com/AvaProtocol/ap-avs/core/apqueue" - "github.com/AvaProtocol/ap-avs/core/config" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/core/apqueue" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) func NewExecutor(config *config.SmartWalletConfig, db storage.Storage, logger sdklogging.Logger) *TaskExecutor { diff --git a/core/taskengine/executor_test.go b/core/taskengine/executor_test.go index 40fe54c9..b7a1b8d2 100644 --- a/core/taskengine/executor_test.go +++ b/core/taskengine/executor_test.go @@ -7,11 +7,11 @@ import ( "sort" "testing" - "github.com/AvaProtocol/ap-avs/core/testutil" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/pkg/gow" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/gow" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) func TestExecutorRunTaskSucess(t *testing.T) { diff --git a/core/taskengine/schema.go b/core/taskengine/schema.go index 8a420f66..d7a0ecb0 100644 --- a/core/taskengine/schema.go +++ b/core/taskengine/schema.go @@ -4,8 +4,8 @@ import ( "fmt" "strings" - "github.com/AvaProtocol/ap-avs/model" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/model" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" "github.com/ethereum/go-ethereum/common" ) diff --git a/core/taskengine/secret.go b/core/taskengine/secret.go index 60e3b0e7..bd0888bf 100644 --- a/core/taskengine/secret.go +++ b/core/taskengine/secret.go @@ -4,8 +4,8 @@ import ( "fmt" "maps" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/storage" "github.com/ethereum/go-ethereum/common" ) diff --git a/core/taskengine/secret_test.go b/core/taskengine/secret_test.go index c485a6f4..f8523958 100644 --- a/core/taskengine/secret_test.go +++ b/core/taskengine/secret_test.go @@ -4,10 +4,10 @@ import ( "reflect" "testing" - "github.com/AvaProtocol/ap-avs/core/testutil" - "github.com/AvaProtocol/ap-avs/model" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/model" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) func TestLoadSecretForTask(t *testing.T) { diff --git a/core/taskengine/stats.go b/core/taskengine/stats.go index 1a95c64f..981453ca 100644 --- a/core/taskengine/stats.go +++ b/core/taskengine/stats.go @@ -3,9 +3,9 @@ package taskengine import ( "strconv" - "github.com/AvaProtocol/ap-avs/model" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/model" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) type StatService struct { diff --git a/core/taskengine/stats_test.go b/core/taskengine/stats_test.go index 2e9c1576..feee25f4 100644 --- a/core/taskengine/stats_test.go +++ b/core/taskengine/stats_test.go @@ -5,10 +5,10 @@ import ( "reflect" "testing" - "github.com/AvaProtocol/ap-avs/core/testutil" - "github.com/AvaProtocol/ap-avs/model" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/model" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) func TestTaskStatCount(t *testing.T) { diff --git a/core/taskengine/trigger/block.go b/core/taskengine/trigger/block.go index dddfb917..a594643d 100644 --- a/core/taskengine/trigger/block.go +++ b/core/taskengine/trigger/block.go @@ -7,7 +7,7 @@ import ( "math/big" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" sdklogging "github.com/Layr-Labs/eigensdk-go/logging" "github.com/ethereum/go-ethereum/core/types" diff --git a/core/taskengine/trigger/event.go b/core/taskengine/trigger/event.go index 231a82cd..0597b3ea 100644 --- a/core/taskengine/trigger/event.go +++ b/core/taskengine/trigger/event.go @@ -7,7 +7,7 @@ import ( "sync" "time" - "github.com/AvaProtocol/ap-avs/core/taskengine/macros" + "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine/macros" sdklogging "github.com/Layr-Labs/eigensdk-go/logging" "github.com/dop251/goja" "github.com/samber/lo" @@ -17,7 +17,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) var ( diff --git a/core/taskengine/trigger/event_test.go b/core/taskengine/trigger/event_test.go index 7676fd09..657050ed 100644 --- a/core/taskengine/trigger/event_test.go +++ b/core/taskengine/trigger/event_test.go @@ -3,9 +3,9 @@ package trigger import ( "testing" - "github.com/AvaProtocol/ap-avs/core/taskengine/macros" - "github.com/AvaProtocol/ap-avs/core/testutil" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine/macros" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) func TestTriggerTopicMatch(t *testing.T) { @@ -340,11 +340,11 @@ func TestTriggerWithContractReadBindingInExpression(t *testing.T) { // // /usr/local/go/src/runtime/panic.go:785 +0x124 // -// github.com/AvaProtocol/ap-avs/core/taskengine/trigger.(*EventTrigger).Evaluate(0x140000ba3e0?, 0x140004f1600, 0x140001e9f18) +// github.com/AvaProtocol/EigenLayer-AVS/core/taskengine/trigger.(*EventTrigger).Evaluate(0x140000ba3e0?, 0x140004f1600, 0x140001e9f18) // // /Users/vinh/Sites/oak/eigenlayer/EigenLayer-AVS/core/taskengine/trigger/event.go:185 +0x704 // -// github.com/AvaProtocol/ap-avs/core/taskengine/trigger.TestTriggerEventExpressionWontCrashOnInvalidInput(0x140004e6b60) +// github.com/AvaProtocol/EigenLayer-AVS/core/taskengine/trigger.TestTriggerEventExpressionWontCrashOnInvalidInput(0x140004e6b60) // // /Users/vinh/Sites/oak/eigenlayer/EigenLayer-AVS/core/taskengine/trigger/event_test.go:330 +0x1b0 // @@ -357,7 +357,7 @@ func TestTriggerWithContractReadBindingInExpression(t *testing.T) { // /usr/local/go/src/testing/testing.go:1743 +0x314 // // exit status 2 -// FAIL github.com/AvaProtocol/ap-avs/core/taskengine/trigger 3.929s +// FAIL github.com/AvaProtocol/EigenLayer-AVS/core/taskengine/trigger 3.929s func TestTriggerEventExpressionWontCrashOnInvalidInput(t *testing.T) { tests := []struct { name string diff --git a/core/taskengine/trigger/time.go b/core/taskengine/trigger/time.go index ae059466..95ef8675 100644 --- a/core/taskengine/trigger/time.go +++ b/core/taskengine/trigger/time.go @@ -6,7 +6,7 @@ import ( "sync" "time" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" sdklogging "github.com/Layr-Labs/eigensdk-go/logging" "github.com/go-co-op/gocron/v2" ) diff --git a/core/taskengine/utils.go b/core/taskengine/utils.go index 298b5e1d..9bdd40f2 100644 --- a/core/taskengine/utils.go +++ b/core/taskengine/utils.go @@ -6,7 +6,7 @@ import ( "fmt" "math/big" - "github.com/AvaProtocol/ap-avs/pkg/erc20" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc20" "github.com/ethereum/go-ethereum/core/types" "github.com/shopspring/decimal" ) diff --git a/core/taskengine/validation.go b/core/taskengine/validation.go index 00d7eac1..016850ec 100644 --- a/core/taskengine/validation.go +++ b/core/taskengine/validation.go @@ -1,8 +1,8 @@ package taskengine import ( - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/storage" "github.com/ethereum/go-ethereum/common" ) diff --git a/core/taskengine/validation_test.go b/core/taskengine/validation_test.go index 24d08d9b..aa67bd13 100644 --- a/core/taskengine/validation_test.go +++ b/core/taskengine/validation_test.go @@ -5,10 +5,10 @@ import ( "github.com/ethereum/go-ethereum/common" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/storage" - "github.com/AvaProtocol/ap-avs/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" ) func TestWalletOwnerReturnTrueForDefaultAddress(t *testing.T) { diff --git a/core/taskengine/vm.go b/core/taskengine/vm.go index 56b50c96..fcd4145a 100644 --- a/core/taskengine/vm.go +++ b/core/taskengine/vm.go @@ -16,12 +16,12 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" - "github.com/AvaProtocol/ap-avs/core/config" - "github.com/AvaProtocol/ap-avs/core/taskengine/macros" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/pkg/erc20" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" + "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine/macros" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc20" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) type VMState string @@ -299,7 +299,12 @@ func NewVMWithData(task *model.Task, reason *avsproto.TriggerReason, smartWallet TransactionHash: event.TxHash.Hex(), Address: event.Address.Hex(), BlockNumber: event.BlockNumber, - BlockTimestamp: blockHeader.Time, + // in Ethereum, timestamp is in seconds, but in our app we use milliseconds, so we need to convert it + // https://docs.soliditylang.org/en/latest/units-and-global-variables.html#block-and-transaction-properties + // This is requested in ticket https://github.com/AvaProtocol/EigenLayer-AVS/issues/191 and implemented in https://github.com/AvaProtocol/EigenLayer-AVS/pull/192/files + // But in that PR, the avs.proto file is updated and documented that this field is in milliseconds but we forgot to update the field in the code. + // This update happen at a time later and migration is configured to reflect the change in PR 192. + BlockTimestamp: blockHeader.Time * 1000, FromAddress: parseTransfer.From.String(), ToAddress: parseTransfer.To.String(), Value: parseTransfer.Value.String(), diff --git a/core/taskengine/vm_runner_branch.go b/core/taskengine/vm_runner_branch.go index 5028a437..e1366a50 100644 --- a/core/taskengine/vm_runner_branch.go +++ b/core/taskengine/vm_runner_branch.go @@ -5,7 +5,7 @@ import ( "strings" "time" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" "github.com/dop251/goja" ) diff --git a/core/taskengine/vm_runner_branch_test.go b/core/taskengine/vm_runner_branch_test.go index 3da4577e..d9404334 100644 --- a/core/taskengine/vm_runner_branch_test.go +++ b/core/taskengine/vm_runner_branch_test.go @@ -8,11 +8,11 @@ import ( "strings" "testing" - "github.com/AvaProtocol/ap-avs/core/testutil" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/pkg/gow" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/gow" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) func TestRunTaskWithMultipleConditions(t *testing.T) { diff --git a/core/taskengine/vm_runner_contract_read.go b/core/taskengine/vm_runner_contract_read.go index c1b6020f..948d2413 100644 --- a/core/taskengine/vm_runner_contract_read.go +++ b/core/taskengine/vm_runner_contract_read.go @@ -11,9 +11,9 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" - "github.com/AvaProtocol/ap-avs/pkg/byte4" - "github.com/AvaProtocol/ap-avs/pkg/gow" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/byte4" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/gow" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) type ContractReadProcessor struct { diff --git a/core/taskengine/vm_runner_contract_read_test.go b/core/taskengine/vm_runner_contract_read_test.go index d506d150..af4162d7 100644 --- a/core/taskengine/vm_runner_contract_read_test.go +++ b/core/taskengine/vm_runner_contract_read_test.go @@ -4,10 +4,10 @@ import ( "strings" "testing" - "github.com/AvaProtocol/ap-avs/core/testutil" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/pkg/gow" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/gow" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) func TestContractReadSimpleReturn(t *testing.T) { diff --git a/core/taskengine/vm_runner_contract_write.go b/core/taskengine/vm_runner_contract_write.go index dcdc5934..8681b6a5 100644 --- a/core/taskengine/vm_runner_contract_write.go +++ b/core/taskengine/vm_runner_contract_write.go @@ -12,10 +12,10 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" - "github.com/AvaProtocol/ap-avs/core/chainio/aa" - "github.com/AvaProtocol/ap-avs/core/config" - "github.com/AvaProtocol/ap-avs/pkg/erc4337/preset" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/aa" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc4337/preset" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) type ContractWriteProcessor struct { diff --git a/core/taskengine/vm_runner_contract_write_test.go b/core/taskengine/vm_runner_contract_write_test.go index abd45e72..df9c32c5 100644 --- a/core/taskengine/vm_runner_contract_write_test.go +++ b/core/taskengine/vm_runner_contract_write_test.go @@ -5,11 +5,11 @@ import ( "strings" "testing" - "github.com/AvaProtocol/ap-avs/core/chainio/aa" - "github.com/AvaProtocol/ap-avs/core/testutil" - "github.com/AvaProtocol/ap-avs/model" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/aa" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/model" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/storage" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" ) diff --git a/core/taskengine/vm_runner_contract_write_transaction_limit_test.go b/core/taskengine/vm_runner_contract_write_transaction_limit_test.go index d4da81d8..318396d8 100644 --- a/core/taskengine/vm_runner_contract_write_transaction_limit_test.go +++ b/core/taskengine/vm_runner_contract_write_transaction_limit_test.go @@ -8,15 +8,15 @@ import ( "github.com/ethereum/go-ethereum/common" - "github.com/AvaProtocol/ap-avs/core/chainio/aa" - "github.com/AvaProtocol/ap-avs/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/aa" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" - // "github.com/AvaProtocol/ap-avs/pkg/erc4337/preset" - // "github.com/AvaProtocol/ap-avs/pkg/erc4337/userop" + // "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc4337/preset" + // "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc4337/userop" - "github.com/AvaProtocol/ap-avs/model" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/model" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) func TestTransactionSponsorshipLimit(t *testing.T) { diff --git a/core/taskengine/vm_runner_customcode.go b/core/taskengine/vm_runner_customcode.go index ba9b22fb..24d7f917 100644 --- a/core/taskengine/vm_runner_customcode.go +++ b/core/taskengine/vm_runner_customcode.go @@ -9,8 +9,8 @@ import ( "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/structpb" - "github.com/AvaProtocol/ap-avs/core/taskengine/macros" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine/macros" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) type JSProcessor struct { diff --git a/core/taskengine/vm_runner_customcode_test.go b/core/taskengine/vm_runner_customcode_test.go index 42e9f9d3..bdc9a556 100644 --- a/core/taskengine/vm_runner_customcode_test.go +++ b/core/taskengine/vm_runner_customcode_test.go @@ -5,10 +5,10 @@ import ( "strings" "testing" - "github.com/AvaProtocol/ap-avs/core/testutil" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/pkg/gow" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/gow" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) func TestRunJavaScript(t *testing.T) { diff --git a/core/taskengine/vm_runner_filter.go b/core/taskengine/vm_runner_filter.go index 2065ec4a..92f1c3b0 100644 --- a/core/taskengine/vm_runner_filter.go +++ b/core/taskengine/vm_runner_filter.go @@ -5,8 +5,8 @@ import ( "strings" "time" - "github.com/AvaProtocol/ap-avs/core/taskengine/macros" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine/macros" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" "github.com/dop251/goja" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/structpb" diff --git a/core/taskengine/vm_runner_filter_test.go b/core/taskengine/vm_runner_filter_test.go index 2ea71ae5..316ad4aa 100644 --- a/core/taskengine/vm_runner_filter_test.go +++ b/core/taskengine/vm_runner_filter_test.go @@ -5,10 +5,10 @@ import ( "strings" "testing" - "github.com/AvaProtocol/ap-avs/core/testutil" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/pkg/gow" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/gow" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) type MockTokenPrice struct { diff --git a/core/taskengine/vm_runner_graphql_query.go b/core/taskengine/vm_runner_graphql_query.go index 0c4641f1..9b32f16f 100644 --- a/core/taskengine/vm_runner_graphql_query.go +++ b/core/taskengine/vm_runner_graphql_query.go @@ -7,8 +7,8 @@ import ( "strings" "time" - "github.com/AvaProtocol/ap-avs/pkg/graphql" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/graphql" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/structpb" ) diff --git a/core/taskengine/vm_runner_graphql_query_test.go b/core/taskengine/vm_runner_graphql_query_test.go index f91f8b27..6bdf5c25 100644 --- a/core/taskengine/vm_runner_graphql_query_test.go +++ b/core/taskengine/vm_runner_graphql_query_test.go @@ -4,10 +4,10 @@ import ( "strings" "testing" - "github.com/AvaProtocol/ap-avs/core/testutil" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/pkg/gow" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/gow" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) // Test make a query to a demo graphql server to ensure our node processing work diff --git a/core/taskengine/vm_runner_rest.go b/core/taskengine/vm_runner_rest.go index 3de0f2f2..68f5f685 100644 --- a/core/taskengine/vm_runner_rest.go +++ b/core/taskengine/vm_runner_rest.go @@ -11,7 +11,7 @@ import ( "google.golang.org/protobuf/types/known/anypb" "google.golang.org/protobuf/types/known/structpb" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) type RestProcessor struct { diff --git a/core/taskengine/vm_runner_rest_test.go b/core/taskengine/vm_runner_rest_test.go index 568dce2a..de6f6f38 100644 --- a/core/taskengine/vm_runner_rest_test.go +++ b/core/taskengine/vm_runner_rest_test.go @@ -8,10 +8,10 @@ import ( "strings" "testing" - "github.com/AvaProtocol/ap-avs/core/testutil" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/pkg/gow" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/gow" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) func TestRestRequest(t *testing.T) { diff --git a/core/taskengine/vm_test.go b/core/taskengine/vm_test.go index 8e6cec5e..df32e177 100644 --- a/core/taskengine/vm_test.go +++ b/core/taskengine/vm_test.go @@ -10,10 +10,10 @@ import ( "github.com/dop251/goja" - "github.com/AvaProtocol/ap-avs/core/testutil" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/pkg/gow" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/gow" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) func TestVMCompile(t *testing.T) { diff --git a/core/testutil/utils.go b/core/testutil/utils.go index 4d2b037f..daa3f53c 100644 --- a/core/testutil/utils.go +++ b/core/testutil/utils.go @@ -8,7 +8,7 @@ import ( "strings" "time" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" sdklogging "github.com/Layr-Labs/eigensdk-go/logging" "github.com/allegro/bigcache/v3" "github.com/ethereum/go-ethereum/common" @@ -16,9 +16,9 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" - "github.com/AvaProtocol/ap-avs/core/config" - "github.com/AvaProtocol/ap-avs/model" - "github.com/AvaProtocol/ap-avs/storage" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" + "github.com/AvaProtocol/EigenLayer-AVS/model" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) const ( diff --git a/core/utils.go b/core/utils.go index 6941c41e..560634df 100644 --- a/core/utils.go +++ b/core/utils.go @@ -3,7 +3,7 @@ package core import ( "math/big" - cstaskmanager "github.com/AvaProtocol/ap-avs/contracts/bindings/AutomationTaskManager" + cstaskmanager "github.com/AvaProtocol/EigenLayer-AVS/contracts/bindings/AutomationTaskManager" "github.com/Layr-Labs/eigensdk-go/crypto/bls" "github.com/ethereum/go-ethereum/accounts/abi" "golang.org/x/crypto/sha3" diff --git a/dockerfiles/operator.Dockerfile b/dockerfiles/operator.Dockerfile index d8d31668..879b7cf7 100644 --- a/dockerfiles/operator.Dockerfile +++ b/dockerfiles/operator.Dockerfile @@ -11,8 +11,8 @@ RUN go mod download COPY . ./ RUN CGO_ENABLED=0 GOOS=linux go build \ - -ldflags "-X github.com/AvaProtocol/ap-avs/version.semver=$RELEASE_TAG" \ - -ldflags "-X github.com/AvaProtocol/ap-avs/version.revision=$COMMIT_SHA" \ + -ldflags "-X github.com/AvaProtocol/EigenLayer-AVS/version.semver=$RELEASE_TAG" \ + -ldflags "-X github.com/AvaProtocol/EigenLayer-AVS/version.revision=$COMMIT_SHA" \ -o /ava diff --git a/go.mod b/go.mod index 7148b6c1..54d371d5 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ -module github.com/AvaProtocol/ap-avs +module github.com/AvaProtocol/EigenLayer-AVS -go 1.23 +go 1.24 require ( github.com/Layr-Labs/cerberus-api v0.0.0-20241016214048-d52f5ddc5559 @@ -14,7 +14,6 @@ require ( github.com/go-playground/validator/v10 v10.22.1 github.com/go-resty/resty/v2 v2.16.2 github.com/golang-jwt/jwt/v5 v5.2.1 - github.com/k0kubun/pp/v3 v3.4.1 github.com/labstack/echo/v4 v4.12.0 github.com/mitchellh/mapstructure v1.5.0 github.com/oklog/ulid/v2 v2.1.1-0.20240413180941-96c4edf226ef diff --git a/go.sum b/go.sum index a459bbbf..84aba0e8 100644 --- a/go.sum +++ b/go.sum @@ -236,8 +236,6 @@ github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7Bd github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= -github.com/k0kubun/pp/v3 v3.4.1 h1:1WdFZDRRqe8UsR61N/2RoOZ3ziTEqgTPVqKrHeb779Y= -github.com/k0kubun/pp/v3 v3.4.1/go.mod h1:+SiNiqKnBfw1Nkj82Lh5bIeKQOAkPy6Xw9CAZUZ8npI= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= diff --git a/main.go b/main.go index 0d2b0109..1e47cc0f 100644 --- a/main.go +++ b/main.go @@ -3,7 +3,7 @@ Copyright © 2024 NAME HERE */ package main -import "github.com/AvaProtocol/ap-avs/cmd" +import "github.com/AvaProtocol/EigenLayer-AVS/cmd" func main() { cmd.Execute() diff --git a/migrations/20250405-232000-change-epoch-to-ms.go b/migrations/20250405-232000-change-epoch-to-ms.go new file mode 100644 index 00000000..2062bc70 --- /dev/null +++ b/migrations/20250405-232000-change-epoch-to-ms.go @@ -0,0 +1,134 @@ +package migrations + +import ( + //"strconv" + "google.golang.org/protobuf/encoding/protojson" + + "github.com/AvaProtocol/EigenLayer-AVS/storage" + "github.com/AvaProtocol/EigenLayer-AVS/model" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" +) + +func ChangeEpochToMs(db storage.Storage) (int, error) { + // This migration converts epoch timestamps from seconds to milliseconds + // We need to identify keys that store epoch timestamps and convert their values + + // Our app used to use epoch time in seconds, but we switched to milliseconds per this issue https://github.com/AvaProtocol/EigenLayer-AVS/issues/191 + + // Based on the context, we need to find all keys that store epoch timestamps + // Let's define a threshold to determine if a timestamp is in seconds + // If timestamp <= threshold, we assume it's in seconds and needs conversion + const ( + // A reasonable threshold for distinguishing seconds vs milliseconds + // This represents Jan/1/20250- any timestamp before this in our db is certainly in seconds + // When a timestamp is in milliseconds, in our app context, it will be always bigger than 1704067200000 + timestampThreshold = 2521872514 + ) + + // Get all execution in the database by prefix. Refer to our doc.go and schema.go for the detail + taskKeys, err := db.ListKeys("t:*") + if err != nil { + return 0, err + } + // Now we will iterate over all task keys and check if the timestamp is in seconds + updates := make(map[string][]byte) + totalUpdated := 0 + for _, key := range taskKeys { + taskRawByte, err := db.GetKey([]byte(key)) + if err != nil { + continue + } + + task := model.NewTask() + if err := task.FromStorageData(taskRawByte); err != nil { + continue + } + + if task.Task.StartAt > 0 && task.Task.StartAt < timestampThreshold { + // Convert the timestamp to milliseconds + task.Task.StartAt = task.Task.StartAt * 1000 + } + if task.Task.ExpiredAt > 0 && task.Task.ExpiredAt < timestampThreshold { + // Convert the timestamp to milliseconds + task.Task.ExpiredAt = task.Task.ExpiredAt * 1000 + } + if task.Task.CompletedAt > 0 && task.Task.CompletedAt < timestampThreshold { + // Convert the timestamp to milliseconds + task.Task.CompletedAt = task.Task.CompletedAt * 1000 + } + if task.Task.LastRanAt > 0 && task.Task.LastRanAt < timestampThreshold { + // Convert the timestamp to milliseconds + task.Task.LastRanAt = task.Task.LastRanAt * 1000 + } + + // Update the task in the database + updates[key], err = task.ToJSON() + if err != nil { + return 0, err + } + totalUpdated++ + } + + // Now we will iterate over all history run keys and check if the timestamp is in seconds + historyExecutionKeys, err := db.ListKeys("history:*") + if err != nil { + return 0, err + } + + for _, key := range historyExecutionKeys { + executionRawByte, err := db.GetKey([]byte(key)) + if err != nil { + continue + } + + exec := avsproto.Execution{} + err = protojson.Unmarshal(executionRawByte, &exec) + if err != nil { + return 0, err + } + + // Convert the timestamp to milliseconds for the execution + if exec.StartAt > 0 && exec.StartAt < timestampThreshold { + exec.StartAt = exec.StartAt * 1000 + } + if exec.EndAt > 0 && exec.EndAt < timestampThreshold { + // Convert the timestamp to milliseconds + exec.EndAt = exec.EndAt * 1000 + } + + // Convert start/end of each step to milliseconds + for i, step := range exec.Steps { + if step.StartAt > 0 && step.StartAt < timestampThreshold { + // Convert the timestamp to milliseconds + exec.Steps[i].StartAt = step.StartAt * 1000 + } + if step.EndAt > 0 && step.EndAt < timestampThreshold { + // Convert the timestamp to milliseconds + exec.Steps[i].EndAt = step.EndAt * 1000 + } + } + + if outputData := exec.GetTransferLog(); outputData != nil { + if outputData.BlockTimestamp > 0 && outputData.BlockTimestamp < timestampThreshold { + outputData.BlockTimestamp = outputData.BlockTimestamp * 1000 + } + } else if outputData := exec.GetTime(); outputData != nil { + if outputData.Epoch > 0 && outputData.Epoch < timestampThreshold { + outputData.Epoch = outputData.Epoch * 1000 + } + } + + updates[key], err = protojson.Marshal(&exec) + if err != nil { + return 0, err + } + totalUpdated++ + } + + // Write all updates to the database + if err := db.BatchWrite(updates); err != nil { + return 0, err + } + + return totalUpdated, nil +} diff --git a/migrations/20250405-232000-change-epoch-to-ms_test.go b/migrations/20250405-232000-change-epoch-to-ms_test.go new file mode 100644 index 00000000..eb0f139c --- /dev/null +++ b/migrations/20250405-232000-change-epoch-to-ms_test.go @@ -0,0 +1,218 @@ +package migrations + +import ( + "fmt" + "testing" + "time" + + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" + + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "google.golang.org/protobuf/encoding/protojson" // Correct import for protojson +) + +func TestChangeEpochToMs(t *testing.T) { + // --- Setup --- + logger := testutil.GetLogger() // Use logger from testutil if needed by setup funcs + _ = logger // Avoid unused variable error if logger isn't directly used + db := testutil.TestMustDB() + defer db.Close() + + // Sample data IDs + taskID := "task-123" + execID := "exec-abc" + + // Sample timestamps in seconds (ensure they are below the migration threshold) + nowSeconds := time.Now().Unix() // e.g., 1715000000 + startSeconds := nowSeconds - 3600 + expiredSeconds := nowSeconds + 86400 + completedSeconds := nowSeconds - 60 + lastRanSeconds := nowSeconds - 120 + execStartSeconds := nowSeconds - 30 + execEndSeconds := nowSeconds - 5 + stepStartSeconds := execStartSeconds + 1 + stepEndSeconds := execEndSeconds - 1 + blockTimestampSeconds := nowSeconds - 10 + epochSeconds := nowSeconds - 15 + + // Expected timestamps in milliseconds + expectedStartMs := startSeconds * 1000 + expectedExpiredMs := expiredSeconds * 1000 + expectedCompletedMs := completedSeconds * 1000 + expectedLastRanMs := lastRanSeconds * 1000 + expectedExecStartMs := execStartSeconds * 1000 + expectedExecEndMs := execEndSeconds * 1000 + expectedStepStartMs := stepStartSeconds * 1000 + expectedStepEndMs := stepEndSeconds * 1000 + expectedBlockTimestampMs := blockTimestampSeconds * 1000 + expectedEpochMs := epochSeconds * 1000 + + // Create Sample Task Data (using avsproto.Task directly as migration handles it) + sampleTask := &avsproto.Task{ + Id: taskID, + StartAt: startSeconds, // Seconds + ExpiredAt: expiredSeconds, // Seconds + CompletedAt: completedSeconds, // Seconds + LastRanAt: lastRanSeconds, // Seconds + // Other fields can be default/empty for this test + } + + // Create Sample Execution Data + sampleExec := &avsproto.Execution{ + Id: execID, + StartAt: execStartSeconds, // Seconds + EndAt: execEndSeconds, // Seconds + Steps: []*avsproto.Execution_Step{ + { + NodeId: "step-1", + Success: true, + StartAt: stepStartSeconds, // Seconds + EndAt: stepEndSeconds, // Seconds + }, + }, + // Include one type of output data for testing + OutputData: &avsproto.Execution_TransferLog{ + TransferLog: &avsproto.Execution_TransferLogOutput{ + BlockTimestamp: uint64(blockTimestampSeconds), // Seconds + // Other fields irrelevant for this test + }, + }, + // Other fields can be default/empty + } + // Add another execution to test TimeOutput + execID2 := "exec-def" + sampleExec2 := &avsproto.Execution{ + Id: execID2, + StartAt: execStartSeconds, // Seconds + EndAt: execEndSeconds, // Seconds + OutputData: &avsproto.Execution_Time{ + Time: &avsproto.Execution_TimeOutput{ + Epoch: uint64(epochSeconds), // Seconds + }, + }, + // Other fields can be default/empty + } + + + // Serialize data using protojson (matching migration) + taskBytes, err := protojson.Marshal(sampleTask) + if err != nil { + t.Fatalf("Failed to marshal sample task: %v", err) + } + execBytes, err := protojson.Marshal(sampleExec) + if err != nil { + t.Fatalf("Failed to marshal sample execution: %v", err) + } + execBytes2, err := protojson.Marshal(sampleExec2) + if err != nil { + t.Fatalf("Failed to marshal sample execution 2: %v", err) + } + + // Store data in DB using correct keys + taskKey := fmt.Sprintf("t:%s", taskID) + execKey := fmt.Sprintf("history:%s:%s", taskID, execID) + execKey2 := fmt.Sprintf("history:%s:%s", taskID, execID2) + + // Use BatchWrite as seen in the migration code for setting multiple keys + updates := map[string][]byte{ + taskKey: taskBytes, + execKey: execBytes, + execKey2: execBytes2, + } + if err := db.BatchWrite(updates); err != nil { + t.Fatalf("Failed to write initial data to db: %v", err) + } + + // --- Execute Migration --- + updatedCount, err := ChangeEpochToMs(db) + if err != nil { + t.Fatalf("Migration function failed: %v", err) + } + // Check if the expected number of records were reported as updated + // Modify '3' if you add/remove test records + expectedUpdates := 3 + if updatedCount != expectedUpdates { + t.Errorf("Migration reported updating %d records, expected %d", updatedCount, expectedUpdates) + } + + // --- Verification --- + + // Verify Task Data using GetKey + retrievedTaskBytes, err := db.GetKey([]byte(taskKey)) + if err != nil { + t.Fatalf("Failed to retrieve task data after migration: %v", err) + } + retrievedTask := &avsproto.Task{} + if err := protojson.Unmarshal(retrievedTaskBytes, retrievedTask); err != nil { + t.Fatalf("Failed to unmarshal retrieved task data: %v", err) + } + + if retrievedTask.StartAt != expectedStartMs { + t.Errorf("Task StartAt incorrect: got %d, want %d", retrievedTask.StartAt, expectedStartMs) + } + if retrievedTask.ExpiredAt != expectedExpiredMs { + t.Errorf("Task ExpiredAt incorrect: got %d, want %d", retrievedTask.ExpiredAt, expectedExpiredMs) + } + if retrievedTask.CompletedAt != expectedCompletedMs { + t.Errorf("Task CompletedAt incorrect: got %d, want %d", retrievedTask.CompletedAt, expectedCompletedMs) + } + if retrievedTask.LastRanAt != expectedLastRanMs { + t.Errorf("Task LastRanAt incorrect: got %d, want %d", retrievedTask.LastRanAt, expectedLastRanMs) + } + + // Verify Execution Data 1 (TransferLog) using GetKey + retrievedExecBytes, err := db.GetKey([]byte(execKey)) + if err != nil { + t.Fatalf("Failed to retrieve execution data after migration: %v", err) + } + retrievedExec := &avsproto.Execution{} + if err := protojson.Unmarshal(retrievedExecBytes, retrievedExec); err != nil { + t.Fatalf("Failed to unmarshal retrieved execution data: %v", err) + } + + if retrievedExec.StartAt != expectedExecStartMs { + t.Errorf("Execution StartAt incorrect: got %d, want %d", retrievedExec.StartAt, expectedExecStartMs) + } + if retrievedExec.EndAt != expectedExecEndMs { + t.Errorf("Execution EndAt incorrect: got %d, want %d", retrievedExec.EndAt, expectedExecEndMs) + } + + if len(retrievedExec.Steps) != 1 { + t.Fatalf("Incorrect number of steps retrieved: got %d, want 1", len(retrievedExec.Steps)) + } + retrievedStep := retrievedExec.Steps[0] + if retrievedStep.StartAt != expectedStepStartMs { + t.Errorf("Step StartAt incorrect: got %d, want %d", retrievedStep.StartAt, expectedStepStartMs) + } + if retrievedStep.EndAt != expectedStepEndMs { + t.Errorf("Step EndAt incorrect: got %d, want %d", retrievedStep.EndAt, expectedStepEndMs) + } + + // Verify Execution Output Data (TransferLog) + if transferLogOutput := retrievedExec.GetTransferLog(); transferLogOutput != nil { + if transferLogOutput.BlockTimestamp != uint64(expectedBlockTimestampMs) { + t.Errorf("TransferLog BlockTimestamp incorrect: got %d, want %d", transferLogOutput.BlockTimestamp, expectedBlockTimestampMs) + } + } else { + t.Errorf("Expected TransferLog output data, but got nil or different type") + } + + // Verify Execution Data 2 (TimeOutput) using GetKey + retrievedExecBytes2, err := db.GetKey([]byte(execKey2)) + if err != nil { + t.Fatalf("Failed to retrieve execution data 2 after migration: %v", err) + } + retrievedExec2 := &avsproto.Execution{} + if err := protojson.Unmarshal(retrievedExecBytes2, retrievedExec2); err != nil { + t.Fatalf("Failed to unmarshal retrieved execution data 2: %v", err) + } + + // Verify Execution Output Data (TimeOutput) + if timeOutput := retrievedExec2.GetTime(); timeOutput != nil { + if timeOutput.Epoch != uint64(expectedEpochMs) { + t.Errorf("TimeOutput Epoch incorrect: got %d, want %d", timeOutput.Epoch, expectedEpochMs) + } + } else { + t.Errorf("Expected Time output data, but got nil or different type") + } +} diff --git a/migrations/README.md b/migrations/README.md new file mode 100644 index 00000000..4d754afa --- /dev/null +++ b/migrations/README.md @@ -0,0 +1,52 @@ +# Database Migrations + +This document outlines how to create and manage database migrations for the EigenLayer-AVS project. + +## What are Migrations? + +Migrations are a way to make incremental, reversible changes to the database schema or data. They help maintain database consistency across different environments and versions of the application. + +## Creating a New Migration + +To create a new migration, follow these steps: + +1. Create a new Go file in the `migrations` package with a descriptive name (e.g., `my_migration.go`) + +2. Define your migration function that implements the required signature: + + ```go + func YourMigrationName(db storage.Storage) error { + // Migration logic here + // Use db.Put(), db.Get(), db.Delete(), etc. to modify data + + return nil // Return error if migration fails + } + ``` + +3. Register your migration in the `migrations.go` file by adding it to the `Migrations` slice: + + ```go + var Migrations = []migrator.Migration{ + // Existing migrations... + { + Name: "your-migration-name", + Function: YourMigrationName, + }, + } + ``` + +## Migration Best Practices + +1. **Descriptive Names**: Use clear, descriptive names for your migrations that indicate what they do. + +2. **Idempotency**: Migrations should be idempotent (can be run multiple times without side effects). + +3. **Atomicity**: Each migration should represent a single, atomic change to the database. + +4. **Error Handling**: Properly handle errors and return them to the migrator. + +5. **Documentation**: Add comments to your migration code explaining what it does and why. + +## Example Migration + +An example of migration can be view in function `ChangeEpochToMs` diff --git a/migrations/migrations.go b/migrations/migrations.go new file mode 100644 index 00000000..de956dd8 --- /dev/null +++ b/migrations/migrations.go @@ -0,0 +1,17 @@ +package migrations + +import ( + "github.com/AvaProtocol/EigenLayer-AVS/core/migrator" +) + +var Migrations = []migrator.Migration{ + { + // The name of the migration will be recored in our key-value store, and it's sorted lexicographically + // so we can use the timestamp to sort the migrations in the right order for debugging + // We should prefix the name with the timestamp in format of YYYYMMDD-HHMMSS + // Not a requirement but strongly recommended + Name: "20250405-232000-change-epoch-to-ms", + Function: ChangeEpochToMs, + }, + // Each migration should be added to this list +} diff --git a/model/task.go b/model/task.go index 7dc67903..62039408 100644 --- a/model/task.go +++ b/model/task.go @@ -11,7 +11,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/oklog/ulid/v2" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" ) type Task struct { diff --git a/model/user.go b/model/user.go index 829a0962..ca01877d 100644 --- a/model/user.go +++ b/model/user.go @@ -5,7 +5,7 @@ import ( "fmt" "math/big" - "github.com/AvaProtocol/ap-avs/core/chainio/aa" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/aa" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" ) diff --git a/operator/alias.go b/operator/alias.go index b230df19..7b716638 100644 --- a/operator/alias.go +++ b/operator/alias.go @@ -5,7 +5,7 @@ import ( "crypto/ecdsa" "fmt" - "github.com/AvaProtocol/ap-avs/core/chainio/apconfig" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/apconfig" "github.com/ethereum/go-ethereum/crypto" eigensdkecdsa "github.com/Layr-Labs/eigensdk-go/crypto/ecdsa" diff --git a/operator/operator.go b/operator/operator.go index 63ebaf19..c4aba503 100644 --- a/operator/operator.go +++ b/operator/operator.go @@ -10,10 +10,10 @@ import ( "google.golang.org/grpc" - "github.com/AvaProtocol/ap-avs/core/chainio" - "github.com/AvaProtocol/ap-avs/core/chainio/apconfig" - "github.com/AvaProtocol/ap-avs/core/chainio/signer" - "github.com/AvaProtocol/ap-avs/metrics" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/apconfig" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/signer" + "github.com/AvaProtocol/EigenLayer-AVS/metrics" "github.com/Layr-Labs/eigensdk-go/metrics/collectors/economic" rpccalls "github.com/Layr-Labs/eigensdk-go/metrics/collectors/rpc_calls" "github.com/Layr-Labs/eigensdk-go/nodeapi" @@ -37,8 +37,8 @@ import ( sdkmetrics "github.com/Layr-Labs/eigensdk-go/metrics" sdktypes "github.com/Layr-Labs/eigensdk-go/types" - //"github.com/AvaProtocol/ap-avs/aggregator" - cstaskmanager "github.com/AvaProtocol/ap-avs/contracts/bindings/AutomationTaskManager" + //"github.com/AvaProtocol/EigenLayer-AVS/aggregator" + cstaskmanager "github.com/AvaProtocol/EigenLayer-AVS/contracts/bindings/AutomationTaskManager" // insecure for local dev blssignerV1 "github.com/Layr-Labs/cerberus-api/pkg/api/v1" @@ -46,14 +46,14 @@ import ( "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" - "github.com/AvaProtocol/ap-avs/core/auth" - avsproto "github.com/AvaProtocol/ap-avs/protobuf" - "github.com/AvaProtocol/ap-avs/version" + "github.com/AvaProtocol/EigenLayer-AVS/core/auth" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/version" - "github.com/AvaProtocol/ap-avs/core/config" - triggerengine "github.com/AvaProtocol/ap-avs/core/taskengine/trigger" - "github.com/AvaProtocol/ap-avs/pkg/ipfetcher" - "github.com/AvaProtocol/ap-avs/pkg/timekeeper" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" + triggerengine "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine/trigger" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/ipfetcher" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/timekeeper" ) const AVS_NAME = "ap-avs" diff --git a/operator/worker_loop.go b/operator/worker_loop.go index 60c677e3..45d47b3f 100644 --- a/operator/worker_loop.go +++ b/operator/worker_loop.go @@ -10,11 +10,11 @@ import ( "github.com/go-co-op/gocron/v2" - "github.com/AvaProtocol/ap-avs/core/taskengine" - "github.com/AvaProtocol/ap-avs/core/taskengine/macros" - triggerengine "github.com/AvaProtocol/ap-avs/core/taskengine/trigger" - avspb "github.com/AvaProtocol/ap-avs/protobuf" - "github.com/AvaProtocol/ap-avs/version" + "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine" + "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine/macros" + triggerengine "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine/trigger" + avspb "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/version" ) const ( diff --git a/pkg/erc4337/bundler/client.go b/pkg/erc4337/bundler/client.go index 081e825e..330759b7 100644 --- a/pkg/erc4337/bundler/client.go +++ b/pkg/erc4337/bundler/client.go @@ -10,7 +10,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rpc" - "github.com/AvaProtocol/ap-avs/pkg/erc4337/userop" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc4337/userop" ) // BundlerClient defines a client for interacting with an EIP-4337 bundler RPC endpoint. diff --git a/pkg/erc4337/preset/builder.go b/pkg/erc4337/preset/builder.go index 508575be..38b84c56 100644 --- a/pkg/erc4337/preset/builder.go +++ b/pkg/erc4337/preset/builder.go @@ -19,9 +19,9 @@ import ( "github.com/AvaProtocol/ap-avs/core/chainio/signer" "github.com/AvaProtocol/ap-avs/core/config" - "github.com/AvaProtocol/ap-avs/pkg/eip1559" - "github.com/AvaProtocol/ap-avs/pkg/erc4337/bundler" - "github.com/AvaProtocol/ap-avs/pkg/erc4337/userop" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/eip1559" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc4337/bundler" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc4337/userop" ) var ( diff --git a/pkg/erc4337/preset/builder_test.go b/pkg/erc4337/preset/builder_test.go index dcf85b10..7a144e36 100644 --- a/pkg/erc4337/preset/builder_test.go +++ b/pkg/erc4337/preset/builder_test.go @@ -9,15 +9,15 @@ import ( "testing" "time" - "github.com/AvaProtocol/ap-avs/core/chainio/aa" - "github.com/AvaProtocol/ap-avs/core/testutil" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/aa" + "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" - "github.com/AvaProtocol/ap-avs/core/chainio/aa/paymaster" - "github.com/AvaProtocol/ap-avs/pkg/erc4337/bundler" - "github.com/AvaProtocol/ap-avs/pkg/erc4337/userop" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/aa/paymaster" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc4337/bundler" + "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc4337/userop" "github.com/ethereum/go-ethereum/ethclient" //"github.com/ethereum/go-ethereum/common/hexutil" ) From 0dd13c54a14b64639c6d0796c7c9b67853156564 Mon Sep 17 00:00:00 2001 From: Vinh Date: Thu, 10 Apr 2025 02:49:47 -0700 Subject: [PATCH 3/9] autoformat code on push --- .github/workflows/push.yml | 44 ++++++++++++- aggregator/aggregator.go | 9 ++- aggregator/repl.go | 12 ++-- core/backup/backup.go | 2 +- core/backup/backup_test.go | 31 +++++---- core/migrator/migrator.go | 17 +++-- core/migrator/migrator_test.go | 32 +++++----- core/taskengine/vm.go | 12 ++-- .../vm_runner_contract_write_test.go | 3 - .../20250405-232000-change-epoch-to-ms.go | 16 ++--- ...20250405-232000-change-epoch-to-ms_test.go | 63 +++++++++---------- pkg/erc4337/preset/builder.go | 8 +-- 12 files changed, 141 insertions(+), 108 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index 29e10737..a2f93d31 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -10,6 +10,48 @@ on: workflow_dispatch: jobs: + format-and-commit: + runs-on: ubuntu-latest + # Grant permissions for the built-in GITHUB_TOKEN to create a commit and push. + permissions: + contents: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + # We need to fetch the history to allow pushing, and potentially check diffs. + # Setting persist-credentials to true isn't strictly necessary with actions/checkout@v4+ + # when using the default GITHUB_TOKEN, but it doesn't hurt. + fetch-depth: 0 # Fetch all history for comparison and commit user info + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.24' # <--- CHANGE THIS to your project's Go version + + - name: Run gofmt + run: gofmt -w . + + - name: Commit changes + run: | + # Configure Git using the GITHUB_ACTOR pattern or a generic bot name + git config --global user.name 'github-actions[bot]' + git config --global user.email 'github-actions[bot]@users.noreply.github.com' + + # Check if there are any changes staged/unstaged + # git diff --quiet exits with 1 if there are changes, 0 if not. + if ! git diff --quiet; then + echo "Detected changes, committing..." + git add . # Stage all changes, including new files if any (though gofmt shouldn't create new files) + # Alternative: git add -u # Only stage modified/deleted tracked files + git commit -m "style: Automated gofmt" -m "Formatted Go code using gofmt." + echo "Pushing changes..." + git push + else + echo "No formatting changes detected." + fi + shell: bash # Explicitly use bash + publish-dev-build: name: Publish dev build docker image to dockerhub runs-on: 'ubuntu-latest' @@ -55,4 +97,4 @@ jobs: file: dockerfiles/operator.Dockerfile push: ${{ github.event_name != 'pull_request' }} tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} + labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/aggregator/aggregator.go b/aggregator/aggregator.go index 5fe8fa5a..bb71cfc7 100644 --- a/aggregator/aggregator.go +++ b/aggregator/aggregator.go @@ -18,7 +18,6 @@ import ( sdktypes "github.com/Layr-Labs/eigensdk-go/types" "github.com/allegro/bigcache/v3" - cstaskmanager "github.com/AvaProtocol/EigenLayer-AVS/contracts/bindings/AutomationTaskManager" "github.com/AvaProtocol/EigenLayer-AVS/storage" @@ -31,7 +30,7 @@ import ( "github.com/AvaProtocol/EigenLayer-AVS/core/config" "github.com/AvaProtocol/EigenLayer-AVS/core/taskengine" "github.com/AvaProtocol/EigenLayer-AVS/version" - + "github.com/AvaProtocol/EigenLayer-AVS/core/backup" "github.com/AvaProtocol/EigenLayer-AVS/core/migrator" "github.com/AvaProtocol/EigenLayer-AVS/migrations" @@ -100,7 +99,7 @@ type Aggregator struct { cache *bigcache.BigCache - backup *backup.Service + backup *backup.Service migrator *migrator.Migrator } @@ -256,7 +255,7 @@ func (agg *Aggregator) Start(ctx context.Context) error { agg.logger.Fatalf("failed to initialize storage", "error", err) } - agg.migrate() + agg.migrate() agg.logger.Infof("Starting Task engine") agg.startTaskEngine(ctx) @@ -287,7 +286,7 @@ func (agg *Aggregator) Start(ctx context.Context) error { agg.status = shutdownStatus agg.stopRepl() agg.stopTaskEngine() - + agg.db.Close() return nil diff --git a/aggregator/repl.go b/aggregator/repl.go index b924bae8..76d46022 100644 --- a/aggregator/repl.go +++ b/aggregator/repl.go @@ -152,32 +152,32 @@ func handleConnection(agg *Aggregator, conn net.Conn) { case "trigger": fmt.Fprintln(conn, "about to trigger on server") //agg.engine.TriggerWith - + case "backup": if len(parts) == 2 { backupDir := parts[1] fmt.Fprintf(conn, "Starting backup to directory: %s\n", backupDir) - + timestamp := fmt.Sprintf("%s", time.Now().Format("06-01-02-15-04")) backupPath := filepath.Join(backupDir, timestamp) - + if err := os.MkdirAll(backupPath, 0755); err != nil { fmt.Fprintf(conn, "Failed to create backup directory: %v\n", err) break } - + backupFile := filepath.Join(backupPath, "badger.backup") f, err := os.Create(backupFile) if err != nil { fmt.Fprintf(conn, "Failed to create backup file: %v\n", err) break } - + fmt.Fprintf(conn, "Running backup to %s\n", backupFile) since := uint64(0) // Full backup _, err = agg.db.Backup(context.Background(), f, since) f.Close() - + if err != nil { fmt.Fprintf(conn, "Backup failed: %v\n", err) } else { diff --git a/core/backup/backup.go b/core/backup/backup.go index cdb6842d..209d8600 100644 --- a/core/backup/backup.go +++ b/core/backup/backup.go @@ -79,7 +79,7 @@ func (s *Service) backupLoop() { func (s *Service) PerformBackup() (string, error) { timestamp := time.Now().Format("06-01-02-15-04") backupPath := filepath.Join(s.backupDir, timestamp) - + if err := os.MkdirAll(backupPath, 0755); err != nil { return "", fmt.Errorf("failed to create backup timestamp directory: %v", err) } diff --git a/core/backup/backup_test.go b/core/backup/backup_test.go index f561d833..e2a2cf81 100644 --- a/core/backup/backup_test.go +++ b/core/backup/backup_test.go @@ -1,9 +1,9 @@ package backup import ( + "os" "testing" "time" - "os" "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" ) @@ -15,63 +15,63 @@ func TestBackup(t *testing.T) { logger := testutil.GetLogger() db := testutil.TestMustDB() tempDir := t.TempDir() - + service := NewService(logger, db, tempDir) - + // Test starting backup service err := service.StartPeriodicBackup(1 * time.Hour) if err != nil { t.Fatalf("Failed to start periodic backup: %v", err) } - + if !service.backupEnabled { t.Error("Backup service should be enabled after starting") } - + // Test starting again should fail err = service.StartPeriodicBackup(1 * time.Hour) if err == nil { t.Error("Starting backup service twice should return an error") } - + // Cleanup service.StopPeriodicBackup() }) - + t.Run("StopPeriodicBackup", func(t *testing.T) { // Setup logger := testutil.GetLogger() db := testutil.TestMustDB() tempDir := t.TempDir() - + service := NewService(logger, db, tempDir) - + // Start and then stop _ = service.StartPeriodicBackup(1 * time.Hour) service.StopPeriodicBackup() - + if service.backupEnabled { t.Error("Backup service should be disabled after stopping") } - + // Test stopping when not running (should be a no-op) service.StopPeriodicBackup() }) - + t.Run("PerformBackup", func(t *testing.T) { // Setup logger := testutil.GetLogger() db := testutil.TestMustDB() tempDir := t.TempDir() - + service := NewService(logger, db, tempDir) - + // Test performing a backup backupFile, err := service.PerformBackup() if err != nil { t.Fatalf("Failed to perform backup: %v", err) } - + // Verify backup file exists if _, err := os.Stat(backupFile); os.IsNotExist(err) { t.Errorf("Backup file %s does not exist", backupFile) @@ -80,4 +80,3 @@ func TestBackup(t *testing.T) { } // Mock implementations for testing - diff --git a/core/migrator/migrator.go b/core/migrator/migrator.go index c4fbc22b..6423995f 100644 --- a/core/migrator/migrator.go +++ b/core/migrator/migrator.go @@ -3,8 +3,8 @@ package migrator import ( "time" - "github.com/AvaProtocol/EigenLayer-AVS/storage" "github.com/AvaProtocol/EigenLayer-AVS/core/backup" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) import ( @@ -40,13 +40,11 @@ func NewMigrator(db storage.Storage, backup *backup.Service, migrations []Migrat } } - - // Register adds a new migration to the list func (m *Migrator) Register(name string, fn MigrationFunc) { m.mu.Lock() defer m.mu.Unlock() - + m.migrations = append(m.migrations, Migration{ Name: name, Function: fn, @@ -57,7 +55,7 @@ func (m *Migrator) Register(name string, fn MigrationFunc) { func (m *Migrator) Run() error { m.mu.Lock() defer m.mu.Unlock() - + // Check if we have any migrations to run hasPendingMigrations := false for _, migration := range m.migrations { @@ -68,7 +66,7 @@ func (m *Migrator) Run() error { break } } - + // If we have migrations to run, take a backup first if hasPendingMigrations { log.Printf("Pending migrations found, creating database backup before proceeding") @@ -78,7 +76,6 @@ func (m *Migrator) Run() error { log.Printf("Database backup created at %s", backupFile) } } - for _, migration := range m.migrations { // Check if migration has already been run @@ -88,7 +85,7 @@ func (m *Migrator) Run() error { log.Printf("Migration %s already applied, skipping", migration.Name) continue } - + // Run the migration log.Printf("Running migration: %s", migration.Name) recordsUpdated, err := migration.Function(m.db) @@ -97,12 +94,12 @@ func (m *Migrator) Run() error { } else { log.Printf("Migration %s completed successfully. %d records updated.", migration.Name, recordsUpdated) } - + // Mark migration as complete in the database if err := m.db.Set([]byte(key), []byte(fmt.Sprintf("records=%d,ts=%d", recordsUpdated, time.Now().UnixMilli()))); err != nil { return fmt.Errorf("failed to mark migration as complete in database: %w", err) } } - + return nil } diff --git a/core/migrator/migrator_test.go b/core/migrator/migrator_test.go index 45563b0d..2a5a4d01 100644 --- a/core/migrator/migrator_test.go +++ b/core/migrator/migrator_test.go @@ -14,27 +14,27 @@ func TestMigrator(t *testing.T) { logger := testutil.GetLogger() db := testutil.TestMustDB() defer db.Close() - + // Create backup service backupDir := t.TempDir() backup := backup.NewService(logger, db, backupDir) - + // Test migration function that updates records testMigration := func(db storage.Storage) (int, error) { return 5, db.Set([]byte("test:key"), []byte("migrated")) } - + // Create migrator with test migration migrations := []Migration{} // Initialize with empty slice migrator := NewMigrator(db, backup, migrations) migrator.Register("test_migration", testMigration) - + // Run migrations err := migrator.Run() if err != nil { t.Fatalf("Failed to run migrations: %v", err) } - + // Verify migration was marked as complete migrationKey := []byte("migration:test_migration") exists, err := db.Exist(migrationKey) @@ -44,13 +44,13 @@ func TestMigrator(t *testing.T) { if !exists { t.Fatalf("Migration was not marked as complete") } - + // Verify migration record format (should contain records count and timestamp) migrationData, err := db.GetKey(migrationKey) if err != nil { t.Fatalf("Failed to get migration data: %v", err) } - + migrationRecord := string(migrationData) if !strings.Contains(migrationRecord, "records=5") { t.Errorf("Migration record doesn't contain correct record count: %s", migrationRecord) @@ -58,7 +58,7 @@ func TestMigrator(t *testing.T) { if !strings.Contains(migrationRecord, "ts=") { t.Errorf("Migration record doesn't contain timestamp: %s", migrationRecord) } - + // Test that migrations aren't run twice // Create a counter to track if migration is called migrationCounter := 0 @@ -66,35 +66,35 @@ func TestMigrator(t *testing.T) { migrationCounter++ return 0, nil } - + // Register a new migration that we've already run migrator.Register("test_migration", countingMigration) - + // Run migrations again err = migrator.Run() if err != nil { t.Fatalf("Failed to run migrations second time: %v", err) } - + // Verify the migration wasn't executed again if migrationCounter > 0 { t.Errorf("Migration was executed again when it should have been skipped") } - + // Test new migration gets executed migrator.Register("second_migration", countingMigration) - + // Run migrations again err = migrator.Run() if err != nil { t.Fatalf("Failed to run migrations third time: %v", err) } - + // Verify the new migration was executed if migrationCounter != 1 { t.Errorf("New migration was not executed") } - + // Verify second migration was marked as complete secondMigrationKey := []byte("migration:second_migration") exists, err = db.Exist(secondMigrationKey) @@ -104,4 +104,4 @@ func TestMigrator(t *testing.T) { if !exists { t.Fatalf("Second migration was not marked as complete") } -} \ No newline at end of file +} diff --git a/core/taskengine/vm.go b/core/taskengine/vm.go index fcd4145a..1dd6a21b 100644 --- a/core/taskengine/vm.go +++ b/core/taskengine/vm.go @@ -293,12 +293,12 @@ func NewVMWithData(task *model.Task, reason *avsproto.TriggerReason, smartWallet } v.parsedTriggerData.TransferLog = &avsproto.Execution_TransferLogOutput{ - TokenName: tokenMetadata.Name, - TokenSymbol: tokenMetadata.Symbol, - TokenDecimals: uint32(tokenMetadata.Decimals), - TransactionHash: event.TxHash.Hex(), - Address: event.Address.Hex(), - BlockNumber: event.BlockNumber, + TokenName: tokenMetadata.Name, + TokenSymbol: tokenMetadata.Symbol, + TokenDecimals: uint32(tokenMetadata.Decimals), + TransactionHash: event.TxHash.Hex(), + Address: event.Address.Hex(), + BlockNumber: event.BlockNumber, // in Ethereum, timestamp is in seconds, but in our app we use milliseconds, so we need to convert it // https://docs.soliditylang.org/en/latest/units-and-global-variables.html#block-and-transaction-properties // This is requested in ticket https://github.com/AvaProtocol/EigenLayer-AVS/issues/191 and implemented in https://github.com/AvaProtocol/EigenLayer-AVS/pull/192/files diff --git a/core/taskengine/vm_runner_contract_write_test.go b/core/taskengine/vm_runner_contract_write_test.go index df9c32c5..1b87a343 100644 --- a/core/taskengine/vm_runner_contract_write_test.go +++ b/core/taskengine/vm_runner_contract_write_test.go @@ -103,9 +103,6 @@ func TestContractWriteSimpleReturn(t *testing.T) { return } - // Print logs for debugging - t.Logf("Logs: %+v", outputData.TxReceipt.Logs) - if len(outputData.TxReceipt.Hash) != 66 { t.Errorf("Missing Tx Hash in the output data") } diff --git a/migrations/20250405-232000-change-epoch-to-ms.go b/migrations/20250405-232000-change-epoch-to-ms.go index 2062bc70..cf21cdb9 100644 --- a/migrations/20250405-232000-change-epoch-to-ms.go +++ b/migrations/20250405-232000-change-epoch-to-ms.go @@ -4,9 +4,9 @@ import ( //"strconv" "google.golang.org/protobuf/encoding/protojson" - "github.com/AvaProtocol/EigenLayer-AVS/storage" "github.com/AvaProtocol/EigenLayer-AVS/model" - avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" + "github.com/AvaProtocol/EigenLayer-AVS/storage" ) func ChangeEpochToMs(db storage.Storage) (int, error) { @@ -43,7 +43,7 @@ func ChangeEpochToMs(db storage.Storage) (int, error) { if err := task.FromStorageData(taskRawByte); err != nil { continue } - + if task.Task.StartAt > 0 && task.Task.StartAt < timestampThreshold { // Convert the timestamp to milliseconds task.Task.StartAt = task.Task.StartAt * 1000 @@ -74,7 +74,7 @@ func ChangeEpochToMs(db storage.Storage) (int, error) { if err != nil { return 0, err } - + for _, key := range historyExecutionKeys { executionRawByte, err := db.GetKey([]byte(key)) if err != nil { @@ -87,17 +87,17 @@ func ChangeEpochToMs(db storage.Storage) (int, error) { return 0, err } - // Convert the timestamp to milliseconds for the execution + // Convert the timestamp to milliseconds for the execution if exec.StartAt > 0 && exec.StartAt < timestampThreshold { exec.StartAt = exec.StartAt * 1000 } - if exec.EndAt > 0 && exec.EndAt < timestampThreshold { + if exec.EndAt > 0 && exec.EndAt < timestampThreshold { // Convert the timestamp to milliseconds exec.EndAt = exec.EndAt * 1000 } // Convert start/end of each step to milliseconds - for i, step := range exec.Steps { + for i, step := range exec.Steps { if step.StartAt > 0 && step.StartAt < timestampThreshold { // Convert the timestamp to milliseconds exec.Steps[i].StartAt = step.StartAt * 1000 @@ -129,6 +129,6 @@ func ChangeEpochToMs(db storage.Storage) (int, error) { if err := db.BatchWrite(updates); err != nil { return 0, err } - + return totalUpdated, nil } diff --git a/migrations/20250405-232000-change-epoch-to-ms_test.go b/migrations/20250405-232000-change-epoch-to-ms_test.go index eb0f139c..b54a00dd 100644 --- a/migrations/20250405-232000-change-epoch-to-ms_test.go +++ b/migrations/20250405-232000-change-epoch-to-ms_test.go @@ -6,7 +6,7 @@ import ( "time" "github.com/AvaProtocol/EigenLayer-AVS/core/testutil" - + avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" "google.golang.org/protobuf/encoding/protojson" // Correct import for protojson ) @@ -49,11 +49,11 @@ func TestChangeEpochToMs(t *testing.T) { // Create Sample Task Data (using avsproto.Task directly as migration handles it) sampleTask := &avsproto.Task{ - Id: taskID, - StartAt: startSeconds, // Seconds - ExpiredAt: expiredSeconds, // Seconds + Id: taskID, + StartAt: startSeconds, // Seconds + ExpiredAt: expiredSeconds, // Seconds CompletedAt: completedSeconds, // Seconds - LastRanAt: lastRanSeconds, // Seconds + LastRanAt: lastRanSeconds, // Seconds // Other fields can be default/empty for this test } @@ -79,20 +79,19 @@ func TestChangeEpochToMs(t *testing.T) { }, // Other fields can be default/empty } - // Add another execution to test TimeOutput - execID2 := "exec-def" - sampleExec2 := &avsproto.Execution{ - Id: execID2, - StartAt: execStartSeconds, // Seconds - EndAt: execEndSeconds, // Seconds - OutputData: &avsproto.Execution_Time{ - Time: &avsproto.Execution_TimeOutput{ - Epoch: uint64(epochSeconds), // Seconds - }, - }, - // Other fields can be default/empty - } - + // Add another execution to test TimeOutput + execID2 := "exec-def" + sampleExec2 := &avsproto.Execution{ + Id: execID2, + StartAt: execStartSeconds, // Seconds + EndAt: execEndSeconds, // Seconds + OutputData: &avsproto.Execution_Time{ + Time: &avsproto.Execution_TimeOutput{ + Epoch: uint64(epochSeconds), // Seconds + }, + }, + // Other fields can be default/empty + } // Serialize data using protojson (matching migration) taskBytes, err := protojson.Marshal(sampleTask) @@ -103,21 +102,21 @@ func TestChangeEpochToMs(t *testing.T) { if err != nil { t.Fatalf("Failed to marshal sample execution: %v", err) } - execBytes2, err := protojson.Marshal(sampleExec2) - if err != nil { - t.Fatalf("Failed to marshal sample execution 2: %v", err) - } + execBytes2, err := protojson.Marshal(sampleExec2) + if err != nil { + t.Fatalf("Failed to marshal sample execution 2: %v", err) + } // Store data in DB using correct keys taskKey := fmt.Sprintf("t:%s", taskID) execKey := fmt.Sprintf("history:%s:%s", taskID, execID) - execKey2 := fmt.Sprintf("history:%s:%s", taskID, execID2) + execKey2 := fmt.Sprintf("history:%s:%s", taskID, execID2) // Use BatchWrite as seen in the migration code for setting multiple keys updates := map[string][]byte{ taskKey: taskBytes, execKey: execBytes, - execKey2: execBytes2, + execKey2: execBytes2, } if err := db.BatchWrite(updates); err != nil { t.Fatalf("Failed to write initial data to db: %v", err) @@ -197,7 +196,7 @@ func TestChangeEpochToMs(t *testing.T) { t.Errorf("Expected TransferLog output data, but got nil or different type") } - // Verify Execution Data 2 (TimeOutput) using GetKey + // Verify Execution Data 2 (TimeOutput) using GetKey retrievedExecBytes2, err := db.GetKey([]byte(execKey2)) if err != nil { t.Fatalf("Failed to retrieve execution data 2 after migration: %v", err) @@ -207,12 +206,12 @@ func TestChangeEpochToMs(t *testing.T) { t.Fatalf("Failed to unmarshal retrieved execution data 2: %v", err) } - // Verify Execution Output Data (TimeOutput) - if timeOutput := retrievedExec2.GetTime(); timeOutput != nil { - if timeOutput.Epoch != uint64(expectedEpochMs) { + // Verify Execution Output Data (TimeOutput) + if timeOutput := retrievedExec2.GetTime(); timeOutput != nil { + if timeOutput.Epoch != uint64(expectedEpochMs) { t.Errorf("TimeOutput Epoch incorrect: got %d, want %d", timeOutput.Epoch, expectedEpochMs) } - } else { - t.Errorf("Expected Time output data, but got nil or different type") - } + } else { + t.Errorf("Expected Time output data, but got nil or different type") + } } diff --git a/pkg/erc4337/preset/builder.go b/pkg/erc4337/preset/builder.go index 38b84c56..75a3bdb8 100644 --- a/pkg/erc4337/preset/builder.go +++ b/pkg/erc4337/preset/builder.go @@ -14,10 +14,10 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient" - "github.com/AvaProtocol/ap-avs/core/chainio/aa" - "github.com/AvaProtocol/ap-avs/core/chainio/aa/paymaster" - "github.com/AvaProtocol/ap-avs/core/chainio/signer" - "github.com/AvaProtocol/ap-avs/core/config" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/aa" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/aa/paymaster" + "github.com/AvaProtocol/EigenLayer-AVS/core/chainio/signer" + "github.com/AvaProtocol/EigenLayer-AVS/core/config" "github.com/AvaProtocol/EigenLayer-AVS/pkg/eip1559" "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc4337/bundler" From 9694549df2197b0e2ee9f037aaf84943ed7f3926 Mon Sep 17 00:00:00 2001 From: Vinh Date: Thu, 10 Apr 2025 03:21:39 -0700 Subject: [PATCH 4/9] Use go1.24 in Dockerfile --- dockerfiles/operator.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockerfiles/operator.Dockerfile b/dockerfiles/operator.Dockerfile index 879b7cf7..85b3fcde 100644 --- a/dockerfiles/operator.Dockerfile +++ b/dockerfiles/operator.Dockerfile @@ -1,4 +1,4 @@ -FROM golang:1.23 AS builder +FROM golang:1.24 AS builder ARG RELEASE_TAG ARG COMMIT_SHA From 2b13d932c9d33d668784e1e90330243207c8b050 Mon Sep 17 00:00:00 2001 From: Vinh Date: Thu, 10 Apr 2025 04:03:59 -0700 Subject: [PATCH 5/9] fix new grpc format --- core/taskengine/engine.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/taskengine/engine.go b/core/taskengine/engine.go index 2cfca52e..5f70debb 100644 --- a/core/taskengine/engine.go +++ b/core/taskengine/engine.go @@ -300,7 +300,7 @@ func (n *Engine) CreateTask(user *model.User, taskPayload *avsproto.CreateTaskRe task, err := model.NewTaskFromProtobuf(user, taskPayload) if err != nil { - return nil, status.Errorf(codes.InvalidArgument, err.Error()) + return nil, grpcstatus.Errorf(codes.InvalidArgument, "%s", err.Error()) } updates := map[string][]byte{} @@ -609,7 +609,7 @@ func (n *Engine) TriggerTask(user *model.User, payload *avsproto.UserTriggerTask data, err := json.Marshal(queueTaskData) if err != nil { n.logger.Error("error serialize trigger to json", err) - return nil, status.Errorf(codes.InvalidArgument, codes.InvalidArgument.String()) + return nil, grpcstatus.Errorf(codes.InvalidArgument, "%s", err.Error()) } jid, err := n.queue.Enqueue(JobTypeExecuteTask, payload.TaskId, data) From b2f100f045360842ddd1aaa37f42727721ae879a Mon Sep 17 00:00:00 2001 From: Vinh Date: Thu, 10 Apr 2025 04:05:18 -0700 Subject: [PATCH 6/9] add new packages to test --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e89cb93b..6e71df13 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,6 +21,8 @@ jobs: - pkg/byte4 - pkg/erc4337/preset - core/backup + - core/migrations + - migrations steps: - uses: actions/checkout@v4 From 01a65a7104e0814f6eaac818875c84f94e4666dc Mon Sep 17 00:00:00 2001 From: Vinh Date: Thu, 10 Apr 2025 04:05:31 -0700 Subject: [PATCH 7/9] add new pkg to test run --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6e71df13..0e69c777 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -21,7 +21,7 @@ jobs: - pkg/byte4 - pkg/erc4337/preset - core/backup - - core/migrations + - core/migrator - migrations steps: From 0c13d4a564e3411618ba35e033d5a2487ecf384c Mon Sep 17 00:00:00 2001 From: Vinh Date: Thu, 10 Apr 2025 09:23:03 -0700 Subject: [PATCH 8/9] fix AI slop --- ...m_runner_contract_write_transaction_limit_test.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/core/taskengine/vm_runner_contract_write_transaction_limit_test.go b/core/taskengine/vm_runner_contract_write_transaction_limit_test.go index 318396d8..0af1d142 100644 --- a/core/taskengine/vm_runner_contract_write_transaction_limit_test.go +++ b/core/taskengine/vm_runner_contract_write_transaction_limit_test.go @@ -13,7 +13,7 @@ import ( // "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc4337/preset" // "github.com/AvaProtocol/EigenLayer-AVS/pkg/erc4337/userop" - + "github.com/ethereum/go-ethereum/ethclient" "github.com/AvaProtocol/EigenLayer-AVS/model" avsproto "github.com/AvaProtocol/EigenLayer-AVS/protobuf" "github.com/AvaProtocol/EigenLayer-AVS/storage" @@ -43,6 +43,14 @@ func TestTransactionSponsorshipLimit(t *testing.T) { CallData: "0xa9059cbb000000000000000000000000e0f7d11fd714674722d325cd86062a5f1882e13a000000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000000000000", } + client, err := ethclient.Dial(smartWalletConfig.EthRpcUrl) + + if err != nil { + t.Fatalf("error connectiong to websocket: %v", err) + } + defer client.Close() + + for i, tc := range testCases { t.Run(tc.name, func(t *testing.T) { db := testutil.TestMustDB() @@ -82,6 +90,7 @@ func TestTransactionSponsorshipLimit(t *testing.T) { CommonProcessor: &CommonProcessor{ vm: vm, }, + client: client, owner: owner, smartWalletConfig: smartWalletConfig, } @@ -90,6 +99,7 @@ func TestTransactionSponsorshipLimit(t *testing.T) { if err != nil { t.Fatalf("Failed to execute step: %v", err) } + fmt.Println("step", step) capturedPaymaster := step.OutputData.(*avsproto.Execution_Step_ContractWrite).ContractWrite.UserOp.PaymasterAndData if tc.expectPaymaster { From 0582c57329d00a702cff105ad927e1b3427609d3 Mon Sep 17 00:00:00 2001 From: Vinh Date: Thu, 10 Apr 2025 09:43:42 -0700 Subject: [PATCH 9/9] fix timestamp change --- core/taskengine/executor_test.go | 4 ++-- .../vm_runner_contract_write_transaction_limit_test.go | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/core/taskengine/executor_test.go b/core/taskengine/executor_test.go index b7a1b8d2..1b4b5ed6 100644 --- a/core/taskengine/executor_test.go +++ b/core/taskengine/executor_test.go @@ -495,8 +495,8 @@ func TestExecutorRunTaskReturnAllExecutionData(t *testing.T) { t.Errorf("expect BlockNumber is 7212417 but got: %d", outputData.BlockNumber) } - if outputData.BlockTimestamp != 1733351604 { - t.Errorf("expect BlockTimestamp is 1733351604 but got: %d", outputData.BlockTimestamp) + if outputData.BlockTimestamp != 1733351604000 { + t.Errorf("expect BlockTimestamp is 1733351604000 but got: %d", outputData.BlockTimestamp) } if outputData.FromAddress != "0x2A6CEbeDF9e737A9C6188c62A68655919c7314DB" { diff --git a/core/taskengine/vm_runner_contract_write_transaction_limit_test.go b/core/taskengine/vm_runner_contract_write_transaction_limit_test.go index 0af1d142..74cef877 100644 --- a/core/taskengine/vm_runner_contract_write_transaction_limit_test.go +++ b/core/taskengine/vm_runner_contract_write_transaction_limit_test.go @@ -50,7 +50,6 @@ func TestTransactionSponsorshipLimit(t *testing.T) { } defer client.Close() - for i, tc := range testCases { t.Run(tc.name, func(t *testing.T) { db := testutil.TestMustDB()