From e0e3848fa954563438710687aa7f6c7d4b412510 Mon Sep 17 00:00:00 2001 From: Victor Fusco <1221933+vfusco@users.noreply.github.com> Date: Wed, 9 Oct 2024 10:34:30 -0300 Subject: [PATCH] refactor: remove testcontainers dependency --- cmd/cartesi-rollups-cli/root/app/add/add.go | 2 +- cmd/cartesi-rollups-cli/root/db/db.go | 2 +- cmd/cartesi-rollups-cli/root/deps/deps.go | 103 ------ .../root/execute/execute.go | 13 +- cmd/cartesi-rollups-cli/root/root.go | 4 - .../root/savesnapshot/savesnapshot.go | 42 --- cmd/cartesi-rollups-cli/root/send/send.go | 13 +- .../root/validate/validate.go | 13 +- cmd/cartesi-rollups-node/main.go | 10 +- go.mod | 38 +-- go.sum | 97 +----- internal/deps/deps.go | 311 ------------------ internal/{node => machine}/machinehash.go | 28 +- internal/machine/machinehash_test.go | 158 +++++++++ internal/machine/snapshot.go | 35 +- internal/node/config/config.go | 84 ++--- internal/node/config/generate/code.go | 2 +- internal/node/config/generated.go | 68 ++-- internal/node/machinehash_test.go | 149 --------- internal/nodemachine/machine.go | 2 +- internal/repository/base_test.go | 40 +-- internal/repository/machine_test.go | 12 +- pkg/addresses/addresses.go | 38 +-- pkg/ethutil/anvil.go | 80 +++++ pkg/ethutil/ethutil.go | 100 ++++-- pkg/ethutil/ethutil_test.go | 43 ++- pkg/ethutil/mnemonic.go | 4 +- pkg/ethutil/mnemonic_test.go | 2 +- pkg/testutil/testutil.go | 12 - test/config.go | 6 +- test/echo_test.go | 190 ----------- test/tooling/db/db.go | 47 +-- test/validator/validator_test.go | 55 +--- 33 files changed, 515 insertions(+), 1288 deletions(-) delete mode 100644 cmd/cartesi-rollups-cli/root/deps/deps.go delete mode 100644 cmd/cartesi-rollups-cli/root/savesnapshot/savesnapshot.go delete mode 100644 internal/deps/deps.go rename internal/{node => machine}/machinehash.go (72%) create mode 100644 internal/machine/machinehash_test.go delete mode 100644 internal/node/machinehash_test.go create mode 100644 pkg/ethutil/anvil.go delete mode 100644 pkg/testutil/testutil.go delete mode 100644 test/echo_test.go diff --git a/cmd/cartesi-rollups-cli/root/app/add/add.go b/cmd/cartesi-rollups-cli/root/app/add/add.go index 1d622e3de..2714cabfa 100644 --- a/cmd/cartesi-rollups-cli/root/app/add/add.go +++ b/cmd/cartesi-rollups-cli/root/app/add/add.go @@ -16,7 +16,7 @@ import ( var Cmd = &cobra.Command{ Use: "add", - Short: "Adds a new application", + Short: "Add an existing application to the node", Example: examples, Run: run, } diff --git a/cmd/cartesi-rollups-cli/root/db/db.go b/cmd/cartesi-rollups-cli/root/db/db.go index 70141a1dd..338877dbb 100644 --- a/cmd/cartesi-rollups-cli/root/db/db.go +++ b/cmd/cartesi-rollups-cli/root/db/db.go @@ -20,7 +20,7 @@ func init() { &common.PostgresEndpoint, "postgres-endpoint", "p", - "postgres://postgres:password@localhost:5432/postgres", + "postgres://postgres:password@localhost:5432/rollupsdb?sslmode=disable", "Postgres endpoint", ) diff --git a/cmd/cartesi-rollups-cli/root/deps/deps.go b/cmd/cartesi-rollups-cli/root/deps/deps.go deleted file mode 100644 index 9c49693f1..000000000 --- a/cmd/cartesi-rollups-cli/root/deps/deps.go +++ /dev/null @@ -1,103 +0,0 @@ -// (c) Cartesi and individual authors (see AUTHORS) -// SPDX-License-Identifier: Apache-2.0 (see LICENSE) - -package deps - -import ( - "context" - "log/slog" - "os" - "os/signal" - "syscall" - - "github.com/cartesi/rollups-node/internal/deps" - "github.com/lmittmann/tint" - "github.com/mattn/go-isatty" - "github.com/spf13/cobra" -) - -var Cmd = &cobra.Command{ - Use: "run-deps", - Short: "Run node dependencies with Docker", - Example: examples, - Run: run, -} - -const examples = `# Run all deps: -cartesi-rollups-cli run-deps` - -var depsConfig = deps.NewDefaultDepsConfig() -var disablePostgres = false -var disableDevnet = false -var verbose = false - -func init() { - Cmd.Flags().StringVar(&depsConfig.Postgres.DockerImage, "postgres-docker-image", - deps.DefaultPostgresDockerImage, - "Postgres docker image name") - - Cmd.Flags().StringVar(&depsConfig.Postgres.Port, "postgres-mapped-port", - deps.DefaultPostgresPort, - "Postgres local listening port number") - - Cmd.Flags().StringVar(&depsConfig.Postgres.Password, "postgres-password", - deps.DefaultPostgresPassword, - "Postgres password") - - Cmd.Flags().StringVar(&depsConfig.Devnet.DockerImage, "devnet-docker-image", - deps.DefaultDevnetDockerImage, - "Devnet docker image name") - - Cmd.Flags().StringVar(&depsConfig.Devnet.Port, "devnet-mapped-port", - deps.DefaultDevnetPort, - "Devnet local listening port number") - - Cmd.Flags().StringVar(&depsConfig.Devnet.BlockTime, "devnet-block-time", - deps.DefaultDevnetBlockTime, - "Devnet mining block time") - - Cmd.Flags().BoolVar(&depsConfig.Devnet.NoMining, "devnet-no-mining", - deps.DefaultDevnetNoMining, - "Devnet disable mining") - - Cmd.Flags().BoolVar(&disablePostgres, "disable-postgres", false, "Disable Postgres") - - Cmd.Flags().BoolVar(&disableDevnet, "disable-devnet", false, "Disable Devnet") - - Cmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "verbose logs") -} - -func run(cmd *cobra.Command, args []string) { - ctx, cancel := signal.NotifyContext(cmd.Context(), syscall.SIGINT, syscall.SIGTERM) - defer cancel() - - if verbose { - // setup log - opts := &tint.Options{ - Level: slog.LevelDebug, - AddSource: true, - NoColor: false || !isatty.IsTerminal(os.Stdout.Fd()), - } - handler := tint.NewHandler(os.Stdout, opts) - logger := slog.New(handler) - slog.SetDefault(logger) - } - - if disablePostgres { - depsConfig.Postgres = nil - } - - if disableDevnet { - depsConfig.Devnet = nil - } - - depsContainers, err := deps.Run(ctx, *depsConfig) - cobra.CheckErr(err) - - slog.Info("All dependencies are up") - - <-ctx.Done() - - err = deps.Terminate(context.Background(), depsContainers) - cobra.CheckErr(err) -} diff --git a/cmd/cartesi-rollups-cli/root/execute/execute.go b/cmd/cartesi-rollups-cli/root/execute/execute.go index 8e4d816c0..cf505d25f 100644 --- a/cmd/cartesi-rollups-cli/root/execute/execute.go +++ b/cmd/cartesi-rollups-cli/root/execute/execute.go @@ -11,6 +11,7 @@ import ( "github.com/cartesi/rollups-node/pkg/addresses" "github.com/cartesi/rollups-node/pkg/ethutil" "github.com/cartesi/rollups-node/pkg/readerclient" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" "github.com/spf13/cobra" ) @@ -58,8 +59,8 @@ func init() { Cmd.Flags().Uint32Var(&account, "account", 0, "account index used to sign the transaction (default: 0)") - Cmd.Flags().StringVar(&addressBookFile, "address-book", "", - "if set, load the address book from the given file; else, use test addresses") + Cmd.Flags().StringVar(&addressBookFile, "address-book", "deployment.json", + "if set, load the address book from the given file; else from deployment.json") } func run(cmd *cobra.Command, args []string) { @@ -85,21 +86,21 @@ func run(cmd *cobra.Command, args []string) { if addressBookFile != "" { book, err = addresses.GetBookFromFile(addressBookFile) cobra.CheckErr(err) - } else { - book = addresses.GetTestBook() } proof := readerclient.ConvertToContractProof(resp.Proof) + appAddr := common.HexToAddress("0x0000000000000000000000000000000000000000") // FIXME + slog.Info("Executing voucher", "voucher-index", voucherIndex, "input-index", inputIndex, - "application-address", book.Application, - ) + "application-address", appAddr) txHash, err := ethutil.ExecuteOutput( ctx, client, book, + appAddr, signer, resp.Payload, proof, diff --git a/cmd/cartesi-rollups-cli/root/root.go b/cmd/cartesi-rollups-cli/root/root.go index 7ab7fa03d..df3bd31af 100644 --- a/cmd/cartesi-rollups-cli/root/root.go +++ b/cmd/cartesi-rollups-cli/root/root.go @@ -10,13 +10,11 @@ import ( "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/app" "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/db" - "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/deps" "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/execute" "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/increasetime" "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/inspect" "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/mine" "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/read" - "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/savesnapshot" "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/send" "github.com/cartesi/rollups-node/cmd/cartesi-rollups-cli/root/validate" "github.com/lmittmann/tint" @@ -40,11 +38,9 @@ func init() { Cmd.AddCommand(send.Cmd) Cmd.AddCommand(read.Cmd) - Cmd.AddCommand(savesnapshot.Cmd) Cmd.AddCommand(inspect.Cmd) Cmd.AddCommand(increasetime.Cmd) Cmd.AddCommand(validate.Cmd) - Cmd.AddCommand(deps.Cmd) Cmd.AddCommand(execute.Cmd) Cmd.AddCommand(mine.Cmd) Cmd.AddCommand(app.Cmd) diff --git a/cmd/cartesi-rollups-cli/root/savesnapshot/savesnapshot.go b/cmd/cartesi-rollups-cli/root/savesnapshot/savesnapshot.go deleted file mode 100644 index e9f400ea0..000000000 --- a/cmd/cartesi-rollups-cli/root/savesnapshot/savesnapshot.go +++ /dev/null @@ -1,42 +0,0 @@ -// (c) Cartesi and individual authors (see AUTHORS) -// SPDX-License-Identifier: Apache-2.0 (see LICENSE) - -package savesnapshot - -import ( - "github.com/cartesi/rollups-node/internal/machine" - "github.com/spf13/cobra" -) - -var Cmd = &cobra.Command{ - Use: "save-snapshot", - Short: "Saves the testing Cartesi machine snapshot to the designated folder", - Example: examples, - Run: run, -} - -const examples = `# Save the default Rollups Echo Application snapshot: -cartesi-rollups-cli save-snapshot` - -var ( - sourceDockerImage string - tempContainerName string - destDir string -) - -func init() { - Cmd.Flags().StringVar(&sourceDockerImage, "docker-image", - "cartesi/rollups-node-snapshot:devel", - "Docker image containing the Cartesi Machine snapshot to be used") - - Cmd.Flags().StringVar(&tempContainerName, "temp-container-name", "temp-machine", - "Name of the temporary container needed to extract the machine snapshot files") - - Cmd.Flags().StringVar(&destDir, "dest-dir", "./machine-snapshot", - "directory where to store the Cartesi Machine snapshot to be used by the local Node") -} - -func run(cmd *cobra.Command, args []string) { - err := machine.Save(sourceDockerImage, destDir, tempContainerName) - cobra.CheckErr(err) -} diff --git a/cmd/cartesi-rollups-cli/root/send/send.go b/cmd/cartesi-rollups-cli/root/send/send.go index da62b3c87..015102919 100644 --- a/cmd/cartesi-rollups-cli/root/send/send.go +++ b/cmd/cartesi-rollups-cli/root/send/send.go @@ -8,6 +8,7 @@ import ( "github.com/cartesi/rollups-node/pkg/addresses" "github.com/cartesi/rollups-node/pkg/ethutil" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/ethclient" "github.com/spf13/cobra" @@ -46,8 +47,8 @@ func init() { cobra.CheckErr(Cmd.MarkFlagRequired("payload")) - Cmd.Flags().StringVar(&addressBookFile, "address-book", "", - "if set, load the address book from the given file; else, use test addresses") + Cmd.Flags().StringVar(&addressBookFile, "address-book", "deployment.json", + "if set, load the address book from the given file; else from deployment.json") } func run(cmd *cobra.Command, args []string) { @@ -66,12 +67,12 @@ func run(cmd *cobra.Command, args []string) { if addressBookFile != "" { book, err = addresses.GetBookFromFile(addressBookFile) cobra.CheckErr(err) - } else { - book = addresses.GetTestBook() } - slog.Info("Sending input", "application-address", book.Application) - inputIndex, err := ethutil.AddInput(ctx, client, book, signer, payload) + appAddr := common.HexToAddress("0x0000000000000000000000000000000000000000") // FIXME + + slog.Info("Sending input", "application-address", appAddr) + inputIndex, err := ethutil.AddInput(ctx, client, book, appAddr, signer, payload) cobra.CheckErr(err) slog.Info("Input added", "input-index", inputIndex) diff --git a/cmd/cartesi-rollups-cli/root/validate/validate.go b/cmd/cartesi-rollups-cli/root/validate/validate.go index 03684d9ef..863f7a2e9 100644 --- a/cmd/cartesi-rollups-cli/root/validate/validate.go +++ b/cmd/cartesi-rollups-cli/root/validate/validate.go @@ -11,6 +11,7 @@ import ( "github.com/cartesi/rollups-node/pkg/addresses" "github.com/cartesi/rollups-node/pkg/ethutil" "github.com/cartesi/rollups-node/pkg/readerclient" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/ethclient" "github.com/spf13/cobra" ) @@ -50,8 +51,8 @@ func init() { Cmd.Flags().StringVar(ðEndpoint, "eth-endpoint", "http://localhost:8545", "ethereum node JSON-RPC endpoint") - Cmd.Flags().StringVar(&addressBookFile, "address-book", "", - "if set, load the address book from the given file; else, use test addresses") + Cmd.Flags().StringVar(&addressBookFile, "address-book", "deployment.json", + "if set, load the address book from the given file; else from deployment.json") } func run(cmd *cobra.Command, args []string) { @@ -74,18 +75,18 @@ func run(cmd *cobra.Command, args []string) { if addressBookFile != "" { book, err = addresses.GetBookFromFile(addressBookFile) cobra.CheckErr(err) - } else { - book = addresses.GetTestBook() } proof := readerclient.ConvertToContractProof(resp.Proof) + appAddr := common.HexToAddress("0x0000000000000000000000000000000000000000") // FIXME + slog.Info("Validating notice", "notice-index", noticeIndex, "input-index", inputIndex, - "application-address", book.Application, + "application-address", appAddr, ) - err = ethutil.ValidateOutput(ctx, client, book, resp.Payload, proof) + err = ethutil.ValidateOutput(ctx, client, book, appAddr, resp.Payload, proof) cobra.CheckErr(err) slog.Info("Notice validated") diff --git a/cmd/cartesi-rollups-node/main.go b/cmd/cartesi-rollups-node/main.go index ace43b956..8553faa0f 100644 --- a/cmd/cartesi-rollups-node/main.go +++ b/cmd/cartesi-rollups-node/main.go @@ -35,18 +35,18 @@ func main() { startup.ConfigLogs(config.LogLevel, config.LogPrettyEnabled) slog.Info("Starting the Cartesi Rollups Node", "version", buildVersion, "config", config) - err := startup.ValidateSchema(config.PostgresEndpoint.Value) + database, err := repository.Connect(ctx, config.PostgresEndpoint.Value) if err != nil { - slog.Error("Node exited with an error", "error", err) + slog.Error("Node couldn't connect to the database", "error", err) os.Exit(1) } + defer database.Close() - database, err := repository.Connect(ctx, config.PostgresEndpoint.Value) + err = startup.ValidateSchema(config.PostgresEndpoint.Value) if err != nil { - slog.Error("Node couldn't connect to the database", "error", err) + slog.Error("Node exited with an error", "error", err) os.Exit(1) } - defer database.Close() _, err = startup.SetupNodePersistentConfig(ctx, database, config) if err != nil { diff --git a/go.mod b/go.mod index 31ad19890..a0b5ddf51 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,6 @@ require ( github.com/ethereum/go-ethereum v1.14.6 github.com/spf13/cobra v1.8.1 github.com/stretchr/testify v1.9.0 - github.com/testcontainers/testcontainers-go v0.32.0 github.com/tyler-smith/go-bip32 v1.0.0 github.com/tyler-smith/go-bip39 v1.1.0 ) @@ -16,55 +15,41 @@ require github.com/BurntSushi/toml v1.4.0 require ( github.com/Khan/genqlient v0.7.0 github.com/deepmap/oapi-codegen/v2 v2.1.0 - github.com/docker/docker v27.0.3+incompatible - github.com/docker/go-connections v0.5.0 github.com/golang-migrate/migrate/v4 v4.17.1 github.com/jackc/pgx/v5 v5.6.0 github.com/lmittmann/tint v1.0.4 github.com/mattn/go-isatty v0.0.20 github.com/oapi-codegen/runtime v1.1.1 - github.com/testcontainers/testcontainers-go/modules/postgres v0.32.0 golang.org/x/sync v0.7.0 golang.org/x/text v0.16.0 ) require ( - dario.cat/mergo v1.0.0 // indirect - github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect github.com/FactomProject/basen v0.0.0-20150613233007-fe3947df716e // indirect github.com/FactomProject/btcutilecc v0.0.0-20130527213604-d3a63a5752ec // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/Microsoft/hcsshim v0.12.4 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect github.com/alexflint/go-arg v1.4.3 // indirect github.com/alexflint/go-scalar v1.2.0 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.3 // indirect - github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/consensys/bavard v0.1.13 // indirect github.com/consensys/gnark-crypto v0.12.1 // indirect - github.com/containerd/containerd v1.7.19 // indirect - github.com/containerd/log v0.1.0 // indirect - github.com/containerd/platforms v0.2.1 // indirect - github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/go-units v0.5.0 // indirect + github.com/docker/docker v27.0.3+incompatible // indirect + github.com/docker/go-connections v0.5.0 // indirect github.com/ethereum/c-kzg-4844 v1.0.2 // indirect - github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/getkin/kin-openapi v0.123.0 // indirect - github.com/go-logr/logr v1.4.2 // indirect - github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect - github.com/gogo/protobuf v1.3.2 // indirect github.com/google/uuid v1.6.0 // indirect github.com/gorilla/websocket v1.5.3 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect @@ -78,28 +63,17 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/klauspost/compress v1.17.9 // indirect github.com/lib/pq v1.10.9 // indirect - github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae // indirect - github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/patternmatcher v0.6.0 // indirect - github.com/moby/sys/sequential v0.5.0 // indirect - github.com/moby/sys/user v0.1.0 // indirect - github.com/moby/term v0.5.0 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect - github.com/morikuni/aec v1.0.0 // indirect - github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect + github.com/prometheus/client_golang v1.14.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect - github.com/shirou/gopsutil/v3 v3.24.5 // indirect - github.com/shoenig/go-m1cpu v0.1.6 // indirect - github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/supranational/blst v0.3.12 // indirect @@ -108,8 +82,6 @@ require ( github.com/vektah/gqlparser/v2 v2.5.16 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect - go.opentelemetry.io/otel v1.28.0 // indirect - go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect go.uber.org/atomic v1.7.0 // indirect golang.org/x/crypto v0.24.0 // indirect @@ -117,8 +89,6 @@ require ( golang.org/x/mod v0.19.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/tools v0.22.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 // indirect - google.golang.org/grpc v1.65.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index 29f0d46bc..e5e5990d0 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,3 @@ -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= @@ -16,8 +12,6 @@ github.com/Khan/genqlient v0.7.0 h1:GZ1meyRnzcDTK48EjqB8t3bcfYvHArCUUvgOwpz1D4w= github.com/Khan/genqlient v0.7.0/go.mod h1:HNyy3wZvuYwmW3Y7mkoQLZsa/R5n5yIRajS1kPBvSFM= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= -github.com/Microsoft/hcsshim v0.12.4 h1:Ev7YUMHAHoWNm+aDSPzc5W9s6E2jyL1szpVDJeZ/Rr4= -github.com/Microsoft/hcsshim v0.12.4/go.mod h1:Iyl1WVpZzr+UkzjekHZbV8o5Z9ZkxNGx6CtY2Qg/JVQ= github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= @@ -45,8 +39,6 @@ github.com/btcsuite/btcd/btcec/v2 v2.3.3 h1:6+iXlDKE8RMtKsvK0gshlXIuPbyWM/h84Ens github.com/btcsuite/btcd/btcec/v2 v2.3.3/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= -github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= -github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= @@ -69,22 +61,12 @@ github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/Yj github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= -github.com/containerd/containerd v1.7.19 h1:/xQ4XRJ0tamDkdzrrBAUy/LE5nCcxFKdBm4EcPrSMEE= -github.com/containerd/containerd v1.7.19/go.mod h1:h4FtNYUUMB4Phr6v+xG89RYKj9XccvbNSCKjdufCrkc= -github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= -github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/containerd/platforms v0.2.1 h1:zvwtM3rz2YHPQsF2CHYM8+KtB5dvhISiXh5ZpSBQv6A= -github.com/containerd/platforms v0.2.1/go.mod h1:XHCb+2/hzowdiut9rkudds9bE5yJ7npe7dG/wG+uFPw= -github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= -github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man/v2 v2.0.4 h1:wfIWP927BUkWJb2NmU/kNDYIBTh/ziUX91+lVfRxZq4= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= -github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= -github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -126,7 +108,6 @@ github.com/getkin/kin-openapi v0.123.0 h1:zIik0mRwFNLyvtXK274Q6ut+dPh6nlxBp0x7mN github.com/getkin/kin-openapi v0.123.0/go.mod h1:wb1aSZA/iWmorQP9KTAS/phLj/t17B5jT7+fS8ed9NM= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= @@ -148,12 +129,11 @@ github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOW github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-migrate/migrate/v4 v4.17.1 h1:4zQ6iqL6t6AiItphxJctQb3cFqWiSpMnX7wLTPnnYO4= github.com/golang-migrate/migrate/v4 v4.17.1/go.mod h1:m8hinFyWBn0SA4QKHuKh175Pm9wjmxj3S2Mia7dbXzM= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= @@ -161,8 +141,6 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -195,8 +173,6 @@ github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+ github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= -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= github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= @@ -211,10 +187,6 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lmittmann/tint v1.0.4 h1:LeYihpJ9hyGvE0w+K2okPTGUdVLfng1+nDNVR4vWISc= github.com/lmittmann/tint v1.0.4/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= -github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae h1:dIZY4ULFcto4tAFlj1FYZl8ztUZ13bdq+PLY+NOfbyI= -github.com/lufia/plan9stats v0.0.0-20240513124658-fba389f38bae/go.mod h1:ilwx/Dta8jXAgpFYFvSWEMwxmbWXyiUHkd5FwyKhb5k= -github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= -github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -234,12 +206,6 @@ github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqky github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= -github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= -github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= -github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= -github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= -github.com/moby/sys/user v0.1.0 h1:WmZ93f5Ux6het5iituh9x2zAG7NFY9Aqi49jjE1PaQg= -github.com/moby/sys/user v0.1.0/go.mod h1:fKJhFOnsCN6xZ5gSfbM6zaHGgDJMrqt9/reuj4T7MmU= github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw= @@ -260,8 +226,6 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= -github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= @@ -282,14 +246,6 @@ github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/shirou/gopsutil/v3 v3.24.5 h1:i0t8kL+kQTvpAYToeuiVk3TgDeKOFioZO3Ztz/iZ9pI= -github.com/shirou/gopsutil/v3 v3.24.5/go.mod h1:bsoOS1aStSs9ErQ1WWfxllSeS1K5D+U30r2NfcubMVk= -github.com/shoenig/go-m1cpu v0.1.6 h1:nxdKQNcEB6vzgA2E2bvzKIYRuNj7XNJ4S/aRSwKzFtM= -github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ= -github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU= -github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k= -github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= -github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -310,10 +266,6 @@ github.com/supranational/blst v0.3.12 h1:Vfas2U2CFHhniv2QkUm2OVa1+pGTdqtpqm9NnhU github.com/supranational/blst v0.3.12/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= -github.com/testcontainers/testcontainers-go v0.32.0 h1:ug1aK08L3gCHdhknlTTwWjPHPS+/alvLJU/DRxTD/ME= -github.com/testcontainers/testcontainers-go v0.32.0/go.mod h1:CRHrzHLQhlXUsa5gXjTOfqIEJcrK5+xMDmBr/WMI88E= -github.com/testcontainers/testcontainers-go/modules/postgres v0.32.0 h1:ZE4dTdswj3P0j71nL+pL0m2e5HTXJwPoIFr+DDgdPaU= -github.com/testcontainers/testcontainers-go/modules/postgres v0.32.0/go.mod h1:njrNuyuoF2fjhVk6TG/R3Oeu82YwfYkbf5WVTyBXhV4= github.com/tklauser/go-sysconf v0.3.14 h1:g5vzr9iPFFz24v2KZXs/pvpvh8/V9Fw6vQK5ZZb78yU= github.com/tklauser/go-sysconf v0.3.14/go.mod h1:1ym4lWMLUOhuBOPGtRcJm7tEGX4SCYNEEEtghGG/8uY= github.com/tklauser/numcpus v0.8.0 h1:Mx4Wwe/FjZLeQsK/6kt2EOepwwSl7SmJrK5bV/dXYgY= @@ -324,38 +276,26 @@ github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2n github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= -github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/vektah/gqlparser/v2 v2.5.16 h1:1gcmLTvs3JLKXckwCwlUagVn/IlV2bwqle0vJ0vy5p8= github.com/vektah/gqlparser/v2 v2.5.16/go.mod h1:1lz1OeCqgQbQepsGxPVywrjdBHW2T08PUS3pJqepRww= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0 h1:Mne5On7VWdx7omSrSSZvM4Kw7cS7NQkOOmLcgscI51U= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.19.0/go.mod h1:IPtUMKL4O3tH5y+iXVyAXqpAwMuzC1IrxVS81rummfE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= -go.opentelemetry.io/otel/sdk v1.19.0 h1:6USY6zH+L8uMH8L3t1enZPR3WFEmSTADlqldyHtJi3o= -go.opentelemetry.io/otel/sdk v1.19.0/go.mod h1:NedEbbS4w3C6zElbLdPJKOpJQOrGUJ+GfzpjUvI0v1A= go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= golang.org/x/crypto v0.0.0-20170613210332-850760c427c5/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= @@ -363,57 +303,26 @@ golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0J golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 h1:KAeGQVN3M9nD0/bQXnr/ClcEMJ968gUXJQ9pwfSynuQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157 h1:7whR9kGa5LUwFtpLm2ArCEejtnxlGeLbAyjFY8sGNFw= -google.golang.org/genproto/googleapis/api v0.0.0-20240528184218-531527333157/go.mod h1:99sLkeliLXfdj2J75X3Ho+rrVCaJze0uwN7zDDkjPVU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094/go.mod h1:Ue6ibwXGpU+dqIcODieyLOcgj7z8+IcskoNIgZxtrFY= -google.golang.org/grpc v1.65.0 h1:bs/cUb4lp1G5iImFFd3u5ixQzweKizoZJAwBNLR42lc= -google.golang.org/grpc v1.65.0/go.mod h1:WgYC2ypjlB0EiQi6wdKixMqukr6lBc0Vo+oOgjrM5ZQ= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -427,8 +336,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= -gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= launchpad.net/gocheck v0.0.0-20140225173054-000000000087 h1:Izowp2XBH6Ya6rv+hqbceQyw/gSGoXfH/UPoTGduL54= launchpad.net/gocheck v0.0.0-20140225173054-000000000087/go.mod h1:hj7XX3B/0A+80Vse0e+BUHsHMTEhd0O4cpUHr/e/BUM= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= diff --git a/internal/deps/deps.go b/internal/deps/deps.go deleted file mode 100644 index 1d2c3282f..000000000 --- a/internal/deps/deps.go +++ /dev/null @@ -1,311 +0,0 @@ -// (c) Cartesi and individual authors (see AUTHORS) -// SPDX-License-Identifier: Apache-2.0 (see LICENSE) - -// Package deps provides mechanisms to run Node dependencies using docker -package deps - -import ( - "context" - "fmt" - "io" - "log/slog" - "strings" - "sync" - "time" - - "github.com/docker/docker/api/types/container" - "github.com/docker/go-connections/nat" - "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/wait" -) - -const ( - DefaultPostgresDatabase = "postgres" - DefaultPostgresDockerImage = "postgres:16-alpine" - DefaultPostgresPort = "5432" - DefaultPostgresUser = "postgres" - DefaultPostgresPassword = "password" - DefaultDevnetDockerImage = "cartesi/rollups-node-devnet:devel" - DefaultDevnetPort = "8545" - DefaultDevnetBlockTime = "1" - DefaultDevnetBlockToWaitForOnStartup = "21" - DefaultDevnetNoMining = false - - numPostgresCheckReadyAttempts = 2 - pollInterval = 5 * time.Second -) - -const ( - postgresKey = iota - devnetKey -) - -const ( - postgresContainerPort = "5432/tcp" - devnetContainerPort = "8545/tcp" -) - -// Struct to hold Node dependencies containers configurations -type DepsConfig struct { - Postgres *PostgresConfig - Devnet *DevnetConfig -} - -type PostgresConfig struct { - DockerImage string - Port string - Password string -} - -type DevnetConfig struct { - DockerImage string - Port string - BlockTime string - BlockToWaitForOnStartup string - NoMining bool -} - -// Builds a DepsConfig struct with default values -func NewDefaultDepsConfig() *DepsConfig { - return &DepsConfig{ - &PostgresConfig{ - DefaultPostgresDockerImage, - DefaultPostgresPort, - DefaultPostgresPassword, - }, - &DevnetConfig{ - DefaultDevnetDockerImage, - DefaultDevnetPort, - DefaultDevnetBlockTime, - DefaultDevnetBlockToWaitForOnStartup, - DefaultDevnetNoMining, - }, - } -} - -// Struct to represent the Node dependencies containers -type DepsContainers struct { - containers map[int]testcontainers.Container - //Literal copies lock value from waitGroup as sync.WaitGroup contains sync.noCopy - waitGroup *sync.WaitGroup -} - -func (depContainers *DepsContainers) DevnetLogs(ctx context.Context) (io.ReadCloser, error) { - container, ok := depContainers.containers[devnetKey] - if !ok { - return nil, fmt.Errorf("Container Devnet is not present") - } - reader, err := container.Logs(ctx) - if err != nil { - return nil, fmt.Errorf("Error retrieving logs from Devnet Container : %w", err) - } - return reader, nil -} - -func (depContainers *DepsContainers) PostgresLogs(ctx context.Context) (io.ReadCloser, error) { - container, ok := depContainers.containers[postgresKey] - if !ok { - return nil, fmt.Errorf("Container Postgres is not present") - } - reader, err := container.Logs(ctx) - if err != nil { - return nil, fmt.Errorf("Error retrieving logs from Postgres Container : %w", err) - } - return reader, nil -} - -func (depContainers *DepsContainers) DevnetEndpoint( - ctx context.Context, - protocol string, -) (string, error) { - container, ok := depContainers.containers[devnetKey] - if !ok { - return "", fmt.Errorf("Container Devnet is not present") - } - endpoint, err := container.Endpoint(ctx, protocol) - if err != nil { - return "", fmt.Errorf("Error retrieving endpoint from Devnet Container : %w", err) - } - return endpoint, nil -} - -func (depContainers *DepsContainers) PostgresEndpoint( - ctx context.Context, - protocol string, -) (string, error) { - - container, ok := depContainers.containers[postgresKey] - if !ok { - return "", fmt.Errorf("Container Postgres is not present") - } - endpoint, err := container.Endpoint(ctx, protocol) - if err != nil { - return "", fmt.Errorf("Error retrieving endpoint from Postgres Container : %w", err) - } - return endpoint, nil -} - -// debugLogging implements the testcontainers.Logging interface by printing the log to slog.Debug. -type debugLogging struct{} - -func (d debugLogging) Printf(format string, v ...interface{}) { - slog.Debug(fmt.Sprintf(format, v...)) -} - -func createHook(finishedWaitGroup *sync.WaitGroup) []testcontainers.ContainerLifecycleHooks { - return []testcontainers.ContainerLifecycleHooks{ - { - - PostTerminates: []testcontainers.ContainerHook{ - func(ctx context.Context, container testcontainers.Container) error { - finishedWaitGroup.Done() - return nil - }, - }, - }, - } -} - -func buildPortMap(portSpec string) (nat.PortMap, error) { - portMappings, err := nat.ParsePortSpec(portSpec) - if err != nil { - return nil, err - } - - portMap := nat.PortMap{} - for _, portMapping := range portMappings { - portMap[portMapping.Port] = append( - portMap[portMapping.Port], - nat.PortBinding{ - HostIP: portMapping.Binding.HostIP, - HostPort: portMapping.Binding.HostPort, - }) - } - return portMap, nil -} - -// Run starts the Node dependencies containers. -// The returned DepContainers struct can be used to gracefully -// terminate the containers using the Terminate method -func Run(ctx context.Context, depsConfig DepsConfig) (*DepsContainers, error) { - - debugLogger := debugLogging{} - var finishedWaitGroup sync.WaitGroup - containers := make(map[int]testcontainers.Container) - if depsConfig.Postgres != nil { - slog.Info("Starting up Postgres") - // wait strategy copied from testcontainers docs - postgresWaitStrategy := wait.ForLog("database system is ready to accept connections"). - WithOccurrence(numPostgresCheckReadyAttempts). - WithPollInterval(pollInterval) - - postgresPortSpec := postgresContainerPort - if depsConfig.Postgres.Port != "" { - postgresPortSpec = strings.Join([]string{ - depsConfig.Postgres.Port, ":", postgresPortSpec}, "") - } - - portMap, err := buildPortMap(postgresPortSpec) - if err != nil { - return nil, err - } - - postgresReq := testcontainers.ContainerRequest{ - Image: depsConfig.Postgres.DockerImage, - ExposedPorts: []string{postgresContainerPort}, - WaitingFor: postgresWaitStrategy, - Env: map[string]string{ - "POSTGRES_PASSWORD": depsConfig.Postgres.Password, - }, - LifecycleHooks: createHook(&finishedWaitGroup), - HostConfigModifier: func(hostConfig *container.HostConfig) { - hostConfig.PortBindings = portMap - }, - } - - postgres, err := testcontainers.GenericContainer( - ctx, - testcontainers.GenericContainerRequest{ - ContainerRequest: postgresReq, - Started: true, - Logger: debugLogger, - }, - ) - if err != nil { - return nil, err - } - finishedWaitGroup.Add(1) - containers[postgresKey] = postgres - } - - if depsConfig.Devnet != nil { - slog.Info("Starting up Devnet") - devnetPortSpec := devnetContainerPort - if depsConfig.Devnet.Port != "" { - devnetPortSpec = strings.Join([]string{ - depsConfig.Devnet.Port, ":", devnetPortSpec}, "") - } - - portMap, err := buildPortMap(devnetPortSpec) - - if err != nil { - return nil, err - } - - cmd := []string{ - "anvil", - "--load-state", - "/usr/share/devnet/anvil_state.json", - } - var waitStrategy *wait.LogStrategy - if depsConfig.Devnet.NoMining { - cmd = append(cmd, "--no-mining") - waitStrategy = wait.ForLog("net_listening") - } else { - cmd = append(cmd, "--block-time", - depsConfig.Devnet.BlockTime) - waitStrategy = wait.ForLog("Block Number: " + depsConfig.Devnet.BlockToWaitForOnStartup) - } - devNetReq := testcontainers.ContainerRequest{ - Image: depsConfig.Devnet.DockerImage, - ExposedPorts: []string{devnetContainerPort}, - WaitingFor: waitStrategy, - Cmd: cmd, - LifecycleHooks: createHook(&finishedWaitGroup), - HostConfigModifier: func(hostConfig *container.HostConfig) { - hostConfig.PortBindings = portMap - }, - } - - devnet, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{ - ContainerRequest: devNetReq, - Started: true, - Logger: debugLogger, - }) - if err != nil { - return nil, err - } - finishedWaitGroup.Add(1) - containers[devnetKey] = devnet - } - - if len(containers) < 1 { - return nil, fmt.Errorf("configuration is empty") - } - - return &DepsContainers{containers: containers, - waitGroup: &finishedWaitGroup, - }, nil -} - -// Terminate terminates all dependencies containers. This method waits for all the containers -// to terminate or gives an error if it fails to terminate one of the containers -func Terminate(ctx context.Context, depContainers *DepsContainers) error { - for _, depContainer := range depContainers.containers { - terr := depContainer.Terminate(ctx) - if terr != nil { - return terr - } - } - return nil -} diff --git a/internal/node/machinehash.go b/internal/machine/machinehash.go similarity index 72% rename from internal/node/machinehash.go rename to internal/machine/machinehash.go index b50591767..c1191d493 100644 --- a/internal/node/machinehash.go +++ b/internal/machine/machinehash.go @@ -1,7 +1,7 @@ // (c) Cartesi and individual authors (see AUTHORS) // SPDX-License-Identifier: Apache-2.0 (see LICENSE) -package node +package machine import ( "context" @@ -17,17 +17,17 @@ import ( // Validates if the hash from the Cartesi Machine at machineDir matches the template hash onchain. // It returns an error if it doesn't. -func validateMachineHash( +func ValidateMachineHash( ctx context.Context, machineDir string, - applicationAddress string, + applicationAddress common.Address, ethereumNodeAddr string, ) error { - offchainHash, err := readHash(machineDir) + offchainHash, err := ReadHash(machineDir) if err != nil { return err } - onchainHash, err := getTemplateHash(ctx, applicationAddress, ethereumNodeAddr) + onchainHash, err := GetTemplateHash(ctx, applicationAddress, ethereumNodeAddr) if err != nil { return err } @@ -43,7 +43,7 @@ func validateMachineHash( // Reads the Cartesi Machine hash from machineDir. Returns it as a hex string or // an error -func readHash(machineDir string) (string, error) { +func ReadHash(machineDir string) (string, error) { path := path.Join(machineDir, "hash") hash, err := os.ReadFile(path) if err != nil { @@ -60,25 +60,25 @@ func readHash(machineDir string) (string, error) { // Retrieves the template hash from the application contract. Returns it as a // hex string or an error -func getTemplateHash( +func GetTemplateHash( ctx context.Context, - applicationAddress string, - ethereumNodeAddr string, + applicationAddress common.Address, + ethereumProvider string, ) (string, error) { - client, err := ethclient.DialContext(ctx, ethereumNodeAddr) + client, err := ethclient.DialContext(ctx, ethereumProvider) if err != nil { - return "", fmt.Errorf("get template hash: %w", err) + return "", fmt.Errorf("get template hash failed to connect: %w", err) } cartesiApplication, err := iapplication.NewIApplicationCaller( - common.HexToAddress(applicationAddress), + applicationAddress, client, ) if err != nil { - return "", fmt.Errorf("get template hash: %w", err) + return "", fmt.Errorf("get template hash failed to instantiate binding: %w", err) } hash, err := cartesiApplication.GetTemplateHash(&bind.CallOpts{Context: ctx}) if err != nil { - return "", fmt.Errorf("get template hash: %w", err) + return "", fmt.Errorf("get template hash failed to call contract method: %w", err) } return common.Bytes2Hex(hash[:]), nil } diff --git a/internal/machine/machinehash_test.go b/internal/machine/machinehash_test.go new file mode 100644 index 000000000..673d828a8 --- /dev/null +++ b/internal/machine/machinehash_test.go @@ -0,0 +1,158 @@ +// (c) Cartesi and individual authors (see AUTHORS) +// SPDX-License-Identifier: Apache-2.0 (see LICENSE) + +package machine + +import ( + "context" + "os" + "testing" + "time" + + "github.com/cartesi/rollups-node/internal/node/config" + "github.com/cartesi/rollups-node/pkg/ethutil" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/suite" +) + +type ValidateMachineHashSuite struct { + suite.Suite +} + +func TestValidateMachineHash(t *testing.T) { + suite.Run(t, new(ValidateMachineHashSuite)) +} + +func (s *ValidateMachineHashSuite) TestItFailsWhenSnapshotHasNoHash() { + machineDir, err := os.MkdirTemp("", "") + s.Require().Nil(err) + defer os.RemoveAll(machineDir) + + appAddr := common.HexToAddress("0x0000000000000000000000000000000000000000") + err = ValidateMachineHash(context.Background(), machineDir, appAddr, "") + s.ErrorContains(err, "no such file or directory") +} + +func (s *ValidateMachineHashSuite) TestItFailsWhenHashHasWrongSize() { + machineDir, err := mockMachineDir("deadbeef") + s.Require().Nil(err) + defer os.RemoveAll(machineDir) + + appAddr := common.HexToAddress("0x0000000000000000000000000000000000000000") + err = ValidateMachineHash(context.Background(), machineDir, appAddr, "") + s.ErrorContains(err, "wrong size") +} + +func (s *ValidateMachineHashSuite) TestItFailsWhenContextIsCanceled() { + ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) + defer cancel() + + machineDir, err := CreateDefaultMachineSnapshot() + s.Require().Nil(err) + defer os.RemoveAll(machineDir) + + appAddr := common.HexToAddress("0x0000000000000000000000000000000000000000") + err = ValidateMachineHash( + ctx, + machineDir, + appAddr, + config.GetBlockchainHttpEndpoint(), + ) + s.ErrorIs(err, context.DeadlineExceeded) +} + +func (s *ValidateMachineHashSuite) TestItFailsWhenHttpEndpointIsInvalid() { + machineDir, err := CreateDefaultMachineSnapshot() + s.Require().Nil(err) + defer os.RemoveAll(machineDir) + + appAddr := common.HexToAddress("0x0000000000000000000000000000000000000000") + err = ValidateMachineHash( + context.Background(), + machineDir, + appAddr, + "http://invalid-endpoint:8545", + ) + s.ErrorContains(err, "no such host") +} + +func (s *ValidateMachineHashSuite) TestItFailsWhenAppAddressIsInvalid() { + machineDir, err := CreateDefaultMachineSnapshot() + s.Require().Nil(err) + defer os.RemoveAll(machineDir) + + ctx := context.Background() + appAddr := common.HexToAddress("invalid address") + err = ValidateMachineHash( + ctx, + machineDir, + appAddr, + config.GetBlockchainHttpEndpoint(), + ) + s.ErrorContains(err, "no contract code at given address") +} + +func (s *ValidateMachineHashSuite) TestItFailsWhenAppAddressIsWrong() { + machineDir, err := CreateDefaultMachineSnapshot() + s.Require().Nil(err) + defer os.RemoveAll(machineDir) + + templateHash, err := ReadHash(machineDir) + s.Require().Nil(err) + + ctx := context.Background() + _, cleanup, err := ethutil.CreateAnvilSnapshotAndDeployApp(ctx, templateHash) + s.Require().Nil(err) + defer cleanup() + + wrongAppAddr := common.HexToAddress("0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") + + err = ValidateMachineHash( + ctx, + machineDir, + wrongAppAddr, + config.GetBlockchainHttpEndpoint(), + ) + s.ErrorContains(err, "no contract code at given address") +} + +func (s *ValidateMachineHashSuite) TestItSucceedsWhenHashesAreEqual() { + machineDir, err := CreateDefaultMachineSnapshot() + s.Require().Nil(err) + defer os.RemoveAll(machineDir) + + templateHash, err := ReadHash(machineDir) + s.Require().Nil(err) + + ctx := context.Background() + appAddr, cleanup, err := ethutil.CreateAnvilSnapshotAndDeployApp(ctx, templateHash) + s.Require().Nil(err) + defer cleanup() + + err = ValidateMachineHash( + ctx, + machineDir, + appAddr, + config.GetBlockchainHttpEndpoint(), + ) + s.Nil(err) +} + +// ------------------------------------------------------------------------------------------------ +// Auxiliary functions +// ------------------------------------------------------------------------------------------------ + +// Mocks the Cartesi Machine directory by creating a temporary directory with +// a single file named "hash" with the contents of `hash`, a hexadecimal string +func mockMachineDir(hash string) (string, error) { + temp, err := os.MkdirTemp("", "") + if err != nil { + return "", err + } + hashFile := temp + "/hash" + err = os.WriteFile(hashFile, common.FromHex(hash), os.ModePerm) + if err != nil { + return "", err + } + return temp, nil +} diff --git a/internal/machine/snapshot.go b/internal/machine/snapshot.go index 675743632..8a19f0dd3 100644 --- a/internal/machine/snapshot.go +++ b/internal/machine/snapshot.go @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 (see LICENSE) // Package machine provides mechanisms to handle Cartesi Machine Snapshots -// to run Node locally for development and tests +// for development and tests package machine import ( @@ -36,7 +36,7 @@ func fileExists(filePath string) bool { return !errors.Is(err, fs.ErrNotExist) } -func Save(sourceDockerImage string, destDir string, tempContainerName string) error { +func Save(destDir string) error { // Remove previous snapshot dir if fileExists(destDir) { @@ -47,29 +47,24 @@ func Save(sourceDockerImage string, destDir string, tempContainerName string) er } } - // Copy machine snapshot from Docker Container - err := runCommand("docker", "create", "--name", tempContainerName, sourceDockerImage) + err := runCommand("cartesi-machine", "--ram-length=128Mi", "--store="+destDir, + "--", "ioctl-echo-loop --vouchers=1 --notices=1 --reports=1 --verbose=1") if err != nil { return err } - defer func() { - err := runCommand("docker", "rm", tempContainerName) - if err != nil { - slog.Warn("Error trying to delete container", - "container", tempContainerName, - "error", err) - } - }() + slog.Info("Cartesi machine snapshot saved on", + "destination-dir", destDir) + return nil +} - fromDir := fmt.Sprintf("%v:%v", tempContainerName, SNAPSHOT_CONTAINER_PATH) - err = runCommand("docker", "cp", fromDir, destDir) +func CreateDefaultMachineSnapshot() (string, error) { + tmpDir, err := os.MkdirTemp("", "") if err != nil { - return err + return "", err } - - slog.Info("Cartesi machine snapshot saved", - "docker-image", sourceDockerImage, - "destination-dir", destDir) - return nil + if err = Save(tmpDir); err != nil { + return "", err + } + return tmpDir, nil } diff --git a/internal/node/config/config.go b/internal/node/config/config.go index 8ef45fd0f..2478a2f11 100644 --- a/internal/node/config/config.go +++ b/internal/node/config/config.go @@ -77,51 +77,51 @@ func (r Redacted[T]) String() string { // FromEnv loads the config from environment variables. func FromEnv() NodeConfig { var config NodeConfig - config.LogLevel = getLogLevel() - config.LogPrettyEnabled = getLogPrettyEnabled() - config.RollupsEpochLength = getEpochLength() - config.BlockchainID = getBlockchainId() - config.BlockchainHttpEndpoint = Redacted[string]{getBlockchainHttpEndpoint()} - config.BlockchainWsEndpoint = Redacted[string]{getBlockchainWsEndpoint()} - config.LegacyBlockchainEnabled = getLegacyBlockchainEnabled() - config.BlockchainFinalityOffset = getBlockchainFinalityOffset() - config.EvmReaderDefaultBlock = getEvmReaderDefaultBlock() - config.EvmReaderRetryPolicyMaxRetries = getEvmReaderRetryPolicyMaxRetries() - config.EvmReaderRetryPolicyMaxDelay = getEvmReaderRetryPolicyMaxDelay() - config.BlockchainBlockTimeout = getBlockchainBlockTimeout() - config.ContractsInputBoxAddress = getContractsInputBoxAddress() - config.ContractsInputBoxDeploymentBlockNumber = getContractsInputBoxDeploymentBlockNumber() - config.SnapshotDir = getSnapshotDir() - config.PostgresEndpoint = Redacted[string]{getPostgresEndpoint()} - config.HttpAddress = getHttpAddress() - config.HttpPort = getHttpPort() - config.FeatureClaimerEnabled = getFeatureClaimerEnabled() - config.FeatureMachineHashCheckEnabled = getFeatureMachineHashCheckEnabled() + config.LogLevel = GetLogLevel() + config.LogPrettyEnabled = GetLogPrettyEnabled() + config.RollupsEpochLength = GetEpochLength() + config.BlockchainID = GetBlockchainId() + config.BlockchainHttpEndpoint = Redacted[string]{GetBlockchainHttpEndpoint()} + config.BlockchainWsEndpoint = Redacted[string]{GetBlockchainWsEndpoint()} + config.LegacyBlockchainEnabled = GetLegacyBlockchainEnabled() + config.BlockchainFinalityOffset = GetBlockchainFinalityOffset() + config.EvmReaderDefaultBlock = GetEvmReaderDefaultBlock() + config.EvmReaderRetryPolicyMaxRetries = GetEvmReaderRetryPolicyMaxRetries() + config.EvmReaderRetryPolicyMaxDelay = GetEvmReaderRetryPolicyMaxDelay() + config.BlockchainBlockTimeout = GetBlockchainBlockTimeout() + config.ContractsInputBoxAddress = GetContractsInputBoxAddress() + config.ContractsInputBoxDeploymentBlockNumber = GetContractsInputBoxDeploymentBlockNumber() + config.SnapshotDir = GetSnapshotDir() + config.PostgresEndpoint = Redacted[string]{GetPostgresEndpoint()} + config.HttpAddress = GetHttpAddress() + config.HttpPort = GetHttpPort() + config.FeatureClaimerEnabled = GetFeatureClaimerEnabled() + config.FeatureMachineHashCheckEnabled = GetFeatureMachineHashCheckEnabled() config.ExperimentalServerManagerLogBypassEnabled = - getExperimentalServerManagerLogBypassEnabled() - config.ExperimentalSunodoValidatorEnabled = getExperimentalSunodoValidatorEnabled() - if getExperimentalSunodoValidatorEnabled() { + GetExperimentalServerManagerLogBypassEnabled() + config.ExperimentalSunodoValidatorEnabled = GetExperimentalSunodoValidatorEnabled() + if GetExperimentalSunodoValidatorEnabled() { config.ExperimentalSunodoValidatorRedisEndpoint = - getExperimentalSunodoValidatorRedisEndpoint() + GetExperimentalSunodoValidatorRedisEndpoint() } - if getFeatureClaimerEnabled() && !getExperimentalSunodoValidatorEnabled() { + if GetFeatureClaimerEnabled() && !GetExperimentalSunodoValidatorEnabled() { config.Auth = authFromEnv() } - config.AdvancerPollingInterval = getAdvancerPollingInterval() - config.ValidatorPollingInterval = getValidatorPollingInterval() + config.AdvancerPollingInterval = GetAdvancerPollingInterval() + config.ValidatorPollingInterval = GetValidatorPollingInterval() // Temporary. - config.MachineServerVerbosity = cartesimachine.ServerVerbosity(getMachineServerVerbosity()) + config.MachineServerVerbosity = cartesimachine.ServerVerbosity(GetMachineServerVerbosity()) return config } func authFromEnv() Auth { - switch getAuthKind() { + switch GetAuthKind() { case AuthKindPrivateKeyVar: return AuthPrivateKey{ - PrivateKey: Redacted[string]{getAuthPrivateKey()}, + PrivateKey: Redacted[string]{GetAuthPrivateKey()}, } case AuthKindPrivateKeyFile: - path := getAuthPrivateKeyFile() + path := GetAuthPrivateKeyFile() privateKey, err := os.ReadFile(path) if err != nil { panic(fmt.Sprintf("failed to read private-key file: %v", err)) @@ -131,23 +131,23 @@ func authFromEnv() Auth { } case AuthKindMnemonicVar: return AuthMnemonic{ - Mnemonic: Redacted[string]{getAuthMnemonic()}, - AccountIndex: Redacted[int]{getAuthMnemonicAccountIndex()}, + Mnemonic: Redacted[string]{GetAuthMnemonic()}, + AccountIndex: Redacted[int]{GetAuthMnemonicAccountIndex()}, } case AuthKindMnemonicFile: - path := getAuthMnemonicFile() + path := GetAuthMnemonicFile() mnemonic, err := os.ReadFile(path) if err != nil { panic(fmt.Sprintf("failed to read mnemonic file: %v", err)) } return AuthMnemonic{ Mnemonic: Redacted[string]{string(mnemonic)}, - AccountIndex: Redacted[int]{getAuthMnemonicAccountIndex()}, + AccountIndex: Redacted[int]{GetAuthMnemonicAccountIndex()}, } case AuthKindAWS: return AuthAWS{ - KeyID: Redacted[string]{getAuthAwsKmsKeyId()}, - Region: Redacted[string]{getAuthAwsKmsRegion()}, + KeyID: Redacted[string]{GetAuthAwsKmsKeyId()}, + Region: Redacted[string]{GetAuthAwsKmsRegion()}, } default: panic("invalid auth kind") @@ -167,11 +167,11 @@ type AdvancerConfig struct { func GetAdvancerConfig() AdvancerConfig { var config AdvancerConfig - config.LogLevel = getLogLevel() - config.LogPrettyEnabled = getLogPrettyEnabled() - config.PostgresEndpoint = Redacted[string]{getPostgresEndpoint()} - config.AdvancerPollingInterval = getAdvancerPollingInterval() + config.LogLevel = GetLogLevel() + config.LogPrettyEnabled = GetLogPrettyEnabled() + config.PostgresEndpoint = Redacted[string]{GetPostgresEndpoint()} + config.AdvancerPollingInterval = GetAdvancerPollingInterval() // Temporary. - config.MachineServerVerbosity = cartesimachine.ServerVerbosity(getMachineServerVerbosity()) + config.MachineServerVerbosity = cartesimachine.ServerVerbosity(GetMachineServerVerbosity()) return config } diff --git a/internal/node/config/generate/code.go b/internal/node/config/generate/code.go index 33f30e900..34ed77e86 100644 --- a/internal/node/config/generate/code.go +++ b/internal/node/config/generate/code.go @@ -177,7 +177,7 @@ var ( // ------------------------------------------------------------------------------------------------ {{range .}} -func get{{toFunctionName .Name}}() {{.GoType}} { +func Get{{toFunctionName .Name}}() {{.GoType}} { s, ok := os.LookupEnv("{{.Name}}") if !ok { {{- if .Default}} diff --git a/internal/node/config/generated.go b/internal/node/config/generated.go index 305b74a26..8c58c04aa 100644 --- a/internal/node/config/generated.go +++ b/internal/node/config/generated.go @@ -120,7 +120,7 @@ var ( // Getters // ------------------------------------------------------------------------------------------------ -func getAuthAwsKmsKeyId() string { +func GetAuthAwsKmsKeyId() string { s, ok := os.LookupEnv("CARTESI_AUTH_AWS_KMS_KEY_ID") if !ok { panic("missing env var CARTESI_AUTH_AWS_KMS_KEY_ID") @@ -132,7 +132,7 @@ func getAuthAwsKmsKeyId() string { return val } -func getAuthAwsKmsRegion() string { +func GetAuthAwsKmsRegion() string { s, ok := os.LookupEnv("CARTESI_AUTH_AWS_KMS_REGION") if !ok { panic("missing env var CARTESI_AUTH_AWS_KMS_REGION") @@ -144,7 +144,7 @@ func getAuthAwsKmsRegion() string { return val } -func getAuthKind() AuthKind { +func GetAuthKind() AuthKind { s, ok := os.LookupEnv("CARTESI_AUTH_KIND") if !ok { s = "mnemonic" @@ -156,7 +156,7 @@ func getAuthKind() AuthKind { return val } -func getAuthMnemonic() string { +func GetAuthMnemonic() string { s, ok := os.LookupEnv("CARTESI_AUTH_MNEMONIC") if !ok { panic("missing env var CARTESI_AUTH_MNEMONIC") @@ -168,7 +168,7 @@ func getAuthMnemonic() string { return val } -func getAuthMnemonicAccountIndex() int { +func GetAuthMnemonicAccountIndex() int { s, ok := os.LookupEnv("CARTESI_AUTH_MNEMONIC_ACCOUNT_INDEX") if !ok { s = "0" @@ -180,7 +180,7 @@ func getAuthMnemonicAccountIndex() int { return val } -func getAuthMnemonicFile() string { +func GetAuthMnemonicFile() string { s, ok := os.LookupEnv("CARTESI_AUTH_MNEMONIC_FILE") if !ok { panic("missing env var CARTESI_AUTH_MNEMONIC_FILE") @@ -192,7 +192,7 @@ func getAuthMnemonicFile() string { return val } -func getAuthPrivateKey() string { +func GetAuthPrivateKey() string { s, ok := os.LookupEnv("CARTESI_AUTH_PRIVATE_KEY") if !ok { panic("missing env var CARTESI_AUTH_PRIVATE_KEY") @@ -204,7 +204,7 @@ func getAuthPrivateKey() string { return val } -func getAuthPrivateKeyFile() string { +func GetAuthPrivateKeyFile() string { s, ok := os.LookupEnv("CARTESI_AUTH_PRIVATE_KEY_FILE") if !ok { panic("missing env var CARTESI_AUTH_PRIVATE_KEY_FILE") @@ -216,7 +216,7 @@ func getAuthPrivateKeyFile() string { return val } -func getBlockchainBlockTimeout() int { +func GetBlockchainBlockTimeout() int { s, ok := os.LookupEnv("CARTESI_BLOCKCHAIN_BLOCK_TIMEOUT") if !ok { s = "60" @@ -228,7 +228,7 @@ func getBlockchainBlockTimeout() int { return val } -func getBlockchainFinalityOffset() int { +func GetBlockchainFinalityOffset() int { s, ok := os.LookupEnv("CARTESI_BLOCKCHAIN_FINALITY_OFFSET") if !ok { s = "10" @@ -240,7 +240,7 @@ func getBlockchainFinalityOffset() int { return val } -func getBlockchainHttpEndpoint() string { +func GetBlockchainHttpEndpoint() string { s, ok := os.LookupEnv("CARTESI_BLOCKCHAIN_HTTP_ENDPOINT") if !ok { panic("missing env var CARTESI_BLOCKCHAIN_HTTP_ENDPOINT") @@ -252,7 +252,7 @@ func getBlockchainHttpEndpoint() string { return val } -func getBlockchainId() uint64 { +func GetBlockchainId() uint64 { s, ok := os.LookupEnv("CARTESI_BLOCKCHAIN_ID") if !ok { panic("missing env var CARTESI_BLOCKCHAIN_ID") @@ -264,7 +264,7 @@ func getBlockchainId() uint64 { return val } -func getBlockchainWsEndpoint() string { +func GetBlockchainWsEndpoint() string { s, ok := os.LookupEnv("CARTESI_BLOCKCHAIN_WS_ENDPOINT") if !ok { panic("missing env var CARTESI_BLOCKCHAIN_WS_ENDPOINT") @@ -276,7 +276,7 @@ func getBlockchainWsEndpoint() string { return val } -func getEvmReaderDefaultBlock() DefaultBlock { +func GetEvmReaderDefaultBlock() DefaultBlock { s, ok := os.LookupEnv("CARTESI_EVM_READER_DEFAULT_BLOCK") if !ok { s = "finalized" @@ -288,7 +288,7 @@ func getEvmReaderDefaultBlock() DefaultBlock { return val } -func getLegacyBlockchainEnabled() bool { +func GetLegacyBlockchainEnabled() bool { s, ok := os.LookupEnv("CARTESI_LEGACY_BLOCKCHAIN_ENABLED") if !ok { s = "false" @@ -300,7 +300,7 @@ func getLegacyBlockchainEnabled() bool { return val } -func getContractsInputBoxAddress() string { +func GetContractsInputBoxAddress() string { s, ok := os.LookupEnv("CARTESI_CONTRACTS_INPUT_BOX_ADDRESS") if !ok { panic("missing env var CARTESI_CONTRACTS_INPUT_BOX_ADDRESS") @@ -312,7 +312,7 @@ func getContractsInputBoxAddress() string { return val } -func getContractsInputBoxDeploymentBlockNumber() int64 { +func GetContractsInputBoxDeploymentBlockNumber() int64 { s, ok := os.LookupEnv("CARTESI_CONTRACTS_INPUT_BOX_DEPLOYMENT_BLOCK_NUMBER") if !ok { panic("missing env var CARTESI_CONTRACTS_INPUT_BOX_DEPLOYMENT_BLOCK_NUMBER") @@ -324,7 +324,7 @@ func getContractsInputBoxDeploymentBlockNumber() int64 { return val } -func getExperimentalServerManagerLogBypassEnabled() bool { +func GetExperimentalServerManagerLogBypassEnabled() bool { s, ok := os.LookupEnv("CARTESI_EXPERIMENTAL_SERVER_MANAGER_LOG_BYPASS_ENABLED") if !ok { s = "false" @@ -336,7 +336,7 @@ func getExperimentalServerManagerLogBypassEnabled() bool { return val } -func getExperimentalSunodoValidatorEnabled() bool { +func GetExperimentalSunodoValidatorEnabled() bool { s, ok := os.LookupEnv("CARTESI_EXPERIMENTAL_SUNODO_VALIDATOR_ENABLED") if !ok { s = "false" @@ -348,7 +348,7 @@ func getExperimentalSunodoValidatorEnabled() bool { return val } -func getExperimentalSunodoValidatorRedisEndpoint() string { +func GetExperimentalSunodoValidatorRedisEndpoint() string { s, ok := os.LookupEnv("CARTESI_EXPERIMENTAL_SUNODO_VALIDATOR_REDIS_ENDPOINT") if !ok { panic("missing env var CARTESI_EXPERIMENTAL_SUNODO_VALIDATOR_REDIS_ENDPOINT") @@ -360,7 +360,7 @@ func getExperimentalSunodoValidatorRedisEndpoint() string { return val } -func getFeatureClaimerEnabled() bool { +func GetFeatureClaimerEnabled() bool { s, ok := os.LookupEnv("CARTESI_FEATURE_CLAIMER_ENABLED") if !ok { s = "true" @@ -372,7 +372,7 @@ func getFeatureClaimerEnabled() bool { return val } -func getFeatureMachineHashCheckEnabled() bool { +func GetFeatureMachineHashCheckEnabled() bool { s, ok := os.LookupEnv("CARTESI_FEATURE_MACHINE_HASH_CHECK_ENABLED") if !ok { s = "true" @@ -384,7 +384,7 @@ func getFeatureMachineHashCheckEnabled() bool { return val } -func getHttpAddress() string { +func GetHttpAddress() string { s, ok := os.LookupEnv("CARTESI_HTTP_ADDRESS") if !ok { s = "127.0.0.1" @@ -396,7 +396,7 @@ func getHttpAddress() string { return val } -func getHttpPort() int { +func GetHttpPort() int { s, ok := os.LookupEnv("CARTESI_HTTP_PORT") if !ok { s = "10000" @@ -408,7 +408,7 @@ func getHttpPort() int { return val } -func getLogLevel() LogLevel { +func GetLogLevel() LogLevel { s, ok := os.LookupEnv("CARTESI_LOG_LEVEL") if !ok { s = "info" @@ -420,7 +420,7 @@ func getLogLevel() LogLevel { return val } -func getLogPrettyEnabled() bool { +func GetLogPrettyEnabled() bool { s, ok := os.LookupEnv("CARTESI_LOG_PRETTY_ENABLED") if !ok { s = "false" @@ -432,7 +432,7 @@ func getLogPrettyEnabled() bool { return val } -func getPostgresEndpoint() string { +func GetPostgresEndpoint() string { s, ok := os.LookupEnv("CARTESI_POSTGRES_ENDPOINT") if !ok { s = "" @@ -444,7 +444,7 @@ func getPostgresEndpoint() string { return val } -func getAdvancerPollingInterval() Duration { +func GetAdvancerPollingInterval() Duration { s, ok := os.LookupEnv("CARTESI_ADVANCER_POLLING_INTERVAL") if !ok { s = "30" @@ -456,7 +456,7 @@ func getAdvancerPollingInterval() Duration { return val } -func getEpochLength() uint64 { +func GetEpochLength() uint64 { s, ok := os.LookupEnv("CARTESI_EPOCH_LENGTH") if !ok { s = "7200" @@ -468,7 +468,7 @@ func getEpochLength() uint64 { return val } -func getEvmReaderRetryPolicyMaxDelay() Duration { +func GetEvmReaderRetryPolicyMaxDelay() Duration { s, ok := os.LookupEnv("CARTESI_EVM_READER_RETRY_POLICY_MAX_DELAY") if !ok { s = "3" @@ -480,7 +480,7 @@ func getEvmReaderRetryPolicyMaxDelay() Duration { return val } -func getEvmReaderRetryPolicyMaxRetries() uint64 { +func GetEvmReaderRetryPolicyMaxRetries() uint64 { s, ok := os.LookupEnv("CARTESI_EVM_READER_RETRY_POLICY_MAX_RETRIES") if !ok { s = "3" @@ -492,7 +492,7 @@ func getEvmReaderRetryPolicyMaxRetries() uint64 { return val } -func getValidatorPollingInterval() Duration { +func GetValidatorPollingInterval() Duration { s, ok := os.LookupEnv("CARTESI_VALIDATOR_POLLING_INTERVAL") if !ok { s = "30" @@ -504,7 +504,7 @@ func getValidatorPollingInterval() Duration { return val } -func getSnapshotDir() string { +func GetSnapshotDir() string { s, ok := os.LookupEnv("CARTESI_SNAPSHOT_DIR") if !ok { s = "/var/lib/cartesi-rollups-node/snapshots" @@ -516,7 +516,7 @@ func getSnapshotDir() string { return val } -func getMachineServerVerbosity() string { +func GetMachineServerVerbosity() string { s, ok := os.LookupEnv("CARTESI_MACHINE_SERVER_VERBOSITY") if !ok { s = "info" diff --git a/internal/node/machinehash_test.go b/internal/node/machinehash_test.go deleted file mode 100644 index 76dc1b24d..000000000 --- a/internal/node/machinehash_test.go +++ /dev/null @@ -1,149 +0,0 @@ -// (c) Cartesi and individual authors (see AUTHORS) -// SPDX-License-Identifier: Apache-2.0 (see LICENSE) - -package node - -import ( - "context" - "os" - "testing" - "time" - - "github.com/cartesi/rollups-node/internal/deps" - "github.com/cartesi/rollups-node/internal/machine" - "github.com/cartesi/rollups-node/pkg/addresses" - "github.com/cartesi/rollups-node/pkg/testutil" - "github.com/ethereum/go-ethereum/common" - "github.com/stretchr/testify/suite" -) - -type ValidateMachineHashSuite struct { - suite.Suite -} - -func TestValidateMachineHash(t *testing.T) { - suite.Run(t, new(ValidateMachineHashSuite)) -} - -func (s *ValidateMachineHashSuite) TestItFailsWhenSnapshotHasNoHash() { - machineDir, err := os.MkdirTemp("", "") - s.Require().Nil(err) - defer os.RemoveAll(machineDir) - - err = validateMachineHash(context.Background(), machineDir, "", "") - s.ErrorContains(err, "no such file or directory") -} - -func (s *ValidateMachineHashSuite) TestItFailsWhenHashHasWrongSize() { - machineDir, err := mockMachineDir("deadbeef") - s.Require().Nil(err) - defer os.RemoveAll(machineDir) - - err = validateMachineHash(context.Background(), machineDir, "", "") - s.ErrorContains(err, "wrong size") -} - -func (s *ValidateMachineHashSuite) TestItFailsWhenContextIsCanceled() { - ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) - defer cancel() - - machineDir, err := createMachineSnapshot() - s.Require().Nil(err) - defer os.RemoveAll(machineDir) - - dependencies, err := startDevnet() - s.Require().Nil(err) - defer func() { - err = deps.Terminate(context.Background(), dependencies) - s.Nil(err) - }() - - blockchainHttpEndpoint, err := dependencies.DevnetEndpoint(context.Background(), "http") - s.Require().Nil(err) - - err = validateMachineHash( - ctx, - machineDir, - addresses.GetTestBook().Application.String(), - blockchainHttpEndpoint, - ) - s.NotNil(err) - s.ErrorIs(err, context.DeadlineExceeded) -} - -func (s *ValidateMachineHashSuite) TestItSucceedsWhenHashesAreEqual() { - ctx := context.Background() - - machineDir, err := createMachineSnapshot() - s.Require().Nil(err) - defer os.RemoveAll(machineDir) - - dependencies, err := startDevnet() - s.Require().Nil(err) - defer func() { - err = deps.Terminate(context.Background(), dependencies) - s.Nil(err) - }() - - blockchainHttpEndpoint, err := dependencies.DevnetEndpoint(context.Background(), "http") - s.Require().Nil(err) - - err = validateMachineHash( - ctx, - machineDir, - addresses.GetTestBook().Application.String(), - blockchainHttpEndpoint, - ) - s.Nil(err) -} - -// ------------------------------------------------------------------------------------------------ -// Auxiliary functions -// ------------------------------------------------------------------------------------------------ - -// Mocks the Cartesi Machine directory by creating a temporary directory with -// a single file named "hash" with the contents of `hash`, a hexadecimal string -func mockMachineDir(hash string) (string, error) { - temp, err := os.MkdirTemp("", "") - if err != nil { - return "", err - } - hashFile := temp + "/hash" - err = os.WriteFile(hashFile, common.FromHex(hash), os.ModePerm) - if err != nil { - return "", err - } - return temp, nil -} - -// Generates a new Cartesi Machine snapshot in a temporary directory and returns its path -func createMachineSnapshot() (string, error) { - tmpDir, err := os.MkdirTemp("", "") - if err != nil { - return "", err - } - if err = machine.Save( - "cartesi/rollups-node-snapshot:devel", - tmpDir, - "snapshotTemp", - ); err != nil { - return "", err - } - return tmpDir, nil -} - -// Starts a devnet in a Docker container with the default parameters -func startDevnet() (*deps.DepsContainers, error) { - container, err := deps.Run(context.Background(), deps.DepsConfig{ - Devnet: &deps.DevnetConfig{ - DockerImage: deps.DefaultDevnetDockerImage, - BlockTime: deps.DefaultDevnetBlockTime, - BlockToWaitForOnStartup: deps.DefaultDevnetBlockToWaitForOnStartup, - Port: testutil.GetCartesiTestDepsPortRange(), - }, - }) - if err != nil { - return nil, err - } - return container, nil -} diff --git a/internal/nodemachine/machine.go b/internal/nodemachine/machine.go index 396d1a0b0..9897b109f 100644 --- a/internal/nodemachine/machine.go +++ b/internal/nodemachine/machine.go @@ -198,7 +198,7 @@ func (machine *NodeMachine) Inspect(ctx context.Context, query []byte) (*Inspect func (machine *NodeMachine) Close() error { ctx := context.Background() - // Makes sure no thread is acessing the machine before closing it. + // Makes sure no thread is accessing the machine before closing it. machine.concurrentAdvances.Lock() defer machine.concurrentAdvances.Unlock() for i := 0; i < int(machine.maxConcurrentInspects); i++ { diff --git a/internal/repository/base_test.go b/internal/repository/base_test.go index 3866e2313..180f1a842 100644 --- a/internal/repository/base_test.go +++ b/internal/repository/base_test.go @@ -10,12 +10,9 @@ import ( "time" . "github.com/cartesi/rollups-node/internal/node/model" - "github.com/cartesi/rollups-node/internal/repository/schema" + "github.com/cartesi/rollups-node/test/tooling/db" "github.com/ethereum/go-ethereum/common" "github.com/stretchr/testify/suite" - "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/modules/postgres" - "github.com/testcontainers/testcontainers-go/wait" ) const testTimeout = 300 * time.Second @@ -25,7 +22,6 @@ type RepositorySuite struct { suite.Suite ctx context.Context cancel context.CancelFunc - postgres *postgres.PostgresContainer database *Database } @@ -33,16 +29,10 @@ func (s *RepositorySuite) SetupSuite() { s.ctx, s.cancel = context.WithTimeout(context.Background(), testTimeout) var err error - s.postgres, err = newPostgresContainer(s.ctx) + endpoint, err := db.GetPostgresTestEndpoint() s.Require().Nil(err) - endpoint, err := s.postgres.ConnectionString(s.ctx, "sslmode=disable") - s.Require().Nil(err) - - schema, err := schema.New(endpoint) - s.Require().Nil(err) - - err = schema.Upgrade() + err = db.SetupTestPostgres(endpoint) s.Require().Nil(err) s.database, err = Connect(s.ctx, endpoint) @@ -52,8 +42,6 @@ func (s *RepositorySuite) SetupSuite() { } func (s *RepositorySuite) TearDownSuite() { - err := s.postgres.Terminate(s.ctx) - s.Nil(err) s.cancel() } @@ -480,25 +468,3 @@ func (s *RepositorySuite) TestInsertSnapshotFailsSameInputId() { func TestRepositorySuite(t *testing.T) { suite.Run(t, new(RepositorySuite)) } - -// We use the postgres alpine docker image to test the repository. -func newPostgresContainer(ctx context.Context) (*postgres.PostgresContainer, error) { - dbName := "postgres" - dbUser := "postgres" - dbPassword := "password" - - // Start the postgres container - container, err := postgres.Run( - ctx, - "postgres:16-alpine", - postgres.WithDatabase(dbName), - postgres.WithUsername(dbUser), - postgres.WithPassword(dbPassword), - testcontainers.WithWaitStrategy( - wait.ForLog("database system is ready to accept connections"). - WithOccurrence(2). - WithStartupTimeout(5*time.Second)), - ) - - return container, err -} diff --git a/internal/repository/machine_test.go b/internal/repository/machine_test.go index fc54d5e0e..c2c599e55 100644 --- a/internal/repository/machine_test.go +++ b/internal/repository/machine_test.go @@ -22,7 +22,11 @@ func TestMachineRepository(t *testing.T) { t.Run("GetMachineConfigurations", func(t *testing.T) { require := require.New(t) - endpoint, err := db.Setup(ctx) + var err error + endpoint, err := db.GetPostgresTestEndpoint() + require.Nil(err) + + err = db.SetupTestPostgres(endpoint) require.Nil(err) database, err := Connect(ctx, endpoint) @@ -63,7 +67,11 @@ func TestMachineRepository(t *testing.T) { t.Run("UpdateEpochs", func(t *testing.T) { require := require.New(t) - endpoint, err := db.Setup(ctx) + var err error + endpoint, err := db.GetPostgresTestEndpoint() + require.Nil(err) + + err = db.SetupTestPostgres(endpoint) require.Nil(err) database, err := Connect(ctx, endpoint) diff --git a/pkg/addresses/addresses.go b/pkg/addresses/addresses.go index f13c36976..ddd8dbf2f 100644 --- a/pkg/addresses/addresses.go +++ b/pkg/addresses/addresses.go @@ -19,11 +19,9 @@ import ( // List of contract addresses. type Book struct { - Application common.Address + ChainId uint64 ApplicationFactory common.Address - Authority common.Address AuthorityFactory common.Address - DAppAddressRelay common.Address ERC1155BatchPortal common.Address ERC1155SinglePortal common.Address ERC20Portal common.Address @@ -31,40 +29,8 @@ type Book struct { EtherPortal common.Address InputBox common.Address QuorumFactory common.Address - SelfHostedApplicationFactory common.Address SafeERC20Transfer common.Address -} - -// Get the addresses for the test environment. -func GetTestBook() *Book { - return &Book{ - Application: common.HexToAddress( - "0x1b0FAD42f016a9EBa358c7491A67fa1fAE82912A"), - ApplicationFactory: common.HexToAddress( - "0xA1DA32BF664109D62208a1cb0d69aACc6a484873"), - Authority: common.HexToAddress( - "0x3fd5dc9dCf5Df3c7002C0628Eb9AD3bb5e2ce257"), - AuthorityFactory: common.HexToAddress( - "0xbDC5D42771A4Ae55eC7670AAdD2458D1d9C7C8A8"), - ERC1155BatchPortal: common.HexToAddress( - "0x4a218D331C0933d7E3EB496ac901669f28D94981"), - ERC1155SinglePortal: common.HexToAddress( - "0x2f0D587DD6EcF67d25C558f2e9c3839c579e5e38"), - ERC20Portal: common.HexToAddress( - "0xB0e28881FF7ee9CD5B1229d570540d74bce23D39"), - ERC721Portal: common.HexToAddress( - "0x874b3245ead7474Cb9f3b83cD1446dC522f6bd36"), - EtherPortal: common.HexToAddress( - "0xfa2292f6D85ea4e629B156A4f99219e30D12EE17"), - InputBox: common.HexToAddress( - "0x593E5BCf894D6829Dd26D0810DA7F064406aebB6"), - QuorumFactory: common.HexToAddress( - "0x68C3d53a095f66A215a8bEe096Cd3Ba4fFB7bAb3"), - SelfHostedApplicationFactory: common.HexToAddress( - "0x0678FAA399F0193Fb9212BE41590316D275b1392"), - SafeERC20Transfer: common.HexToAddress( - "0x817b126F242B5F184Fa685b4f2F91DC99D8115F9"), - } + SelfHostedApplicationFactory common.Address } // Get the address book from json File. diff --git a/pkg/ethutil/anvil.go b/pkg/ethutil/anvil.go new file mode 100644 index 000000000..24720a8bc --- /dev/null +++ b/pkg/ethutil/anvil.go @@ -0,0 +1,80 @@ +// (c) Cartesi and individual authors (see AUTHORS) +// SPDX-License-Identifier: Apache-2.0 (see LICENSE) + +package ethutil + +import ( + "context" + "fmt" + "log" + + "github.com/cartesi/rollups-node/internal/node/config" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rpc" +) + +func CreateAnvilSnapshotAndDeployApp(ctx context.Context, templateHash string) (common.Address, func(), error) { + var contractAddr common.Address + // Connect to Anvil (replace with appropriate RPC URL) + client, err := ethclient.Dial(config.GetBlockchainHttpEndpoint()) + if err != nil { + return contractAddr, nil, fmt.Errorf("failed to connect to Anvil: %w", err) + } + + // Create a snapshot of the current state + snapshotID, err := CreateAnvilSnapshot(client.Client()) + if err != nil { + return contractAddr, nil, fmt.Errorf("failed to create snapshot: %w", err) + } + + signer, err := NewMnemonicSigner(ctx, client, FoundryMnemonic, 0) + if err != nil { + _ = RevertToAnvilSnapshot(client.Client(), snapshotID) + return contractAddr, nil, fmt.Errorf("failed to create signer: %w", err) + } + + factoryAddr := common.HexToAddress("0x0678FAA399F0193Fb9212BE41590316D275b1392") // FIXME get from book + owner := signer.Account() + salt := "0000000000000000000000000000000000000000000000000000000000000000" + // Deploy the application contract + contractAddr, err = DeploySelfHostedApplication(ctx, client, signer, factoryAddr, owner, + templateHash, salt) + if err != nil { + _ = RevertToAnvilSnapshot(client.Client(), snapshotID) + return contractAddr, nil, fmt.Errorf("failed to deploy application contract: %w", err) + } + + // Define a cleanup function to revert to the snapshot + cleanup := func() { + err := RevertToAnvilSnapshot(client.Client(), snapshotID) + if err != nil { + log.Printf("failed to revert to snapshot: %v", err) + } + } + + return contractAddr, cleanup, nil +} + +func CreateAnvilSnapshot(rpcClient *rpc.Client) (string, error) { + var snapshotID string + // Using the JSON-RPC method "evm_snapshot" to create a snapshot + err := rpcClient.Call(&snapshotID, "evm_snapshot") + if err != nil { + return "", fmt.Errorf("failed to create snapshot: %w", err) + } + return snapshotID, nil +} + +func RevertToAnvilSnapshot(rpcClient *rpc.Client, snapshotID string) error { + var success bool + // Using the JSON-RPC method "evm_revert" to revert to the snapshot + err := rpcClient.Call(&success, "evm_revert", snapshotID) + if err != nil { + return fmt.Errorf("failed to revert to snapshot: %w", err) + } + if !success { + return fmt.Errorf("failed to revert to snapshot with ID: %s", snapshotID) + } + return nil +} diff --git a/pkg/ethutil/ethutil.go b/pkg/ethutil/ethutil.go index 3b9d46d47..e847e2b08 100644 --- a/pkg/ethutil/ethutil.go +++ b/pkg/ethutil/ethutil.go @@ -12,10 +12,11 @@ import ( "github.com/cartesi/rollups-node/pkg/addresses" "github.com/cartesi/rollups-node/pkg/contracts/iapplication" + "github.com/cartesi/rollups-node/pkg/contracts/iapplicationfactory" "github.com/cartesi/rollups-node/pkg/contracts/iinputbox" + "github.com/cartesi/rollups-node/pkg/contracts/iselfhostedapplicationfactory" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethclient" "github.com/ethereum/go-ethereum/rpc" @@ -37,6 +38,60 @@ type Signer interface { Account() common.Address } +func DeploySelfHostedApplication( + ctx context.Context, + client *ethclient.Client, + signer Signer, + shAppFactoryAddr common.Address, + ownerAddr common.Address, + templateHash string, + salt string, +) (common.Address, error) { + var appAddr common.Address + templateHashBytes := common.Hex2Bytes(templateHash) + saltBytes := common.Hex2Bytes(salt) + + factory, err := iselfhostedapplicationfactory.NewISelfHostedApplicationFactory(shAppFactoryAddr, client) + if err != nil { + return appAddr, fmt.Errorf("Failed to instantiate contract: %v", err) + } + + receipt, err := sendTransaction( + ctx, client, signer, big.NewInt(0), GasLimit, + func(txOpts *bind.TransactOpts) (*types.Transaction, error) { + return factory.DeployContracts(txOpts, ownerAddr, big.NewInt(10), ownerAddr, toBytes32(templateHashBytes), toBytes32(saltBytes)) + }, + ) + if err != nil { + return appAddr, err + } + // Parse logs to get the address of the new application contract + contractABI, err := iapplicationfactory.IApplicationFactoryMetaData.GetAbi() + if err != nil { + return appAddr, fmt.Errorf("Failed to parse IApplicationFactory ABI: %v", err) + } + + // Look for the specific event in the receipt logs + for _, vLog := range receipt.Logs { + event := struct { + Consensus common.Address + AppOwner common.Address + TemplateHash [32]byte + AppContract common.Address + }{} + + // Parse log for ApplicationCreated event + err := contractABI.UnpackIntoInterface(&event, "ApplicationCreated", vLog.Data) + if err != nil { + continue // Skip logs that don't match + } + + return event.AppContract, nil + } + + return appAddr, fmt.Errorf("Failed to find ApplicationCreated event in receipt logs") +} + // Add input to the input box for the given DApp address. // This function waits until the transaction is added to a block and return the input index. func AddInput( @@ -63,39 +118,6 @@ func AddInput( return getInputIndex(book, inputBox, receipt) } -// Convenience function to add an input using Foundry Mnemonic -// This function waits until the transaction is added to a block and return the input index. -func AddInputUsingFoundryMnemonic( - ctx context.Context, - blockchainHttpEndpoint string, - payload string, -) (int, error) { - - // Send Input - client, err := ethclient.DialContext(ctx, blockchainHttpEndpoint) - if err != nil { - return 0, err - } - defer client.Close() - - signer, err := NewMnemonicSigner(ctx, client, FoundryMnemonic, 0) - if err != nil { - return 0, err - } - book, err := addresses.GetBookFromFile("deployment.json") // FIXME - if err != nil { - return 0, err - } - - appAddr := common.HexToAddress("0x0000000000000000000000000000000000000000") // FIXME - - payloadBytes, err := hexutil.Decode(payload) - if err != nil { - panic(err) - } - return AddInput(ctx, client, book, appAddr, signer, payloadBytes) -} - // Get input index in the transaction by looking at the event logs. func getInputIndex( book *addresses.Book, @@ -239,3 +261,13 @@ func MineNewBlock( defer ethClient.Close() return ethClient.BlockNumber(ctx) } + +func toBytes32(data []byte) [32]byte { + var arr [32]byte + if len(data) > 32 { + copy(arr[:], data[:32]) + } else { + copy(arr[:], data) + } + return arr +} diff --git a/pkg/ethutil/ethutil_test.go b/pkg/ethutil/ethutil_test.go index e015f1c99..12725a4ce 100644 --- a/pkg/ethutil/ethutil_test.go +++ b/pkg/ethutil/ethutil_test.go @@ -5,10 +5,13 @@ package ethutil import ( "context" + "os" "sync" "testing" "time" + "github.com/cartesi/rollups-node/internal/machine" + "github.com/cartesi/rollups-node/internal/node/config" "github.com/cartesi/rollups-node/pkg/addresses" "github.com/cartesi/rollups-node/pkg/contracts/inputs" "github.com/ethereum/go-ethereum/common" @@ -17,24 +20,27 @@ import ( ) const testTimeout = 300 * time.Second -const inputBoxDeploymentBlockNumber = 0x0F // This suite sets up a container running a devnet Ethereum node, and connects to it using // go-ethereum's client. type EthUtilSuite struct { suite.Suite - ctx context.Context - cancel context.CancelFunc - client *ethclient.Client - endpoint string - signer Signer - book *addresses.Book - appAddr common.Address + ctx context.Context + cancel context.CancelFunc + client *ethclient.Client + endpoint string + signer Signer + book *addresses.Book + appAddr common.Address + machineDir string + cleanup func() } func (s *EthUtilSuite) SetupTest() { s.ctx, s.cancel = context.WithTimeout(context.Background(), testTimeout) + s.endpoint = config.GetBlockchainHttpEndpoint() + var err error s.client, err = ethclient.DialContext(s.ctx, s.endpoint) s.Require().Nil(err) @@ -42,14 +48,22 @@ func (s *EthUtilSuite) SetupTest() { s.signer, err = NewMnemonicSigner(s.ctx, s.client, FoundryMnemonic, 0) s.Require().Nil(err) - s.book, err = addresses.GetBookFromFile("deployment.json") // FIXME + s.book, err = addresses.GetBookFromFile("../../deployment.json") // FIXME + s.Require().Nil(err) + + s.machineDir, err = machine.CreateDefaultMachineSnapshot() + s.Require().Nil(err) + + templateHash, err := machine.ReadHash(s.machineDir) s.Require().Nil(err) - s.appAddr = common.HexToAddress("0x0000000000000000000000000000000000000000") // FIXME + s.appAddr, s.cleanup, err = CreateAnvilSnapshotAndDeployApp(s.ctx, templateHash) + s.Require().Nil(err) } func (s *EthUtilSuite) TearDownTest() { - // TODO revert anvil snapshot + os.RemoveAll(s.machineDir) + s.cleanup() s.cancel() } @@ -79,9 +93,8 @@ func (s *EthUtilSuite) TestAddInput() { waitGroup.Wait() time.Sleep(1 * time.Second) - blockNumber, err := MineNewBlock(s.ctx, s.endpoint) + _, err = MineNewBlock(s.ctx, s.endpoint) s.Require().Nil(err) - s.Require().Equal(uint64(inputBoxDeploymentBlockNumber+1), blockNumber) select { case err := <-errChan: @@ -106,9 +119,11 @@ func (s *EthUtilSuite) TestAddInput() { } func (s *EthUtilSuite) TestMineNewBlock() { + prevBlockNumber, err := s.client.BlockNumber(s.ctx) + s.Require().Nil(err) blockNumber, err := MineNewBlock(s.ctx, s.endpoint) s.Require().Nil(err) - s.Require().Equal(uint64(inputBoxDeploymentBlockNumber+1), blockNumber) + s.Require().Equal(prevBlockNumber+1, blockNumber) } diff --git a/pkg/ethutil/mnemonic.go b/pkg/ethutil/mnemonic.go index fbb4cc29b..45c88bfd5 100644 --- a/pkg/ethutil/mnemonic.go +++ b/pkg/ethutil/mnemonic.go @@ -36,7 +36,7 @@ func NewMnemonicSigner( if err != nil { return nil, fmt.Errorf("get chain id: %v", err) } - privateKey, err := mnemonicToPrivateKey(mnemonic, accountIndex) + privateKey, err := MnemonicToPrivateKey(mnemonic, accountIndex) if err != nil { return nil, err } @@ -60,7 +60,7 @@ func (s *MnemonicSigner) Account() common.Address { // Create the private key from mnemonic and account index based on the BIP44 standard. // For more info on BIP44, see https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki -func mnemonicToPrivateKey(mnemonic string, accountIndex uint32) (*ecdsa.PrivateKey, error) { +func MnemonicToPrivateKey(mnemonic string, accountIndex uint32) (*ecdsa.PrivateKey, error) { seed := bip39.NewSeed(mnemonic, "") masterKey, err := bip32.NewMasterKey(seed) diff --git a/pkg/ethutil/mnemonic_test.go b/pkg/ethutil/mnemonic_test.go index b42144e9d..65144fa88 100644 --- a/pkg/ethutil/mnemonic_test.go +++ b/pkg/ethutil/mnemonic_test.go @@ -14,7 +14,7 @@ func testKey(t *testing.T, mnemonic string, account uint32, expected string) { expectedKey, err := crypto.HexToECDSA(expected) require.Nil(t, err) - key, err := mnemonicToPrivateKey(mnemonic, account) + key, err := MnemonicToPrivateKey(mnemonic, account) require.Nil(t, err) require.Equal(t, expectedKey, key) } diff --git a/pkg/testutil/testutil.go b/pkg/testutil/testutil.go deleted file mode 100644 index dfb689282..000000000 --- a/pkg/testutil/testutil.go +++ /dev/null @@ -1,12 +0,0 @@ -// (c) Cartesi and individual authors (see AUTHORS) -// SPDX-License-Identifier: Apache-2.0 (see LICENSE) - -// This package contains tests utilities. - -package testutil - -import "os" - -func GetCartesiTestDepsPortRange() string { - return os.Getenv("CARTESI_TEST_DEPS_PORT_RANGE") -} diff --git a/test/config.go b/test/config.go index 30411aa8e..2d13a32c4 100644 --- a/test/config.go +++ b/test/config.go @@ -5,6 +5,7 @@ package endtoendtests import ( + "log" "log/slog" "github.com/cartesi/rollups-node/internal/node/config" @@ -27,7 +28,10 @@ func NewLocalNodeConfig(localPostgresEndpoint string, localBlockchainHttpEndpoin var nodeConfig config.NodeConfig - book := addresses.GetTestBook() + book, err := addresses.GetBookFromFile("deployment.json") + if err != nil { + log.Fatalf("failed to load address book: %v", err) + } //Log nodeConfig.LogLevel = slog.LevelInfo diff --git a/test/echo_test.go b/test/echo_test.go deleted file mode 100644 index 8c178e140..000000000 --- a/test/echo_test.go +++ /dev/null @@ -1,190 +0,0 @@ -// (c) Cartesi and individual authors (see AUTHORS) -// SPDX-License-Identifier: Apache-2.0 (see LICENSE) - -//go:build endtoendtests -// +build endtoendtests - -package endtoendtests - -import ( - "context" - _ "embed" - "encoding/json" - "net/url" - "os" - "path" - "testing" - "time" - - "github.com/Khan/genqlient/graphql" - "github.com/cartesi/rollups-node/internal/deps" - "github.com/cartesi/rollups-node/internal/machine" - "github.com/cartesi/rollups-node/internal/node" - "github.com/cartesi/rollups-node/pkg/ethutil" - "github.com/cartesi/rollups-node/pkg/readerclient" - "github.com/cartesi/rollups-node/pkg/testutil" - "github.com/stretchr/testify/suite" -) - -const ( - payload = "0xdeadbeef" - maxReadInputAttempts = 10 - blockTimestampInSeconds = 7000000000 - testTimeout = 300 * time.Second - devNetAdvanceTimeInSeconds = 120 - devNetMiningBlockTimeInSeconds = "2" - graphqlEndpoint = "http://localhost:10000/graphql" -) - -type EchoInputTestSuite struct { - suite.Suite - containers *deps.DepsContainers - ctx context.Context - cancel context.CancelFunc - tempDir string - supervisorErr chan error - blockchainHttpEndpoint string -} - -//go:embed data/echo_input/expected_input_with_proofs.json -var expectedInputJsonBytes []byte - -func (s *EchoInputTestSuite) SetupTest() { - - ctx, cancel := context.WithTimeout(context.Background(), testTimeout) - - // Create tempdir - tempDir, err := os.MkdirTemp("", "echo-test") - s.Require().Nil(err) - snapshotDir := path.Join(tempDir, "machine-snapshot") - - machine.Save("cartesi/rollups-node-snapshot:devel", snapshotDir, "test-echo-app") - - // Run deps - var depsConfig = deps.DepsConfig{ - &deps.PostgresConfig{ - DockerImage: deps.DefaultPostgresDockerImage, - Port: testutil.GetCartesiTestDepsPortRange(), - Password: deps.DefaultPostgresPassword, - }, - &deps.DevnetConfig{ - DockerImage: deps.DefaultDevnetDockerImage, - Port: testutil.GetCartesiTestDepsPortRange(), - BlockTime: devNetMiningBlockTimeInSeconds, - BlockToWaitForOnStartup: deps.DefaultDevnetBlockToWaitForOnStartup, - }, - } - - depsContainers, err := deps.Run(ctx, depsConfig) - s.Require().Nil(err) - - // Capture endpoints - postgresEndpoint, err := depsContainers.PostgresEndpoint(ctx, "postgres") - s.Require().Nil(err) - - postgresUrl, err := url.Parse(postgresEndpoint) - s.Require().Nil(err) - - postgresUrl.User = url.UserPassword(deps.DefaultPostgresUser, deps.DefaultPostgresPassword) - postgresUrl = postgresUrl.JoinPath(deps.DefaultPostgresDatabase) - - devnetHttpEndpoint, err := depsContainers.DevnetEndpoint(ctx, "http") - s.Require().Nil(err) - devnetWsEndpoint, err := depsContainers.DevnetEndpoint(ctx, "ws") - s.Require().Nil(err) - - s.blockchainHttpEndpoint = devnetHttpEndpoint - - // Fix the Blockchain timestamp. Must be "in the future" - err = ethutil.SetNextDevnetBlockTimestamp(ctx, devnetHttpEndpoint, blockTimestampInSeconds) - s.Require().Nil(err) - - // Run Node Service - nodeConfig := NewLocalNodeConfig(postgresUrl.String(), devnetHttpEndpoint, devnetWsEndpoint, snapshotDir) - - supervisor, err := node.Setup(ctx, nodeConfig, tempDir) - s.Require().Nil(err) - - ready := make(chan struct{}, 1) - supervisorErr := make(chan error, 1) - go func() { - err := supervisor.Start(ctx, ready) - if err != nil { - supervisorErr <- err - } - }() - - select { - case err := <-supervisorErr: - s.Require().Nil(err) - case <-ready: - break - } - - // Configure Suite for tear down - s.containers = depsContainers - s.tempDir = tempDir - s.ctx = ctx - s.cancel = cancel - s.supervisorErr = supervisorErr - -} - -func (s *EchoInputTestSuite) TearDownTest() { - - // Stop Node services - s.cancel() - - // Remove temp files - os.RemoveAll(s.tempDir) - - // Terminate deps - ctx := context.Background() - err := deps.Terminate(ctx, s.containers) - s.Require().Nil(err) - -} - -func (s *EchoInputTestSuite) TestSendInput() { - - inputIndex, err := ethutil.AddInputUsingFoundryMnemonic(s.ctx, s.blockchainHttpEndpoint, payload) - s.Require().Nil(err) - - // Check input was correctly added to the blockchain - s.Require().Equal(0, inputIndex) - - // Get Input with vouchers and proofs - graphQlClient := graphql.NewClient(graphqlEndpoint, nil) - var input *readerclient.Input - attempts := 0 - for ; attempts < maxReadInputAttempts; attempts++ { - time.Sleep(2 * time.Second) - input, err = readerclient.GetInput(s.ctx, graphQlClient, inputIndex) - if err == nil && input.Status == "ACCEPTED" && - input.Vouchers != nil && input.Vouchers[0].Proof != nil && - input.Notices != nil && input.Notices[0].Proof != nil { - break - } - } - if attempts == maxReadInputAttempts { - select { - case err = <-s.supervisorErr: - s.Require().Nil(err) - break - case <-time.After(1 * time.Second): - s.Require().FailNow("Reached max read attempts") - } - } - - //Check Input - var expectedInput readerclient.Input - err = json.Unmarshal(expectedInputJsonBytes, &expectedInput) - s.Require().Nil(err) - s.Require().EqualValues(&expectedInput, input) - -} - -func TestEchoInput(t *testing.T) { - - suite.Run(t, new(EchoInputTestSuite)) -} diff --git a/test/tooling/db/db.go b/test/tooling/db/db.go index 61123d7c6..44db648f7 100644 --- a/test/tooling/db/db.go +++ b/test/tooling/db/db.go @@ -4,59 +4,22 @@ package db import ( - "context" + "fmt" "os" - "time" "github.com/cartesi/rollups-node/internal/repository/schema" - "github.com/testcontainers/testcontainers-go" - "github.com/testcontainers/testcontainers-go/modules/postgres" - "github.com/testcontainers/testcontainers-go/wait" ) -const ( - postgresImage = "postgres:16-alpine" - postgresDatabase = "cartesinode" - postgresUsername = "admin" - postgresPassword = "password" -) - -func Setup(ctx context.Context) (string, error) { - endpoint, ok := os.LookupEnv("TESTS_POSTGRES_ENDPOINT") +func GetPostgresTestEndpoint() (string, error) { + endpoint, ok := os.LookupEnv("CARTESI_TEST_POSTGRES_ENDPOINT") if !ok { - container, err := SetupContainer(ctx) - if err != nil { - return "", err - } - - endpoint, err = container.ConnectionString(ctx, "sslmode=disable") - if err != nil { - return "", err - } - } - - err := SetupSchema(endpoint) - if err != nil { - return "", err + return "", fmt.Errorf("environment variable CARTESI_TEST_POSTGRES_ENDPOINT not set") } - return endpoint, nil } -func SetupContainer(ctx context.Context) (*postgres.PostgresContainer, error) { - log := "database system is ready to accept connections" - occurrences := 2 //nolint: mnd - timeout := 10 * time.Second //nolint: mnd - strategy := wait.ForLog(log).WithOccurrence(occurrences).WithStartupTimeout(timeout) - return postgres.Run(ctx, - postgresImage, - postgres.WithDatabase(postgresDatabase), - postgres.WithUsername(postgresUsername), - postgres.WithPassword(postgresPassword), - testcontainers.WithWaitStrategy(strategy)) -} +func SetupTestPostgres(endpoint string) error { -func SetupSchema(endpoint string) error { schema, err := schema.New(endpoint) if err != nil { return err diff --git a/test/validator/validator_test.go b/test/validator/validator_test.go index 957c9368f..736190c39 100644 --- a/test/validator/validator_test.go +++ b/test/validator/validator_test.go @@ -5,18 +5,14 @@ package validator import ( "context" - "fmt" - "net/url" "testing" "time" - "github.com/cartesi/rollups-node/internal/deps" "github.com/cartesi/rollups-node/internal/merkle" "github.com/cartesi/rollups-node/internal/node/model" "github.com/cartesi/rollups-node/internal/repository" - "github.com/cartesi/rollups-node/internal/repository/schema" "github.com/cartesi/rollups-node/internal/validator" - "github.com/cartesi/rollups-node/pkg/testutil" + "github.com/cartesi/rollups-node/test/tooling/db" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/suite" @@ -26,13 +22,11 @@ const testTimeout = 300 * time.Second type ValidatorRepositoryIntegrationSuite struct { suite.Suite - ctx context.Context - cancel context.CancelFunc - containers *deps.DepsContainers - validator *validator.Validator - database *repository.Database - databaseURL *url.URL - schema *schema.Schema + ctx context.Context + cancel context.CancelFunc + validator *validator.Validator + database *repository.Database + postgresEndpoint string } func TestValidatorRepositoryIntegration(t *testing.T) { @@ -42,58 +36,35 @@ func TestValidatorRepositoryIntegration(t *testing.T) { func (s *ValidatorRepositoryIntegrationSuite) SetupSuite() { s.ctx, s.cancel = context.WithTimeout(context.Background(), testTimeout) - var depsConfig = deps.DepsConfig{ - Postgres: &deps.PostgresConfig{ - DockerImage: deps.DefaultPostgresDockerImage, - Port: testutil.GetCartesiTestDepsPortRange(), - Password: deps.DefaultPostgresPassword, - }, - } - var err error - s.containers, err = deps.Run(s.ctx, depsConfig) - s.Require().Nil(err) - // build database URL - postgresEndpoint, err := s.containers.PostgresEndpoint(s.ctx, "postgres") + s.postgresEndpoint, err = db.GetPostgresTestEndpoint() s.Require().Nil(err) - s.databaseURL, err = url.Parse(postgresEndpoint) + + err = db.SetupTestPostgres(s.postgresEndpoint) s.Require().Nil(err) - s.databaseURL.User = url.UserPassword(deps.DefaultPostgresUser, deps.DefaultPostgresPassword) - s.databaseURL = s.databaseURL.JoinPath(deps.DefaultPostgresDatabase) } func (s *ValidatorRepositoryIntegrationSuite) SetupSubTest() { var err error - s.database, err = repository.Connect(s.ctx, s.databaseURL.String()) - s.Require().Nil(err) - - s.schema, err = schema.New( - fmt.Sprintf("%v?sslmode=disable", s.databaseURL.String()), - ) + s.database, err = repository.Connect(s.ctx, s.postgresEndpoint) s.Require().Nil(err) s.validator = validator.NewValidator(s.database, 0) - err = s.schema.Upgrade() + err = db.SetupTestPostgres(s.postgresEndpoint) s.Require().Nil(err) } func (s *ValidatorRepositoryIntegrationSuite) TearDownSubTest() { s.validator = nil - err := s.schema.Downgrade() - s.Require().Nil(err) - s.schema.Close() - s.database.Close() } func (s *ValidatorRepositoryIntegrationSuite) TearDownSuite() { + // TODO reset database and anvil s.cancel() - - err := deps.Terminate(context.Background(), s.containers) - s.Require().Nil(err) } func (s *ValidatorRepositoryIntegrationSuite) TestItReturnsPristineClaim() { @@ -336,7 +307,7 @@ func (s *ValidatorRepositoryIntegrationSuite) TestItReturnsANewClaimAndProofs() firstEpoch.Id, err = s.database.InsertEpoch(s.ctx, firstEpoch) s.Require().Nil(err) - // update input with its epoch id and OuputsHash and insert it in the db + // update input with its epoch id and OutputsHash and insert it in the db firstInput.EpochId = firstEpoch.Id firstInput.OutputsHash = &firstEpochClaim firstInput.Id, err = s.database.InsertInput(s.ctx, firstInput)