diff --git a/.gitea/workflows/test.yml b/.gitea/workflows/test.yml new file mode 100644 index 0000000..a75ae67 --- /dev/null +++ b/.gitea/workflows/test.yml @@ -0,0 +1,134 @@ +name: Test + +on: + pull_request: + branches: '*' + push: + branches: + - main + +env: + # Needed until we can incorporate docker startup into the executor container + DOCKER_HOST: unix:///var/run/dind.sock + CANONICAL_VERSION: v5.0.4-alpha + +jobs: + tests: + name: Run unit and integration tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-go@v3 + with: + go-version-file: go.mod + check-latest: true + - name: Install test fixtures + uses: actions/checkout@v3 + with: + repository: cerc-io/eth-testing + path: ./fixtures + ref: v0.3.1 + - name: Configure Gitea access + env: + TOKEN: ${{ secrets.CICD_REPO_TOKEN }} + run: | + git config --global url."https://$TOKEN:@git.vdb.to/".insteadOf https://git.vdb.to/ + - name: Build package + run: go build . + - name: Run unit tests + run: make test + + - name: Run dockerd + run: | + dockerd -H $DOCKER_HOST --userland-proxy=false & + sleep 5 + - name: Run DB container + run: docker compose -f test/compose.yml up --wait + + # Run a sanity test against the fixture data + # Complete integration tests are TODO + - name: Run basic integration test + env: + SNAPSHOT_MODE: postgres + SNAPSHOT_BLOCK_HEIGHT: 32 + LEVELDB_PATH: ./fixtures/chaindata/_data/small + LEVELDB_ANCIENT: ./fixtures/chaindata/_data/small/ancient + ETH_GENESIS_BLOCK: "0x37cbb63c7150a7b60f2878433963ed8ba7e5f82fb2683ec7a945c974e1cf4e05" + run: | + until + ready_query='select max(version_id) from goose_db_version;' + version=$(docker exec -e PGPASSWORD=password test-ipld-eth-db-1 \ + psql -tA cerc_testing -U vdbm -c "$ready_query") + [[ "$version" -ge 18 ]] + do sleep 1; done + + ./ipld-eth-state-snapshot --config test/ci-config.toml stateSnapshot + + count_results() { + query="select count(*) from $1;" + docker exec -e PGPASSWORD=password test-ipld-eth-db-1 \ + psql -tA cerc_testing -U vdbm -c "$query" + } + set -x + [[ "$(count_results eth.header_cids)" = 1 ]] + [[ "$(count_results eth.state_cids)" = 5 ]] + [[ "$(count_results eth.storage_cids)" = 13 ]] + + compliance-test: + name: Run compliance tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + path: ./ipld-eth-state-snapshot + - uses: actions/setup-go@v3 + with: + go-version-file: ./ipld-eth-state-snapshot/go.mod + check-latest: true + - name: Install test fixtures + uses: actions/checkout@v3 + with: + repository: cerc-io/eth-testing + path: ./fixtures + ref: v0.3.1 + - name: Configure Gitea access + env: + TOKEN: ${{ secrets.CICD_REPO_TOKEN }} + run: | + git config --global url."https://$TOKEN:@git.vdb.to/".insteadOf https://git.vdb.to/ + - name: Build current version + working-directory: ./ipld-eth-state-snapshot + run: go build -o ../snapshot-current . + + - name: Checkout canonical version + uses: actions/checkout@v3 + with: + path: ./ipld-eth-state-snapshot-canonical + ref: ${{ env.CANONICAL_VERSION }} + - name: Build canonical version + working-directory: ./ipld-eth-state-snapshot-canonical + run: go build -o ../snapshot-canonical . + + - name: Run dockerd + run: | + dockerd -H $DOCKER_HOST --userland-proxy=false & + sleep 5 + - name: Run DB container + working-directory: ./ipld-eth-state-snapshot + run: docker compose -f test/compose.yml up --wait + - name: Compare snapshot output + env: + SNAPSHOT_BLOCK_HEIGHT: 200 + LEVELDB_PATH: ./fixtures/chaindata/_data/small2 + LEVELDB_ANCIENT: ./fixtures/chaindata/_data/small2/ancient + ETH_GENESIS_BLOCK: "0x8a3c7cddacbd1ab4ec1b03805fa2a287f3a75e43d87f4f987fcc399f5c042614" + run: | + until + ready_query='select max(version_id) from goose_db_version;' + version=$(docker exec -e PGPASSWORD=password test-ipld-eth-db-1 \ + psql -tA cerc_testing -U vdbm -c "$ready_query") + [[ "$version" -ge 18 ]] + do sleep 1; done + + ./ipld-eth-state-snapshot/scripts/compare-snapshots.sh \ + ./snapshot-canonical ./snapshot-current diff --git a/.github/workflows/on-pr.yaml b/.github/workflows/on-pr.yaml deleted file mode 100644 index e8e7b76..0000000 --- a/.github/workflows/on-pr.yaml +++ /dev/null @@ -1,30 +0,0 @@ -name: Docker Build - -on: [pull_request] - -jobs: - test: - name: Run unit tests - runs-on: ubuntu-latest - env: - GOPATH: /tmp/go - GO111MODULE: on - steps: - - name: Create GOPATH - run: mkdir -p /tmp/go - - - uses: actions/setup-go@v3 - with: - go-version: ">=1.19.0" - check-latest: true - - - name: Checkout code - uses: actions/checkout@v2 - - - name: Run database - run: docker-compose up -d - - - name: Run unit tests - run: | - sleep 45 - make dbtest diff --git a/.gitignore b/.gitignore index c678610..9a81394 100644 --- a/.gitignore +++ b/.gitignore @@ -1,8 +1,6 @@ .idea/ .vscode/ ipld-eth-state-snapshot -mocks/ -.vscode output_dir*/ log_file recovery_file diff --git a/Dockerfile b/Dockerfile index 394690e..5178bf3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,27 +1,31 @@ FROM golang:1.20-alpine as builder -RUN apk --update --no-cache add make git g++ linux-headers +RUN apk add --no-cache git gcc musl-dev binutils-gold # DEBUG RUN apk add busybox-extras -# Get and build ipfs-blockchain-watcher -ADD . /go/src/github.com/cerc-io/ipld-eth-state-snapshot -#RUN git clone https://github.com/cerc-io/ipld-eth-state-snapshot.git /go/src/github.com/vulcanize/ipld-eth-state-snapshot +WORKDIR /ipld-eth-state-snapshot -WORKDIR /go/src/github.com/cerc-io/ipld-eth-state-snapshot -RUN GO111MODULE=on GCO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o ipld-eth-state-snapshot . +ARG GIT_VDBTO_TOKEN + +COPY go.mod go.sum ./ +RUN if [ -n "$GIT_VDBTO_TOKEN" ]; then git config --global url."https://$GIT_VDBTO_TOKEN:@git.vdb.to/".insteadOf "https://git.vdb.to/"; fi && \ + go mod download && \ + rm -f ~/.gitconfig +COPY . . + +RUN go build -ldflags '-extldflags "-static"' -o ipld-eth-state-snapshot . -# app container FROM alpine RUN apk --no-cache add su-exec bash WORKDIR /app -COPY --from=builder /go/src/github.com/cerc-io/ipld-eth-state-snapshot/startup_script.sh . -COPY --from=builder /go/src/github.com/cerc-io/ipld-eth-state-snapshot/environments environments +COPY --from=builder /ipld-eth-state-snapshot/startup_script.sh . +COPY --from=builder /ipld-eth-state-snapshot/environments environments # keep binaries immutable -COPY --from=builder /go/src/github.com/cerc-io/ipld-eth-state-snapshot/ipld-eth-state-snapshot ipld-eth-state-snapshot +COPY --from=builder /ipld-eth-state-snapshot/ipld-eth-state-snapshot ipld-eth-state-snapshot ENTRYPOINT ["/app/startup_script.sh"] diff --git a/Makefile b/Makefile index 69dfd00..272e88f 100644 --- a/Makefile +++ b/Makefile @@ -1,28 +1,13 @@ -BIN = $(GOPATH)/bin +MOCKGEN ?= mockgen +MOCKS_DIR := $(CURDIR)/internal/mocks -## Mockgen tool -MOCKGEN = $(BIN)/mockgen -$(BIN)/mockgen: - go install github.com/golang/mock/mockgen@v1.6.0 +mocks: $(MOCKS_DIR)/gen_indexer.go +.PHONY: mocks -MOCKS_DIR = $(CURDIR)/mocks - -.PHONY: mocks test - -mocks: $(MOCKGEN) mocks/snapshot/publisher.go - -mocks/snapshot/publisher.go: pkg/types/publisher.go - $(MOCKGEN) -package snapshot_mock -destination $@ -source $< Publisher Tx - -clean: - rm -f mocks/snapshot/publisher.go - -build: - go fmt ./... - go build +$(MOCKS_DIR)/gen_indexer.go: + $(MOCKGEN) --package mocks --destination $@ \ + --mock_names Indexer=MockgenIndexer \ + github.com/cerc-io/plugeth-statediff/indexer Indexer test: mocks go clean -testcache && go test -p 1 -v ./... - -dbtest: mocks - go clean -testcache && TEST_WITH_DB=true go test -p 1 -v ./... diff --git a/README.md b/README.md index d15e880..7b4ceb7 100644 --- a/README.md +++ b/README.md @@ -19,16 +19,16 @@ Config format: ```toml [snapshot] mode = "file" # indicates output mode - workers = 4 # degree of concurrency, the state trie is subdivided into sections that are traversed and processed concurrently + workers = 4 # degree of concurrency: the state trie is subdivided into sections that are traversed and processed concurrently blockHeight = -1 # blockheight to perform the snapshot at (-1 indicates to use the latest blockheight found in leveldb) recoveryFile = "recovery_file" # specifies a file to output recovery information on error or premature closure accounts = [] # list of accounts (addresses) to take the snapshot for # SNAPSHOT_ACCOUNTS [leveldb] # path to geth leveldb - path = "/Users/user/Library/Ethereum/geth/chaindata" # LVL_DB_PATH + path = "/Users/user/Library/Ethereum/geth/chaindata" # LEVELDB_PATH # path to geth ancient database - ancient = "/Users/user/Library/Ethereum/geth/chaindata/ancient" # ANCIENT_DB_PATH + ancient = "/Users/user/Library/Ethereum/geth/chaindata/ancient" # LEVELDB_ANCIENT [database] # when operating in 'postgres' output mode @@ -65,6 +65,12 @@ Config format: genesisBlock = "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3" # ETH_GENESIS_BLOCK ``` +> **Note:** previous versions of this service used different variable names. To update, change the following: +> * `LVL_DB_PATH` => `LEVELDB_PATH` +> * `ANCIENT_DB_PATH` => `LEVELDB_ANCIENT` +> * `LOGRUS_LEVEL`, `LOGRUS_FILE` => `LOG_LEVEL`, `LOG_FILE`, etc. + + ## Usage * For state snapshot from LevelDB: @@ -125,8 +131,8 @@ Config format: * Combine output from multiple workers and copy to post-processed output directory: ```bash - # public.blocks - cat {output_dir,output_dir/*}/public.blocks.csv > output_dir/processed_output/combined-public.blocks.csv + # ipld.blocks + cat {output_dir,output_dir/*}/ipld.blocks.csv > output_dir/processed_output/combined-ipld.blocks.csv # eth.state_cids cat output_dir/*/eth.state_cids.csv > output_dir/processed_output/combined-eth.state_cids.csv @@ -144,8 +150,8 @@ Config format: * De-duplicate data: ```bash - # public.blocks - sort -u output_dir/processed_output/combined-public.blocks.csv -o output_dir/processed_output/deduped-combined-public.blocks.csv + # ipld.blocks + sort -u output_dir/processed_output/combined-ipld.blocks.csv -o output_dir/processed_output/deduped-combined-ipld.blocks.csv # eth.header_cids sort -u output_dir/processed_output/eth.header_cids.csv -o output_dir/processed_output/deduped-eth.header_cids.csv @@ -171,8 +177,8 @@ Config format: # public.nodes COPY public.nodes FROM '/output_dir/processed_output/public.nodes.csv' CSV; - # public.blocks - COPY public.blocks FROM '/output_dir/processed_output/deduped-combined-public.blocks.csv' CSV; + # ipld.blocks + COPY ipld.blocks FROM '/output_dir/processed_output/deduped-combined-ipld.blocks.csv' CSV; # eth.header_cids COPY eth.header_cids FROM '/output_dir/processed_output/deduped-eth.header_cids.csv' CSV; diff --git a/cmd/root.go b/cmd/root.go index 92bcd26..4d414b1 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -42,14 +42,13 @@ var rootCmd = &cobra.Command{ // Execute executes root Command. func Execute() { - log.Info("----- Starting vDB -----") if err := rootCmd.Execute(); err != nil { log.Fatal(err) } } func initFuncs(cmd *cobra.Command, args []string) { - logfile := viper.GetString(snapshot.LOGRUS_FILE_TOML) + logfile := viper.GetString(snapshot.LOG_FILE_TOML) if logfile != "" { file, err := os.OpenFile(logfile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) @@ -68,7 +67,7 @@ func initFuncs(cmd *cobra.Command, args []string) { } if viper.GetBool(snapshot.PROM_METRICS_TOML) { - log.Info("initializing prometheus metrics") + log.Info("Initializing prometheus metrics") prom.Init() } @@ -84,7 +83,7 @@ func initFuncs(cmd *cobra.Command, args []string) { } func logLevel() error { - lvl, err := log.ParseLevel(viper.GetString(snapshot.LOGRUS_LEVEL_TOML)) + lvl, err := log.ParseLevel(viper.GetString(snapshot.LOG_LEVEL_TOML)) if err != nil { return err } @@ -103,13 +102,13 @@ func init() { viper.AutomaticEnv() rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file location") - rootCmd.PersistentFlags().String(snapshot.LOGRUS_FILE_CLI, "", "file path for logging") + rootCmd.PersistentFlags().String(snapshot.LOG_FILE_CLI, "", "file path for logging") rootCmd.PersistentFlags().String(snapshot.DATABASE_NAME_CLI, "vulcanize_public", "database name") rootCmd.PersistentFlags().Int(snapshot.DATABASE_PORT_CLI, 5432, "database port") rootCmd.PersistentFlags().String(snapshot.DATABASE_HOSTNAME_CLI, "localhost", "database hostname") rootCmd.PersistentFlags().String(snapshot.DATABASE_USER_CLI, "", "database user") rootCmd.PersistentFlags().String(snapshot.DATABASE_PASSWORD_CLI, "", "database password") - rootCmd.PersistentFlags().String(snapshot.LOGRUS_LEVEL_CLI, log.InfoLevel.String(), "log level (trace, debug, info, warn, error, fatal, panic)") + rootCmd.PersistentFlags().String(snapshot.LOG_LEVEL_CLI, log.InfoLevel.String(), "log level (trace, debug, info, warn, error, fatal, panic)") rootCmd.PersistentFlags().Bool(snapshot.PROM_METRICS_CLI, false, "enable prometheus metrics") rootCmd.PersistentFlags().Bool(snapshot.PROM_HTTP_CLI, false, "enable prometheus http service") @@ -117,13 +116,13 @@ func init() { rootCmd.PersistentFlags().String(snapshot.PROM_HTTP_PORT_CLI, "8086", "prometheus http port") rootCmd.PersistentFlags().Bool(snapshot.PROM_DB_STATS_CLI, false, "enables prometheus db stats") - viper.BindPFlag(snapshot.LOGRUS_FILE_TOML, rootCmd.PersistentFlags().Lookup(snapshot.LOGRUS_FILE_CLI)) + viper.BindPFlag(snapshot.LOG_FILE_TOML, rootCmd.PersistentFlags().Lookup(snapshot.LOG_FILE_CLI)) viper.BindPFlag(snapshot.DATABASE_NAME_TOML, rootCmd.PersistentFlags().Lookup(snapshot.DATABASE_NAME_CLI)) viper.BindPFlag(snapshot.DATABASE_PORT_TOML, rootCmd.PersistentFlags().Lookup(snapshot.DATABASE_PORT_CLI)) viper.BindPFlag(snapshot.DATABASE_HOSTNAME_TOML, rootCmd.PersistentFlags().Lookup(snapshot.DATABASE_HOSTNAME_CLI)) viper.BindPFlag(snapshot.DATABASE_USER_TOML, rootCmd.PersistentFlags().Lookup(snapshot.DATABASE_USER_CLI)) viper.BindPFlag(snapshot.DATABASE_PASSWORD_TOML, rootCmd.PersistentFlags().Lookup(snapshot.DATABASE_PASSWORD_CLI)) - viper.BindPFlag(snapshot.LOGRUS_LEVEL_TOML, rootCmd.PersistentFlags().Lookup(snapshot.LOGRUS_LEVEL_CLI)) + viper.BindPFlag(snapshot.LOG_LEVEL_TOML, rootCmd.PersistentFlags().Lookup(snapshot.LOG_LEVEL_CLI)) viper.BindPFlag(snapshot.PROM_METRICS_TOML, rootCmd.PersistentFlags().Lookup(snapshot.PROM_METRICS_CLI)) viper.BindPFlag(snapshot.PROM_HTTP_TOML, rootCmd.PersistentFlags().Lookup(snapshot.PROM_HTTP_CLI)) @@ -138,7 +137,7 @@ func initConfig() { if err := viper.ReadInConfig(); err == nil { log.Printf("Using config file: %s", viper.ConfigFileUsed()) } else { - log.Fatal(fmt.Sprintf("Couldn't read config file: %s", err.Error())) + log.Fatalf("Couldn't read config file: %s", err) } } else { log.Warn("No config file passed with --config flag") diff --git a/cmd/stateSnapshot.go b/cmd/stateSnapshot.go index f9553ef..ef7ac45 100644 --- a/cmd/stateSnapshot.go +++ b/cmd/stateSnapshot.go @@ -16,6 +16,7 @@ package cmd import ( + "context" "fmt" "github.com/sirupsen/logrus" @@ -23,6 +24,7 @@ import ( "github.com/spf13/viper" "github.com/cerc-io/ipld-eth-state-snapshot/pkg/snapshot" + "github.com/cerc-io/plugeth-statediff/indexer" ) // stateSnapshotCmd represents the stateSnapshot command @@ -40,8 +42,7 @@ var stateSnapshotCmd = &cobra.Command{ } func stateSnapshot() { - modeStr := viper.GetString(snapshot.SNAPSHOT_MODE_TOML) - mode := snapshot.SnapshotMode(modeStr) + mode := snapshot.SnapshotMode(viper.GetString(snapshot.SNAPSHOT_MODE_TOML)) config, err := snapshot.NewConfig(mode) if err != nil { logWithCommand.Fatalf("unable to initialize config: %v", err) @@ -59,12 +60,25 @@ func stateSnapshot() { logWithCommand.Infof("no recovery file set, using default: %s", recoveryFile) } - pub, err := snapshot.NewPublisher(mode, config) + var idxconfig indexer.Config + switch mode { + case snapshot.PgSnapshot: + idxconfig = *config.DB + case snapshot.FileSnapshot: + idxconfig = *config.File + } + _, indexer, err := indexer.NewStateDiffIndexer( + context.Background(), + nil, // ChainConfig is only used in PushBlock, which we don't call + config.Eth.NodeInfo, + idxconfig, + false, + ) if err != nil { logWithCommand.Fatal(err) } - snapshotService, err := snapshot.NewSnapshotService(edb, pub, recoveryFile) + snapshotService, err := snapshot.NewSnapshotService(edb, indexer, recoveryFile) if err != nil { logWithCommand.Fatal(err) } @@ -79,14 +93,14 @@ func stateSnapshot() { logWithCommand.Fatal(err) } } - logWithCommand.Infof("state snapshot at height %d is complete", height) + logWithCommand.Infof("State snapshot at height %d is complete", height) } func init() { rootCmd.AddCommand(stateSnapshotCmd) - stateSnapshotCmd.PersistentFlags().String(snapshot.LVL_DB_PATH_CLI, "", "path to primary datastore") - stateSnapshotCmd.PersistentFlags().String(snapshot.ANCIENT_DB_PATH_CLI, "", "path to ancient datastore") + stateSnapshotCmd.PersistentFlags().String(snapshot.LEVELDB_PATH_CLI, "", "path to primary datastore") + stateSnapshotCmd.PersistentFlags().String(snapshot.LEVELDB_ANCIENT_CLI, "", "path to ancient datastore") stateSnapshotCmd.PersistentFlags().String(snapshot.SNAPSHOT_BLOCK_HEIGHT_CLI, "", "block height to extract state at") stateSnapshotCmd.PersistentFlags().Int(snapshot.SNAPSHOT_WORKERS_CLI, 1, "number of concurrent workers to use") stateSnapshotCmd.PersistentFlags().String(snapshot.SNAPSHOT_RECOVERY_FILE_CLI, "", "file to recover from a previous iteration") @@ -94,8 +108,8 @@ func init() { stateSnapshotCmd.PersistentFlags().String(snapshot.FILE_OUTPUT_DIR_CLI, "", "directory for writing ouput to while operating in 'file' mode") stateSnapshotCmd.PersistentFlags().StringArray(snapshot.SNAPSHOT_ACCOUNTS_CLI, nil, "list of account addresses to limit snapshot to") - viper.BindPFlag(snapshot.LVL_DB_PATH_TOML, stateSnapshotCmd.PersistentFlags().Lookup(snapshot.LVL_DB_PATH_CLI)) - viper.BindPFlag(snapshot.ANCIENT_DB_PATH_TOML, stateSnapshotCmd.PersistentFlags().Lookup(snapshot.ANCIENT_DB_PATH_CLI)) + viper.BindPFlag(snapshot.LEVELDB_PATH_TOML, stateSnapshotCmd.PersistentFlags().Lookup(snapshot.LEVELDB_PATH_CLI)) + viper.BindPFlag(snapshot.LEVELDB_ANCIENT_TOML, stateSnapshotCmd.PersistentFlags().Lookup(snapshot.LEVELDB_ANCIENT_CLI)) viper.BindPFlag(snapshot.SNAPSHOT_BLOCK_HEIGHT_TOML, stateSnapshotCmd.PersistentFlags().Lookup(snapshot.SNAPSHOT_BLOCK_HEIGHT_CLI)) viper.BindPFlag(snapshot.SNAPSHOT_WORKERS_TOML, stateSnapshotCmd.PersistentFlags().Lookup(snapshot.SNAPSHOT_WORKERS_CLI)) viper.BindPFlag(snapshot.SNAPSHOT_RECOVERY_FILE_TOML, stateSnapshotCmd.PersistentFlags().Lookup(snapshot.SNAPSHOT_RECOVERY_FILE_CLI)) diff --git a/db/migrations/00001_create_ipfs_blocks_table.sql b/db/migrations/00001_create_ipfs_blocks_table.sql deleted file mode 100644 index 6e3941e..0000000 --- a/db/migrations/00001_create_ipfs_blocks_table.sql +++ /dev/null @@ -1,8 +0,0 @@ --- +goose Up -CREATE TABLE IF NOT EXISTS public.blocks ( - key TEXT UNIQUE NOT NULL, - data BYTEA NOT NULL -); - --- +goose Down -DROP TABLE public.blocks; diff --git a/db/migrations/00002_create_nodes_table.sql b/db/migrations/00002_create_nodes_table.sql deleted file mode 100644 index 76db3d7..0000000 --- a/db/migrations/00002_create_nodes_table.sql +++ /dev/null @@ -1,12 +0,0 @@ --- +goose Up -CREATE TABLE nodes ( - id SERIAL PRIMARY KEY, - client_name VARCHAR, - genesis_block VARCHAR(66), - network_id VARCHAR, - node_id VARCHAR(128), - CONSTRAINT node_uc UNIQUE (genesis_block, network_id, node_id) -); - --- +goose Down -DROP TABLE nodes; diff --git a/db/migrations/00003_create_eth_schema.sql b/db/migrations/00003_create_eth_schema.sql deleted file mode 100644 index 84d6f4b..0000000 --- a/db/migrations/00003_create_eth_schema.sql +++ /dev/null @@ -1,5 +0,0 @@ --- +goose Up -CREATE SCHEMA eth; - --- +goose Down -DROP SCHEMA eth; \ No newline at end of file diff --git a/db/migrations/00004_create_eth_header_cids_table.sql b/db/migrations/00004_create_eth_header_cids_table.sql deleted file mode 100644 index 339eb42..0000000 --- a/db/migrations/00004_create_eth_header_cids_table.sql +++ /dev/null @@ -1,23 +0,0 @@ --- +goose Up -CREATE TABLE eth.header_cids ( - id SERIAL PRIMARY KEY, - block_number BIGINT NOT NULL, - block_hash VARCHAR(66) NOT NULL, - parent_hash VARCHAR(66) NOT NULL, - cid TEXT NOT NULL, - mh_key TEXT NOT NULL REFERENCES public.blocks (key) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - td NUMERIC NOT NULL, - node_id INTEGER NOT NULL REFERENCES nodes (id) ON DELETE CASCADE, - reward NUMERIC NOT NULL, - state_root VARCHAR(66) NOT NULL, - tx_root VARCHAR(66) NOT NULL, - receipt_root VARCHAR(66) NOT NULL, - uncle_root VARCHAR(66) NOT NULL, - bloom BYTEA NOT NULL, - timestamp NUMERIC NOT NULL, - times_validated INTEGER NOT NULL DEFAULT 1, - UNIQUE (block_number, block_hash) -); - --- +goose Down -DROP TABLE eth.header_cids; \ No newline at end of file diff --git a/db/migrations/00005_create_eth_uncle_cids_table.sql b/db/migrations/00005_create_eth_uncle_cids_table.sql deleted file mode 100644 index c46cafb..0000000 --- a/db/migrations/00005_create_eth_uncle_cids_table.sql +++ /dev/null @@ -1,14 +0,0 @@ --- +goose Up -CREATE TABLE eth.uncle_cids ( - id SERIAL PRIMARY KEY, - header_id INTEGER NOT NULL REFERENCES eth.header_cids (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - block_hash VARCHAR(66) NOT NULL, - parent_hash VARCHAR(66) NOT NULL, - cid TEXT NOT NULL, - mh_key TEXT NOT NULL REFERENCES public.blocks (key) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - reward NUMERIC NOT NULL, - UNIQUE (header_id, block_hash) -); - --- +goose Down -DROP TABLE eth.uncle_cids; \ No newline at end of file diff --git a/db/migrations/00006_create_eth_transaction_cids_table.sql b/db/migrations/00006_create_eth_transaction_cids_table.sql deleted file mode 100644 index cbbef78..0000000 --- a/db/migrations/00006_create_eth_transaction_cids_table.sql +++ /dev/null @@ -1,15 +0,0 @@ --- +goose Up -CREATE TABLE eth.transaction_cids ( - id SERIAL PRIMARY KEY, - header_id INTEGER NOT NULL REFERENCES eth.header_cids (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - tx_hash VARCHAR(66) NOT NULL, - index INTEGER NOT NULL, - cid TEXT NOT NULL, - mh_key TEXT NOT NULL REFERENCES public.blocks (key) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - dst VARCHAR(66) NOT NULL, - src VARCHAR(66) NOT NULL, - UNIQUE (header_id, tx_hash) -); - --- +goose Down -DROP TABLE eth.transaction_cids; diff --git a/db/migrations/00007_create_eth_receipt_cids_table.sql b/db/migrations/00007_create_eth_receipt_cids_table.sql deleted file mode 100644 index 5d4ae0c..0000000 --- a/db/migrations/00007_create_eth_receipt_cids_table.sql +++ /dev/null @@ -1,18 +0,0 @@ --- +goose Up -CREATE TABLE eth.receipt_cids ( - id SERIAL PRIMARY KEY, - tx_id INTEGER NOT NULL REFERENCES eth.transaction_cids (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - cid TEXT NOT NULL, - mh_key TEXT NOT NULL REFERENCES public.blocks (key) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - contract VARCHAR(66), - contract_hash VARCHAR(66), - topic0s VARCHAR(66)[], - topic1s VARCHAR(66)[], - topic2s VARCHAR(66)[], - topic3s VARCHAR(66)[], - log_contracts VARCHAR(66)[], - UNIQUE (tx_id) -); - --- +goose Down -DROP TABLE eth.receipt_cids; \ No newline at end of file diff --git a/db/migrations/00008_create_eth_state_cids_table.sql b/db/migrations/00008_create_eth_state_cids_table.sql deleted file mode 100644 index e0bf6e5..0000000 --- a/db/migrations/00008_create_eth_state_cids_table.sql +++ /dev/null @@ -1,15 +0,0 @@ --- +goose Up -CREATE TABLE eth.state_cids ( - id SERIAL PRIMARY KEY, - header_id INTEGER NOT NULL REFERENCES eth.header_cids (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - state_leaf_key VARCHAR(66), - cid TEXT NOT NULL, - mh_key TEXT NOT NULL REFERENCES public.blocks (key) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - state_path BYTEA, - node_type INTEGER, - diff BOOLEAN NOT NULL DEFAULT FALSE, - UNIQUE (header_id, state_path) -); - --- +goose Down -DROP TABLE eth.state_cids; \ No newline at end of file diff --git a/db/migrations/00009_create_eth_storage_cids_table.sql b/db/migrations/00009_create_eth_storage_cids_table.sql deleted file mode 100644 index 944d39e..0000000 --- a/db/migrations/00009_create_eth_storage_cids_table.sql +++ /dev/null @@ -1,15 +0,0 @@ --- +goose Up -CREATE TABLE eth.storage_cids ( - id SERIAL PRIMARY KEY, - state_id INTEGER NOT NULL REFERENCES eth.state_cids (id) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - storage_leaf_key VARCHAR(66), - cid TEXT NOT NULL, - mh_key TEXT NOT NULL REFERENCES public.blocks (key) ON DELETE CASCADE DEFERRABLE INITIALLY DEFERRED, - storage_path BYTEA, - node_type INTEGER NOT NULL, - diff BOOLEAN NOT NULL DEFAULT FALSE, - UNIQUE (state_id, storage_path) -); - --- +goose Down -DROP TABLE eth.storage_cids; \ No newline at end of file diff --git a/db/migrations/00010_create_eth_state_accouts_table.sql b/db/migrations/00010_create_eth_state_accouts_table.sql deleted file mode 100644 index 322d948..0000000 --- a/db/migrations/00010_create_eth_state_accouts_table.sql +++ /dev/null @@ -1,13 +0,0 @@ --- +goose Up -CREATE TABLE eth.state_accounts ( - id SERIAL PRIMARY KEY, - state_id INTEGER NOT NULL REFERENCES eth.state_cids (id) ON DELETE CASCADE, - balance NUMERIC NOT NULL, - nonce INTEGER NOT NULL, - code_hash BYTEA NOT NULL, - storage_root VARCHAR(66) NOT NULL, - UNIQUE (state_id) -); - --- +goose Down -DROP TABLE eth.state_accounts; \ No newline at end of file diff --git a/environments/example.toml b/environments/example.toml index 5eb8f36..91f4858 100644 --- a/environments/example.toml +++ b/environments/example.toml @@ -11,7 +11,7 @@ [log] level = "info" - file = "log_file" + file = "" # Leave blank to output to stdout [prom] metrics = true @@ -26,9 +26,6 @@ blockHeight = 32 recoveryFile = "recovery_file" - startHeight = 1 - endHeight = 12 - [file] outputDir = "output_dir/" diff --git a/fixture/.gitignore b/fixture/.gitignore deleted file mode 100644 index 7c4ab7e..0000000 --- a/fixture/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -*/*.log -*/CURRENT* -*/LOCK -*/LOG -*/MANIFEST-* -*/ancient/FLOCK -*/ancient/*.meta diff --git a/fixture/chain2data/000002.ldb b/fixture/chain2data/000002.ldb deleted file mode 100644 index c7bb1f9..0000000 Binary files a/fixture/chain2data/000002.ldb and /dev/null differ diff --git a/fixture/chain2data/000004.ldb b/fixture/chain2data/000004.ldb deleted file mode 100644 index bdea3f6..0000000 Binary files a/fixture/chain2data/000004.ldb and /dev/null differ diff --git a/fixture/chain2data/000006.log b/fixture/chain2data/000006.log deleted file mode 100644 index e69de29..0000000 diff --git a/fixture/chain2data/CURRENT b/fixture/chain2data/CURRENT deleted file mode 100644 index aa5bb8e..0000000 --- a/fixture/chain2data/CURRENT +++ /dev/null @@ -1 +0,0 @@ -MANIFEST-000005 diff --git a/fixture/chain2data/LOCK b/fixture/chain2data/LOCK deleted file mode 100644 index e69de29..0000000 diff --git a/fixture/chain2data/LOG b/fixture/chain2data/LOG deleted file mode 100644 index 9a1434b..0000000 --- a/fixture/chain2data/LOG +++ /dev/null @@ -1,15 +0,0 @@ -=============== Mar 31, 2023 (CDT) =============== -12:22:01.281499 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed -12:22:01.281586 table@recovery F·2 -12:22:01.281592 table@recovery recovering @2 -12:22:01.281901 table@recovery recovered @2 Gk·13 Ck·0 Cb·0 S·918 Q·13 -12:22:01.281909 table@recovery recovering @4 -12:22:01.282725 table@recovery recovered @4 Gk·416 Ck·0 Cb·0 S·35872 Q·430 -12:22:01.282737 table@recovery recovered F·2 N·429 Gk·429 Ck·0 Q·430 -12:22:01.298688 version@stat F·[2] S·35KiB[35KiB] Sc·[0.50] -12:22:01.308338 db@open opening -12:22:01.308738 version@stat F·[2] S·35KiB[35KiB] Sc·[0.50] -12:22:01.314746 db@janitor F·4 G·0 -12:22:01.314778 db@open done T·6.427167ms -12:22:01.317510 db@close closing -12:22:01.317545 db@close done T·34.833µs diff --git a/fixture/chain2data/MANIFEST-000005 b/fixture/chain2data/MANIFEST-000005 deleted file mode 100644 index 71a995b..0000000 Binary files a/fixture/chain2data/MANIFEST-000005 and /dev/null differ diff --git a/fixture/chain2data/ancient/FLOCK b/fixture/chain2data/ancient/FLOCK deleted file mode 100644 index e69de29..0000000 diff --git a/fixture/chain2data/ancient/bodies.0000.cdat b/fixture/chain2data/ancient/bodies.0000.cdat deleted file mode 100644 index e69de29..0000000 diff --git a/fixture/chain2data/ancient/bodies.cidx b/fixture/chain2data/ancient/bodies.cidx deleted file mode 100644 index ab2c684..0000000 Binary files a/fixture/chain2data/ancient/bodies.cidx and /dev/null differ diff --git a/fixture/chain2data/ancient/bodies.meta b/fixture/chain2data/ancient/bodies.meta deleted file mode 100644 index 59ee616..0000000 --- a/fixture/chain2data/ancient/bodies.meta +++ /dev/null @@ -1 +0,0 @@ -€ \ No newline at end of file diff --git a/fixture/chain2data/ancient/diffs.0000.rdat b/fixture/chain2data/ancient/diffs.0000.rdat deleted file mode 100644 index e69de29..0000000 diff --git a/fixture/chain2data/ancient/diffs.meta b/fixture/chain2data/ancient/diffs.meta deleted file mode 100644 index 59ee616..0000000 --- a/fixture/chain2data/ancient/diffs.meta +++ /dev/null @@ -1 +0,0 @@ -€ \ No newline at end of file diff --git a/fixture/chain2data/ancient/diffs.ridx b/fixture/chain2data/ancient/diffs.ridx deleted file mode 100644 index ab2c684..0000000 Binary files a/fixture/chain2data/ancient/diffs.ridx and /dev/null differ diff --git a/fixture/chain2data/ancient/hashes.0000.rdat b/fixture/chain2data/ancient/hashes.0000.rdat deleted file mode 100644 index e69de29..0000000 diff --git a/fixture/chain2data/ancient/hashes.meta b/fixture/chain2data/ancient/hashes.meta deleted file mode 100644 index 59ee616..0000000 --- a/fixture/chain2data/ancient/hashes.meta +++ /dev/null @@ -1 +0,0 @@ -€ \ No newline at end of file diff --git a/fixture/chain2data/ancient/hashes.ridx b/fixture/chain2data/ancient/hashes.ridx deleted file mode 100644 index ab2c684..0000000 Binary files a/fixture/chain2data/ancient/hashes.ridx and /dev/null differ diff --git a/fixture/chain2data/ancient/headers.0000.cdat b/fixture/chain2data/ancient/headers.0000.cdat deleted file mode 100644 index e69de29..0000000 diff --git a/fixture/chain2data/ancient/headers.cidx b/fixture/chain2data/ancient/headers.cidx deleted file mode 100644 index ab2c684..0000000 Binary files a/fixture/chain2data/ancient/headers.cidx and /dev/null differ diff --git a/fixture/chain2data/ancient/headers.meta b/fixture/chain2data/ancient/headers.meta deleted file mode 100644 index 59ee616..0000000 --- a/fixture/chain2data/ancient/headers.meta +++ /dev/null @@ -1 +0,0 @@ -€ \ No newline at end of file diff --git a/fixture/chain2data/ancient/receipts.0000.cdat b/fixture/chain2data/ancient/receipts.0000.cdat deleted file mode 100644 index e69de29..0000000 diff --git a/fixture/chain2data/ancient/receipts.cidx b/fixture/chain2data/ancient/receipts.cidx deleted file mode 100644 index ab2c684..0000000 Binary files a/fixture/chain2data/ancient/receipts.cidx and /dev/null differ diff --git a/fixture/chain2data/ancient/receipts.meta b/fixture/chain2data/ancient/receipts.meta deleted file mode 100644 index 59ee616..0000000 --- a/fixture/chain2data/ancient/receipts.meta +++ /dev/null @@ -1 +0,0 @@ -€ \ No newline at end of file diff --git a/fixture/chaindata.go b/fixture/chaindata.go deleted file mode 100644 index 991b17e..0000000 --- a/fixture/chaindata.go +++ /dev/null @@ -1,27 +0,0 @@ -package fixture - -import ( - "os" - "path/filepath" -) - -// TODO: embed some mainnet data -// import "embed" -//_go:embed mainnet_data.tar.gz - -// GetChainDataPath returns the absolute paths to chain data in 'fixture/' given the chain (chain | chain2) -func GetChainDataPath(chain string) (string, string) { - path := filepath.Join("..", "..", "fixture", chain) - - chaindataPath, err := filepath.Abs(path) - if err != nil { - panic("cannot resolve path " + path) - } - ancientdataPath := filepath.Join(chaindataPath, "ancient") - - if _, err := os.Stat(chaindataPath); err != nil { - panic("must populate chaindata at " + chaindataPath) - } - - return chaindataPath, ancientdataPath -} diff --git a/fixture/chaindata/000002.ldb b/fixture/chaindata/000002.ldb deleted file mode 100644 index 8e5331a..0000000 Binary files a/fixture/chaindata/000002.ldb and /dev/null differ diff --git a/fixture/chaindata/000004.log b/fixture/chaindata/000004.log deleted file mode 100644 index e69de29..0000000 diff --git a/fixture/chaindata/CURRENT b/fixture/chaindata/CURRENT deleted file mode 100644 index 4fb1dad..0000000 --- a/fixture/chaindata/CURRENT +++ /dev/null @@ -1 +0,0 @@ -MANIFEST-000003 diff --git a/fixture/chaindata/LOCK b/fixture/chaindata/LOCK deleted file mode 100644 index e69de29..0000000 diff --git a/fixture/chaindata/LOG b/fixture/chaindata/LOG deleted file mode 100644 index 76eb743..0000000 --- a/fixture/chaindata/LOG +++ /dev/null @@ -1,13 +0,0 @@ -=============== Mar 31, 2023 (CDT) =============== -12:22:01.090151 log@legend F·NumFile S·FileSize N·Entry C·BadEntry B·BadBlock Ke·KeyError D·DroppedEntry L·Level Q·SeqNum T·TimeElapsed -12:22:01.090565 table@recovery F·1 -12:22:01.090576 table@recovery recovering @2 -12:22:01.106640 table@recovery recovered @2 Gk·146827 Ck·0 Cb·0 S·5765300 Q·146827 -12:22:01.106661 table@recovery recovered F·1 N·146827 Gk·146827 Ck·0 Q·146827 -12:22:01.133566 version@stat F·[1] S·5MiB[5MiB] Sc·[0.25] -12:22:01.145740 db@open opening -12:22:01.146636 version@stat F·[1] S·5MiB[5MiB] Sc·[0.25] -12:22:01.151049 db@janitor F·3 G·0 -12:22:01.151090 db@open done T·5.315792ms -12:22:01.161329 db@close closing -12:22:01.161389 db@close done T·58.667µs diff --git a/fixture/chaindata/MANIFEST-000003 b/fixture/chaindata/MANIFEST-000003 deleted file mode 100644 index 5c352ab..0000000 Binary files a/fixture/chaindata/MANIFEST-000003 and /dev/null differ diff --git a/fixture/chaindata/ancient/FLOCK b/fixture/chaindata/ancient/FLOCK deleted file mode 100644 index e69de29..0000000 diff --git a/fixture/chaindata/ancient/bodies.0000.cdat b/fixture/chaindata/ancient/bodies.0000.cdat deleted file mode 100644 index 838476f..0000000 Binary files a/fixture/chaindata/ancient/bodies.0000.cdat and /dev/null differ diff --git a/fixture/chaindata/ancient/bodies.cidx b/fixture/chaindata/ancient/bodies.cidx deleted file mode 100644 index 36aa86b..0000000 Binary files a/fixture/chaindata/ancient/bodies.cidx and /dev/null differ diff --git a/fixture/chaindata/ancient/bodies.meta b/fixture/chaindata/ancient/bodies.meta deleted file mode 100644 index 59ee616..0000000 --- a/fixture/chaindata/ancient/bodies.meta +++ /dev/null @@ -1 +0,0 @@ -€ \ No newline at end of file diff --git a/fixture/chaindata/ancient/diffs.0000.rdat b/fixture/chaindata/ancient/diffs.0000.rdat deleted file mode 100644 index 465f590..0000000 Binary files a/fixture/chaindata/ancient/diffs.0000.rdat and /dev/null differ diff --git a/fixture/chaindata/ancient/diffs.meta b/fixture/chaindata/ancient/diffs.meta deleted file mode 100644 index 59ee616..0000000 --- a/fixture/chaindata/ancient/diffs.meta +++ /dev/null @@ -1 +0,0 @@ -€ \ No newline at end of file diff --git a/fixture/chaindata/ancient/diffs.ridx b/fixture/chaindata/ancient/diffs.ridx deleted file mode 100644 index 3519945..0000000 Binary files a/fixture/chaindata/ancient/diffs.ridx and /dev/null differ diff --git a/fixture/chaindata/ancient/hashes.0000.rdat b/fixture/chaindata/ancient/hashes.0000.rdat deleted file mode 100644 index f865e0f..0000000 Binary files a/fixture/chaindata/ancient/hashes.0000.rdat and /dev/null differ diff --git a/fixture/chaindata/ancient/hashes.meta b/fixture/chaindata/ancient/hashes.meta deleted file mode 100644 index 59ee616..0000000 --- a/fixture/chaindata/ancient/hashes.meta +++ /dev/null @@ -1 +0,0 @@ -€ \ No newline at end of file diff --git a/fixture/chaindata/ancient/hashes.ridx b/fixture/chaindata/ancient/hashes.ridx deleted file mode 100644 index 91c8489..0000000 Binary files a/fixture/chaindata/ancient/hashes.ridx and /dev/null differ diff --git a/fixture/chaindata/ancient/headers.0000.cdat b/fixture/chaindata/ancient/headers.0000.cdat deleted file mode 100644 index 3e1c6d2..0000000 Binary files a/fixture/chaindata/ancient/headers.0000.cdat and /dev/null differ diff --git a/fixture/chaindata/ancient/headers.cidx b/fixture/chaindata/ancient/headers.cidx deleted file mode 100644 index 2328522..0000000 Binary files a/fixture/chaindata/ancient/headers.cidx and /dev/null differ diff --git a/fixture/chaindata/ancient/headers.meta b/fixture/chaindata/ancient/headers.meta deleted file mode 100644 index 59ee616..0000000 --- a/fixture/chaindata/ancient/headers.meta +++ /dev/null @@ -1 +0,0 @@ -€ \ No newline at end of file diff --git a/fixture/chaindata/ancient/receipts.0000.cdat b/fixture/chaindata/ancient/receipts.0000.cdat deleted file mode 100644 index 808a254..0000000 Binary files a/fixture/chaindata/ancient/receipts.0000.cdat and /dev/null differ diff --git a/fixture/chaindata/ancient/receipts.cidx b/fixture/chaindata/ancient/receipts.cidx deleted file mode 100644 index 4683e01..0000000 Binary files a/fixture/chaindata/ancient/receipts.cidx and /dev/null differ diff --git a/fixture/chaindata/ancient/receipts.meta b/fixture/chaindata/ancient/receipts.meta deleted file mode 100644 index 59ee616..0000000 --- a/fixture/chaindata/ancient/receipts.meta +++ /dev/null @@ -1 +0,0 @@ -€ \ No newline at end of file diff --git a/fixture/leaf_keys.go b/fixture/leaf_keys.go deleted file mode 100644 index 8fcd4c1..0000000 --- a/fixture/leaf_keys.go +++ /dev/null @@ -1,264 +0,0 @@ -package fixture - -var Block1_StateNodeLeafKeys = []string{ - "0x291b6bbca879d684337ee5e2bca5d18cfb2d3b7a97c8187e703309564280295e", - "0x021fe3360ba8c02e194f8e7facdeb9088b3cf433b6498bd6900d50df0266ffe3", - "0x7820b41394d7f30f2b02f24f8a33afe8b98cd68827ec651aec3ba33e41206fe2", - "0xf908d785cef1abc9fcea55c07490d16b4825e8a6a7c8fb157ed2900bf4af58b9", - "0xd207b05b684ba18361df8e81e846d10365ffcf04f7840403c5bacf77add4c50f", - "0x5037b71f063bfe647233f570aa06602b1e6b5124db0b1fe998975f93b0fb1084", - "0xb02c4d58a3800d93f95f2eb4850b3d242756bf1ca3099bc43907af6dff0bf337", - "0x300d2dbe83a6ba7fd75737c8d7453d984e7938ba7ae113d3da2ad7433061157b", - "0x80382280e2f4a8ea9001c8e22332a3dc3d3a692b549d3c90f65796270e1eb770", - "0x087fb108e6836a088e06156b1a26210d1f5284296b30b0bb0b3d1c2a7e01ac11", - "0x71a3c7f8d0fe8abc9fbab1860ad576eddff2144763937195ea4f012fc625b053", - "0xb8864cb7c6215e99ffe5db7b22b3129e93b9a38b9b54193a0e3d7c8251657173", - "0x881a506039e25a818f35aa0e3ec58c64df5c106245dc25ef6fa4cf1eb1aab56a", - "0x40637a529320dace54763c2e6ac52c522c8a446ba9b6f54daf84c0e442124b93", - "0xa092c3f36135f79c57aa5683d97e5d5750c37d0bd0ada215e9a96856c56d7e91", - "0x684272547bac4c083b7380f054d08a5030862a5f06a2367f3b8e880c4b7370ed", - "0x18dcd435bf7d1820085f6c46d587cae669ca7c2d3ad4cea9db320a0b3c8bd21d", - "0xc00c28a6bfe2829613432a2c21eefc25da5bad983c5430ca28bc1a92d2b65ec5", - "0xf03db4f61547c9d8c58b4f37f84f74eff767c24cf81b957662e96622f2ac4d19", - "0x38401b4e97e67c4a6d8095979b4c1ecb9eaf5726fc8a12798975a7653e980872", - "0x992470b3e52c94f7bd5d4962a1798a41425bea74ad087a7f53aebb785401df3d", - "0xe015d2e4c085291611298460602b913b5f19272715fcaa48258efe24cf21885e", - "0x2092b5602121cc484fa55b90cea0be17d931184263925a864e0d5d43a20d67b0", - "0xe83c2c56f351d8c25863a55ece938ffcb6cdf2978eb34ea1a19591884d3885f3", - "0x489fe686547f4a999d2818aedbc18b735ed2cd502c30124a0b8af861b2251f91", - "0x90b0d289ea211dca8e020c9cc8c5d6ba2f416fe15fa692b47184a4b946b2214d", - "0x6042501054831920bc9d50a33d6be1b5a8214c31ba9416958f8996cdb6ddb05c", - "0x125adc67efe8bf6808c02bd3ae20262953b5e45dab4eb9386441cf6ec7381844", - "0xd81c5d559ba870e90a2b617cf0542695e9a626619b59148b40295a0ba55ca66e", - "0x5839262442bd87bdce9bcd8e97628a84fd07aaf55ba8c4c29e1ae91cb17cb222", - "0xa876da518a393dbd067dc72abfa08d475ed6447fca96d92ec3f9e7eba503ca61", - "0xc93e183a9dd09cdd44ca2a9eb6b94f970f8fa309b0f9cfd823572c23aad58fb2", - "0x75422a3d36c93fcbccad2e502775226f375e264e35fc55ac20df1e9f050e8b8c", - "0x20ebfef43639215aeb35e1e00bc96174f52155afb781659f34628d1f3f7ae018", - "0x20ebfef43639215aeb35e1e00bc96174f52155afb781659f34628d1f3f7ae018", - "0x005e54f1867fd030f90673b8b625ac8f0656e44a88cfc0b3af3e3f3c3d486960", - "0x1a6d9674aec5c8329252cb634022308bf4c98e70edec613d925ab781483445a4", - "0x5095b76023974440e6c155e26b3f7084f0b1901a0df2183dcfebe01f326d5e96", - "0x58bb8d7ba2f52228853238b26bfe3eb9607cea944e7020458981618efe8280a1", - "0xf92f9911e6d5b40e46f574db0a406d360f91c8de842ded48c8c699080985b4cf", - "0x785a32bf0f42bd6c986b900070bd70ff4ed5eaad448e57cf5d997224c3f87c2c", - "0x9546dea22f2479752816b65aa9db1b835efefbc1ed11804699683897cda4227e", - "0x39c8bb92227ba91a2657f29c5498f5c5b07ae36369c8d9283444f477930c79be", - "0x75422a3d36c93fcbccad2e502775226f375e264e35fc55ac20df1e9f050e8b8c", - "0x9ee40dcbc49746e31a754155515aaa232bf0bdbfd5a7ab77ea9cd39f4b7282a1", - "0xe8c07bab8822eeeb875236e148f781341157f9bfc56c1c53972489ff4009695b", - "0xb0fe18e510f695dbf24ad56fb3b647aa09f8e19021abe80686a66a2e653cb12d", - "0xf5b693085beb21b0878c7e5fab7519ce0d6105354cf6744dbfb73e3745e929e4", - "0xa0a22226f85371b5e5e4173b33a1b9629d745961f36e9b0510c591f11e3dd95b", - "0x08b3f9a96baba12f47430f2b0e2851f407e8ca355bb8a9a69242bc99aecc2cf3", - "0xc01318ac6e0d2cc08468abc1df6f2c9ec3fc5cfbfe5efec83aab250cfc83ef3f", - "0x8938be2ad9950390d6d92213ca102fc21a4304c88354d0e74f4b3ff696ce5791", - "0x623f300bf600b7b050b9b70fa57140c59a5f0b9fc5b9d0bdab11d108a71fc1a3", - "0xb8f37a61c26d388306ad9dee25e72aa86a49903a1fbbe6205211b47d1f39f77f", - "0x127ec70ea0d8a7b6244ae7d951b2204f75336cf21f49df6370ab920534c95728", - "0x68492f20c1d7597425c8a53a7f5e380fbce058d1bfea2521a7e8af03c387e1a0", - "0xf93d447fcf86f847e6609bfb3100aa5d07df37f2c72cbc4961e3a0f86a7c24b7", - "0x3a2c7d5164f6a1d8cbc5d9e228253eae4a66d8b0d550d07c53ec84d47ed17172", - "0xf93d447fcf86f847e6609bfb3100aa5d07df37f2c72cbc4961e3a0f86a7c24b7", - "0x4b6029773e7175f32398422fd18c6cb095e5278ac7be41ca4a5a6c0a6dda1a71", - "0xd222125724b9df1f4a92e1284dbc871a9156c253572df0a38ae146ac03b62af4", - "0x5a4be2322eb50cfea1051978c284526cd5a6e28caca681855736a5d3c31d9bad", - "0x89d04bcba396d12de1ed36f41df60ce0ae0449bae83f14c740451cf19362ae8f", - "0xd8ffcbc0be38306e539da616161c64ef7bc0f0281d62e5296bc8eb6ea709cb0b", - "0x96ad0b27ef10fa7a9940299df122d31222cc911bd2c91d2740f25a0dc931f4c0", - "0x40f85cb8136e95238cea4cb951a2ee645a4998c108831d5abe1d8f48696864c3", - "0xcb44297958c82fe80fb882f2c8a085a38556247b3c3f665eca382d27e26e3bbc", - "0x6298deb7c736dc50b4590ca066b72173d4e2c3f75bb109396f32eaaf9ad11bc8", - "0x3019c0a91ba30d346a55890b1b07287d8aae35baa8c4068ef8f1de66084aca75", - "0xb9af72fc0534a4a5a94eb1f64cb1bd6c425acba3249fb8441e7411e9be9ec1f3", - "0x80be858ab09789d26cf1128775756a8abe1c8ffc4218d3e990b3d25a82583255", - "0x0999f18de77e9451867cb1935f9acd56f79cbc11d04826c3da6b420a4f4bbe21", - "0xb14d9fdc657d712208d6e7c2cfbf62f7ad7ba1bfff2e63e6caee2b0bf5bad0fd", - "0xa93db8611e8d0c159eb724d2aea72763dfb5a6909a8516467c79d0386d61a511", - "0xc01b3857946cb77af9fb09394c4a359fba6df202c77d3e07e53177f3f18a55f2", - "0x79deb2f042f1717cc882c5a38bbb6c524932352ff25baeb8b8fd2225095e29ae", - "0x50ff4d47a46c9cd35b029e95ef9c957e57da987491f6e7be242e72bc5d3e8086", - "0xe8c6b410e2984be3bed9a84b76fbbd647f5fa56e65e36c264903275aa22cdb0d", - "0xe1e23690e890cdec6eb19b06f5d31d422b5c17bd4c435afb2a2532180011453f", - "0x9f0dbaecc6581cfbb57cd6c6f50e24c23ad4fcdf228140c0cb51a8a4edf5d0b0", - "0xf67f470df15c88b9beaf3fad72890a64f8851d01ece546b0c9fb3bdf92041a35", - "0x1d50131be868de2741cb775d0ff800631f96065f40b60845bce72e782718af23", - "0xa0f1ddc6e3aad69109e0e8c5d15e8800e220b192f85f369e0bef5cf858dccf9a", - "0x689802d6ed1a28b049e9d4fe5334c5902fd9bc00c42821c82f82ee2da10be908", - "0x1318a4c2bc731718857238ec2c42e4a95c0aeb7290a60c8abb110c2e638341c2", - "0x21120e1be03d384ee32a9bd7268578d8829f271540c848c97a495990bc48f582", - "0x297d3acffb942c7e6f3fb029b735338ac34e39c4ce9e852f64d50fb57cc97ec0", - "0x7744be2427cacf17062cb030d30e34c3b543b28a83707df04e64d3f7ddb471b8", - "0x028e62cb4665fce19ae1fc13a604618d7d20be037fc68b63beb3384dfa5ab776", - "0xcce46204baa86f733abf208b358ba8b807081d6d46a407745238aef2c133fd4d", - "0xaa546817dabffc9c4249830a0af5cf43c6ece6562720990736199e570f621d7c", - "0xfb1d6797796ad9edd1b8b41030035a003eb6286ae2fc1a8296b509891acfa033", - "0xb25939867994cd8e5a18f341628420fa8ab88b2f5d05ffe51291654922f5454f", - "0x2b7afbb14b4c902f37163b15f70fe8335dec4e26fbae4718c03f19da5aecbe8b", - "0x1e22733f173fbc95fa079ed50ec24c498a8aad2515d827e5ff8200c240e9cdc9", - "0x4b945ef2e8c78482bbffcbdf4921cd375065e3b5024a3bed469a9f34b2e773e7", - "0x13b8f5750961b5588bc69fbd0b701461854e110fd78c14767515bdd882725975", - "0x41351b958be1e95cdc37f7d2d654315e33ff7f45bac9179f9242fdc828c8d2e3", - "0x9f4e60123db23e3f3055f75087248fd5923d469e76d344d28b4f24a449ca6398", - "0x7d1009331195f6a3c2eee6ac4b4664f61c777500c163ee84769913578a33bdf2", - "0xbb62e8d8d0eb3d7432758c244131f1649874367cc52a4fa4fd0609def9e57389", - "0xe22d496c425479acb445c4040bdb5e17fa461de175eaaa77aa79e23b5b19f761", - "0xd24e8fff20c5317074c54fd54ca9f1fc8fef36bb70c44b55f90a70c621b91f9a", - "0xd90bcdecb44a3402e2a1b5d3a321b51e415e298ebaca3c95d91443adc03f6cec", - "0x826ce1d60ac9f0ab5944acf1c06700a585f8407d670495c7811b97cf8263b434", - "0x2139fa1aaa3d60e53d070d5a1f1ac9c8211f41b2dd5a1813416c8447a7759557", - "0x96e16af9aa5f894c43514d940687dafaa5ad04ea78a3b0080319370e454602d2", - "0x6400fc32c5b2d3580c0e19889487cf9e057d6b82a99bf30eb6e539b7cde52655", - "0x02cb51767354e1fe6bd4a49b64b3721ffddbc95fed1b8ead005c39bbc07bc4d8", - "0x3a82e1e58ae6f14fbbeb35b6d833330c4fb5b3cb770391f5cc340949c6254e83", - "0xa216c0a47b12c20d5ac5c381464a89521d8b0c1a5cb328aeabb29b70bc3347d4", - "0xea674e603f60ba1e252419d86d0485fd3f46ca6abbf4c65afee0a9ba29059655", - "0x8ae586aa1ec2c29aced4feb5adf9336541769b93cd5b8cc1b64b7d831c7b0ec2", - "0x323e393774eeec8e9d596258267d0133a5b2f01c567822a4ff018488671ecb6e", - "0x51ee1e08db014fc699587667b7256e7b9090e1755c587420cff5fbe0e20194fc", - "0x6a1c4e8b7c710531c9e66166d0629ff443df19cefa081eb4fffcc7d267ce7c92", - "0x09af9e7ea2370ab3e3ee7f0a465a7dacb6c9b7e65196dc496d5570a0d8020bda", - "0x5b70e80538acdabd6137353b0f9d8d149f4dba91e8be2e7946e409bfdbe685b9", - "0xc0f4fde474181fca3d1fb6e0dc118a71457fe7cc5d4f1e426c92e1767eb885a0", - "0x4bce4e0299e5362578a95a27bcb779b9a89232296388db803909696f90635581", - "0x1ebfd7dbb6804351804443df01a482e6451912b884cd26b31504bb77bbec9862", - "0x03089e01be9eb2af5ff5fa1c5983c6c6fb78dd734658d1f8f11d4f8d27a23fd5", - "0xb31ba6d576dbde0542d30a9264e2c71be270e3eb4f5910567a8c1c0619a2e5ec", - "0xaa8d9c947771632a645c67655595b61da72837bfa97f30f417dbaed82f2f11c3", - "0x32fc4fd3fc836c6db0058fd20ff7e8ca611885eb7215b39f97d2b4e797dca254", - "0x5c33820c3d76f4de8d1e0eca24c7d2fbef76189b6a43a7afea4dfda5b50edb96", - "0x6aefc729e28e1bbd2e63dd0803314deb808ab044909af882b7935dd05f5939a4", - "0x0c3a3c99f34afe9d2c8cecc90524ef63afc9fc13384d5d931281f414d5d487c0", - "0x9fa95d10732f34365f34f5a2f7702a9dae40c583105c40921a5052dca1f9f793", - "0xeacbb86ec518baa710dea5ed986162f21df2a98d2119f6cacbb01e8d9a77a629", - "0x7d1d5f3a14c0ab133b65698c2d62c818c65f13306ccbfd61aa4b7590bb78660c", - "0xfb6ab511cf5bcb157f833241e74ead7128a21818c2b5080be21ee9f85ff5d523", - "0x21ea8bdf8a4ea6dc9e204591d88c3b5b19533d33bfbc59c08cca266c3c87a960", - "0x9782bb006174ed014c59e6eee381c6e10bc9304226edb99edd6f8e9041e9d9a7", - "0xbc0cb591a67822e88dcebb8991bca5b7305b5858d65bc2b5e6605e481a650588", - "0x8484452e4f0c1a9f115c52b4ac78a0de2f1b0ab1a4aae8390426ac71e03f8779", - "0x2bd9aebde44794e6db317be6d83c5a266e1a96e18e04bc7073998bb779cfe2fe", - "0xd9ed35852650f28d7a8f73c7ba49bcd72d97edf8d731797e5a2728559b865552", - "0x1468288056310c82aa4c01a7e12a10f8111a0560e72b700555479031b86c357d", - "0xfc39bbcf08818ec3329e5769dff3fbdad66e6312a961acb32c1b203edf70aeba", - "0x5d9114e8c0b1e858bf7322eec122e3fc4b0988f146620def0fde9dbd322f3a03", - "0x4e09550da9ca55ba375e56c525b49b27814d20165528e4e7f309878221b2878b", - "0xe2c8bbf962c30afe9c35e9d7e036ef496b52cb770c645a76f2cee5f8811a9830", - "0xbddec651652e0aa17e056de1790554aeca5fa248cecc4131d189dacd26c4ca55", - "0x51f0e21d8c8aeef60da6ae58d10dcf1f42e7d9a0cb8ee2b4a97caa566a152b61", - "0x421df1fa259221d02aa4956eb0d35ace318ca24c0a33a64c1af96cf67cf245b6", - "0xd37476a178ee68b02b3de0edee1ebb57e1638eebf58b3e256322e0da1189f272", - "0xa3b41c13f6e16fd2242a43b041cfd1f02cbb4cf06943d14365bb8f0a30ff507a", - "0x3ac3fe84c663607ebbe01c6b008d02b92ed4feab26ed8171014853c0f9419cc8", - "0xad00cf4d7db523f20b5000bd1469a11d70b73feadd36578abdb9f3558bdd3674", - "0x8c3ab0970b73895b8c9959bae685c3a19f45eb5ad89d42b52a340ec4ac204d19", - "0x2d15e1e82ca50b7334be8990b93a8b043e771340cc9398baa23845763c696d22", - "0x331d99c6bec3aecbec962be74b25448511983b013c0876f6f4e6029773dfad61", - "0x258487f1d48945c7743c412b0f026d722a4641d5978f11a0b44dbf7c1d274d41", - "0x528b55564e8518548e42b534da3a526179b820f264ee7c6929d00b0b6a31cfc2", - "0xc2911b75be7d3fdb9442b900ca8f7205d6d52fdb3505e77ea8676f811a6d5ea1", - "0xda0d7fc05c32bbba16518f9f2936fd75140d5c99b95ae536205ba9caf1868378", - "0x26dbcce1b599ebed46e2569579562031255ea9a1c1c575fdddb0003f4d389165", - "0x8cfefa9806c99db8bea1ed8e534f6dcdb835cd1410f1f287ea4293e29a3eacc0", - "0xbe017710d6bfb0ac7a8d140333127571809eaf2b590900f168545daea3865f60", - "0x42b45de6853d406783b6b50c378bfb61d6ce5271b3bf813cc2b959055fc12f98", - "0x2df378e8ecee785e1d65200d738178432cbc9ad55c49ea5af905629d348416c2", - "0xe36c0f154a365e086c687050cee74bddde9997a1dedeb0e55217368c0ab6baa4", - "0xa62e9dc15a35c1ab9d0ac4345b1f02fd8e8070883a33651c0c143b2582708268", - "0x04242954a5cb9748d3f66bcd4583fd3830287aa585bebd9dd06fa6625976be49", - "0xb41089e529c1ff6c4d6583ecfca7ea6419bf39e0d418686bb7a24424c670b332", - "0xd3a7e59f888a7ac07a211c717c07b82970d94597f6365cf8c93d51ac9d45c597", - "0xaddb0d4b14749bb4b5cd858f29a4b4225138c3953090ce45204458dcd53749e4", - "0x34275c313c5286317794f0154f8e4ffacfc80d9d0c5b184d2482e7f9211ffc3e", - "0xfce7321f278a2973bf5c67757ea7690649295d53967daa3ae858695be336abe2", - "0x1f99af2df2da9c0176bdb3e995bdfa47ffbfe6a3aacf8e54401f4dac2ece9338", - "0x6b2c03103b55a45cc1e4550889a9396e7e331b5cf1729e4871ff4dee701139e9", - "0x640528e5cf143f173d29cd8b4f896a1c6128f3416c887c10d4a11898841b4a82", - "0xe4295c5aa043a60d279854f7424e21250d5c1e1f9959549e90bc926d70e97068", - "0xae49f4417048cacc01716a2d804f699d8ec34ead735e1c61604996ac37f35157", - "0x52a6fb56e13d45fe16456e828c8c375b0decaae2d644b76f8a9b0a741de1ed89", - "0x5f9e4ee172469cfda38a7457ef192b6efb169fedb73943e4c987d4eb910189d4", - "0x43926296aa3c8efab7e2ff9bc644236193fa657726127559ba0668734d1b2790", - "0xd52688a8f926c816ca1e079067caba944f158e764817b83fc43594370ca9cf62", - "0xb53f6bc81ecfaf0cf4c3dcd9527e3c0f6910383acf964ed14b194fa660d30b10", - "0x0d21eb4f7c202eeccd6d87627f3d512e630d4d05578585847168758fd1aaed22", - "0x1ffff1a455b66d52107a26231feefb0f3565067e9544cf9470d975f01111b1cf", - "0xdc8829261b6bfd53ab7daac305c2ad0ed15423234128bdc5b86a2e9eaf6157e4", - "0x6bcfd58769c6966e31aabe28addce6151f2dd2ea1d9c307e09c6c9db95b6b103", - "0x7d766503b9158ee06b0a587859f6e24974c78c3a64b6e4d8aefbcb8ad3bc2127", - "0xeb885fa37ef7e686a7f8dd3d9004de555526310e78dcbf857c9b0a31e40b9736", - "0x34447afb686b4074d3b93b99076a60b5f5a902fa32df18d85fc1d13ada8cdb71", - "0x2f1b6a8f228675a171126d1781aeb52756d6fe5685af8c7ec23dc8187d783d1f", - "0x6545d98b7c7dd9e023753a64c515e69e19e72b18f163831c08c7f559dd8134b5", - "0x15b381b518c6b754185d6903caf17b4f8dc30babfedf8072b118bbc3eec3013f", - "0x06339935111b4a563a28a91c253b638af868b3af7c372cab497cac4f6cb2c0aa", - "0x45b0937bfe39b0fdadcaa8974daf324193624b47f4918234645819823dbec07f", - "0x8dd81a60355138e9a80054603fe23d7896544254f66e236d478a9b033c3a0330", - "0x3ba5ac70a18399817ccbe8bd4d9c78115136cc61699d51af87608af520226c32", - "0x0e8271a44c634b7fedcd00cb09afea2a70ac8380b6bf5f61ff07e793ee3f6d4c", - "0x34562e3ace608bdd75a10eb153cbc2c00e69b935d42f57c193c38ef6d674abac", - "0x06d9e4b9abc0b8978120d451eb4cca4f72ff1d97321713e0ef379a157b8f2b60", - "0x65a1c5667776dd9a726a67038e45e040b1fa463ed55f753c2156b355616f2c82", - "0xdcbad7acc8ff4bb5562dc1a37e87244df11ed754f8f25ebb6fc23320e5268b3f", - "0xe55b734df35ab6d576607e01c42f21d275cd9c0f86fbb3100241a14ba0c7672f", - "0xb7c8c273af675612bc8ee68c7a419b671e678e63fb9ed62646358d70adb82434", - "0x15c53c582284ec93075084bae0536b5ab7ae44a44ee2718489b72be3aa78c3c7", - "0xfced34088582b4a78f611c7366195e3e94f9080637f4104bbbd0d07ffb783d49", - "0xbe03f50d58fee6912ddb6cdfd5c26302db94c986ad69eb4e7fb32768636bc9e6", - "0x6be4eb2fb308fd641346533a4acb9c4cca3e2d478e9075522646c972a2062985", - "0xebd4d964df19c1598d3ce8354498f4f0cadb39d700af15ba6a42f8f6444c27d0", - "0x5380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a", - "0x7e833b9b867caae3d5e2b64c13a744f0e5cc1bff50fdb3713e3c505114a07de1", - "0xaeb868cc8cd000167af8b0f4dadd2e348e543a019cd0b1312dbedeb4ecdc592a", - "0xb7fc8b1cc055dd94a0f598f5ce4f8e121a8e3e4ac752b027ba3e2e99ed10c7b8", - "0x3c9bd268aedc8dbb36db0a4664e17b83abcfd87e404901eee7bd5704a95064ee", - "0xc2cf8e05450be6d2c98edc5df219a4cbd86dc60667b4a7810257177dc73217ed", - "0x07c57780db2d0b81258ad3be5df2c3a9e89e4c06bfaddc3a1f4e3b9401215947", - "0x7eb6fdadc6703ad64a7ccd5feddc788dc92efac7e066e01d5eb7176e91a6331d", - "0x6d2032b002dda8c5280bf48213d7b981476a9a8e53a69a39c625e5c8129e9287", - "0x65ca73153cb8f02233c0d12f996e3dc1584f0426285f63bf41bec91a86d3c36e", - "0xaebe9973fc4849a27521c2a71aab7673ddab83cc88e91abec675c1c471abf927", - "0xe690b239ba3aaf993e443ae14aeffc44cf8d9931a79baed9fa141d0e4506e131", - "0xbe8f0a3d1c2d7a0fc2342f9a4c78e00fe38a7f26da345758cb2b8efd052bcd55", - "0xeca6cdd9768090f90960cf9bad47705ca3b19a54c8ec8186e2987ffdd3a8435b", - "0x15fefe8613a1e673567aac83294fa0da6d048e5c7642227017441c9f899fed1b", - "0xfdfacf5483fdda2fc98d08bcce1a68d5d308d3ad88ee21b50004fd694ba6f805", - "0x36b3096c912adc7674ca92b68ddb3b0494e9b988fbef1bed7938e8fac4c2df7a", - "0x8f8755e5d8418704774f38ac79dd944c223bae9ae361c5efdd614d09c60fdcfc", - "0xdd7ad9673f823444e5194d5ab0eca9a1fb7bd3770d0fdc62ce3e180037158773", - "0x46f3f8cc486e8047567212c0f011c065466bcb76647dcf87d42756d7fbbfcb4b", - "0x546690cf9510b4b7732d2c99c7c2d994f6668b7d7f75a1d28c0eba53f784fe1e", - "0xc49241829446ad570b5b97d38a504782a6522204c67d5f29b61515246d0410dc", - "0x8fd56ff474602c98136f4a9389e3e2b5d7e78ec55d5edb63fb477d7281424515", - "0x471703c5eda8644a64cec152c58f5aacec93d72fb0bfa705f0473f9043a8357c", - "0xddc48afbdb1661c8789b447f581ae07eb1863b24e50865dfacacf0aef7a4f9dc", - "0xe6c05c2ebac68df110b9966cbf92414a6ddcf3b67fc77901a5fa049da0cfb109", - "0x3da06a67e7fee9c938155c50e6cec9da70b66679e777da6f02149c6674cd9105", - "0xaf03175444dc43cc33391c4c4010eac15d401b2eb5ffc7bc778abe372f28ce37", - "0xee317a72c6604e9e4abcba1ad9d6159a00d9168558be819e4393936aa1eee432", - "0x162386be0a525c5a9e6110c7244a375038c525fe102df224286161b1289bc716", - "0x54c901f415ecf89c46159b356a4a95e9e5666bc88f8bf4bf5d9c15aac8709e0a", - "0xbeda4b34674f3b9d0aaf6c3946c05b73b4e7ac680c7084d41dc8f0bd3bb38031", - "0x65d07b4d81508c24f55172afab2935db210689baba6270991f0218356705dc1c", - "0xfe6a58207750197f48cb90864096850259845c2c8e90c74433325c0b144bf8bb", - "0xc57975ae690f9a6554015459db6c13e8c6dbf6e4cc0f5cf986afd1210c233abf", - "0xee9d69f02d1245985cab3ed816bc86177c83e0701cc5515de9932aa065886407", - "0x6dc809012cc91335a5ea4e186bd04479aac7dae1bcbd023bf660213a69f4fdbd", - "0x3e400fa3269849dec0cbf4edbd663657c73bdc8c97c07aa166dd8b49f0b14028", - "0x56d423ba59df7075b27e5d573ad8399ac6ab8a7541efb9a1e646a67244301fed", - "0xe748320edc6a9c30d249d75af74a19ade7f69c56e5e0d3a9adb17fee1b0a4bef", - "0xde6e6fcaefc39f05e5912014093f38926987bb7b125e51b49ddfb49b03e36c50", - "0xfffa0eae268038cfa984647a1d0635beb86eda9fb7b500688f3189520cfa9ee5", - "0x660f4f93865ad80d0c9f1159bc17ecaa398a0f4af3a374dd033b20029378980a", - "0xe7cf18b96a1c12507c9a95b7f48c3e012651793a196ce2b81aaa6cb185dc03b6", - "0xc60f70699042477727e7230f64b5c94d8dcb2c7815f8c2542722fcef900dd238", - "0x6688c7b8c02428a3ba7e0b83237978a46faf9a632fc615dfcf7226473c244004", - "0x3e9a637c5898b70506a347ae7b5768d1a84022f9702e8268e8a5bade8194dd47", - "0x3eea7e8e2ca3e385fe39d605086b049b99df1adab85a1c6569873424f488c5ad", - "0xc6474110edeef59c48841b35aed37057feb211e738124285a233e77e53152a57", - "0x3eef5a1ec65e8ae1c87be5edc45099ac9e7783d4b8075810ba688eb479e7a730", - "0xc6e7f2ef75851a2b752eb247b5701aa5f24d0c867534330c74c51c1ae91319f7", - "0xc705619eb7a97a01d24e21cda98066d40aeb6d6ce6fb9e9a4880d86fe4432b13", - "0xc7caa90744f6b0e1fadfc5c21ccc5de0057447d6160835e35e25a82fc391d051", - "0xc7dd5ab81d775d5c8b283ddf787bc88c61e766b7b418c0d6375683f59fe6e5a9", -} diff --git a/go.mod b/go.mod index 716e58e..dd03631 100644 --- a/go.mod +++ b/go.mod @@ -3,43 +3,53 @@ module github.com/cerc-io/ipld-eth-state-snapshot go 1.19 require ( - github.com/ethereum/go-ethereum v1.11.6 + github.com/cerc-io/eth-iterator-utils v1.2.0 + github.com/cerc-io/eth-testing v0.2.1 + github.com/cerc-io/plugeth-statediff v0.1.0 + github.com/ethereum/go-ethereum v1.12.0 github.com/golang/mock v1.6.0 - github.com/ipfs/go-cid v0.2.0 - github.com/lib/pq v1.10.7 - github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/client_golang v1.16.0 github.com/sirupsen/logrus v1.9.0 github.com/spf13/cobra v1.5.0 github.com/spf13/viper v1.12.0 - golang.org/x/sync v0.1.0 + github.com/stretchr/testify v1.8.2 ) require ( - github.com/DataDog/zstd v1.5.2 // indirect - github.com/VictoriaMetrics/fastcache v1.6.0 // indirect + github.com/DataDog/zstd v1.5.5 // indirect + github.com/VictoriaMetrics/fastcache v1.12.1 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.2 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/cockroachdb/errors v1.9.1 // indirect + github.com/cockroachdb/errors v1.10.0 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 // indirect - github.com/cockroachdb/redact v1.1.3 // indirect - github.com/deckarep/golang-set/v2 v2.1.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/cockroachdb/pebble v0.0.0-20230720154706-692f3b61a3c4 // indirect + github.com/cockroachdb/redact v1.1.5 // indirect + github.com/cockroachdb/tokenbucket v0.0.0-20230613231145-182959a1fad6 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set/v2 v2.3.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/fjl/memsize v0.0.1 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/georgysavva/scany v1.2.1 // indirect - github.com/getsentry/sentry-go v0.18.0 // indirect + github.com/getsentry/sentry-go v0.22.0 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-stack/stack v1.8.1 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect - github.com/gorilla/websocket v1.4.2 // indirect + github.com/gorilla/websocket v1.5.0 // indirect + github.com/hashicorp/go-bexpr v0.1.12 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/holiman/bloomfilter/v2 v2.0.3 // indirect - github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c // indirect + github.com/holiman/uint256 v1.2.3 // indirect + github.com/huin/goupnp v1.2.0 // indirect + github.com/inconshreveable/log15 v2.16.0+incompatible // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/ipfs/go-cid v0.4.1 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgconn v1.11.0 // indirect github.com/jackc/pgio v1.0.0 // indirect @@ -49,31 +59,41 @@ require ( github.com/jackc/pgtype v1.10.0 // indirect github.com/jackc/pgx/v4 v4.15.0 // indirect github.com/jackc/puddle v1.2.1 // indirect + github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jmoiron/sqlx v1.3.5 // indirect - github.com/klauspost/compress v1.15.15 // indirect - github.com/klauspost/cpuid/v2 v2.0.9 // indirect + github.com/klauspost/compress v1.16.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect + github.com/lib/pq v1.10.9 // indirect github.com/magiconair/properties v1.8.6 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect - github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect - github.com/minio/sha256-simd v1.0.0 // indirect + github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mitchellh/pointerstructure v1.2.1 // indirect github.com/mr-tron/base58 v1.2.0 // indirect - github.com/multiformats/go-base32 v0.0.4 // indirect - github.com/multiformats/go-base36 v0.1.0 // indirect - github.com/multiformats/go-multibase v0.0.3 // indirect - github.com/multiformats/go-multihash v0.1.0 // indirect - github.com/multiformats/go-varint v0.0.6 // indirect + github.com/multiformats/go-base32 v0.1.0 // indirect + github.com/multiformats/go-base36 v0.2.0 // indirect + github.com/multiformats/go-multibase v0.2.0 // indirect + github.com/multiformats/go-multihash v0.2.3 // indirect + github.com/multiformats/go-varint v0.0.7 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/openrelayxyz/plugeth-utils v1.2.0 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect + github.com/pganalyze/pg_query_go/v4 v4.2.1 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.39.0 // indirect - github.com/prometheus/procfs v0.9.0 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/prometheus/client_model v0.4.0 // indirect + github.com/prometheus/common v0.44.0 // indirect + github.com/prometheus/procfs v0.11.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/rs/cors v1.9.0 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shopspring/decimal v1.2.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -83,20 +103,31 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.3.0 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a // indirect - github.com/thoas/go-funk v0.9.2 // indirect + github.com/thoas/go-funk v0.9.3 // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect - github.com/tklauser/numcpus v0.6.0 // indirect - github.com/yusufpapurcu/wmi v1.2.2 // indirect - golang.org/x/crypto v0.6.0 // indirect - golang.org/x/exp v0.0.0-20230206171751-46f607a40771 // indirect - golang.org/x/sys v0.6.0 // indirect - golang.org/x/text v0.8.0 // indirect - google.golang.org/protobuf v1.28.1 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + github.com/urfave/cli/v2 v2.25.7 // indirect + github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + github.com/yusufpapurcu/wmi v1.2.3 // indirect + golang.org/x/crypto v0.11.0 // indirect + golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/sys v0.10.0 // indirect + golang.org/x/term v0.10.0 // indirect + golang.org/x/text v0.11.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.1.7 // indirect + lukechampine.com/blake3 v1.2.1 // indirect ) -replace github.com/ethereum/go-ethereum v1.11.6 => github.com/cerc-io/go-ethereum v1.11.6-statediff-5.0.8 +replace ( + github.com/cerc-io/eth-iterator-utils => git.vdb.to/cerc-io/eth-iterator-utils v0.1.2 + github.com/cerc-io/eth-testing => git.vdb.to/cerc-io/eth-testing v0.3.1 + github.com/cerc-io/plugeth-statediff => git.vdb.to/cerc-io/plugeth-statediff v0.1.4 + github.com/ethereum/go-ethereum => git.vdb.to/cerc-io/plugeth v0.0.0-20230808125822-691dc334fab1 + github.com/openrelayxyz/plugeth-utils => git.vdb.to/cerc-io/plugeth-utils v0.0.0-20230706160122-cd41de354c46 +) diff --git a/go.sum b/go.sum index 797b76c..ae29405 100644 --- a/go.sum +++ b/go.sum @@ -36,32 +36,31 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +git.vdb.to/cerc-io/eth-iterator-utils v0.1.2 h1:PdMR5B9wrQSYuYpFhN+9Kc8AEZ0pTt5eKCmu8oCtFcY= +git.vdb.to/cerc-io/eth-iterator-utils v0.1.2/go.mod h1:OvXbdWbZ5viBXC/Ui1EkhsSmGB+AUX+TjGa3UDAfjfg= +git.vdb.to/cerc-io/eth-testing v0.3.1 h1:sPnlMev6oEgTjsW7GtUkSsjKNG/+X6P9q0izSejLGpM= +git.vdb.to/cerc-io/eth-testing v0.3.1/go.mod h1:qdvpc/W1xvf2MKx3rMOqvFvYaYIHG77Z1g0lwsmw0Uk= +git.vdb.to/cerc-io/plugeth v0.0.0-20230808125822-691dc334fab1 h1:KLjxHwp9Zp7xhECccmJS00RiL+VwTuUGLU7qeIctg8g= +git.vdb.to/cerc-io/plugeth v0.0.0-20230808125822-691dc334fab1/go.mod h1:cYXZu70+6xmDgIgrTD81GPasv16piiAFJnKyAbwVPMU= +git.vdb.to/cerc-io/plugeth-statediff v0.1.4 h1:swDJDAk1/yu6MOHAvxeyZz+MS1H9FCmSWGQRswFxFEw= +git.vdb.to/cerc-io/plugeth-statediff v0.1.4/go.mod h1:PX1bwTwZKzegQu6zYdpuJf1tHNmU0suapKOUUO2xIzs= +git.vdb.to/cerc-io/plugeth-utils v0.0.0-20230706160122-cd41de354c46 h1:KYcbbne/RXd7AuxbUd/3hgk1jPN+33k2CKiNsUsMCC0= +git.vdb.to/cerc-io/plugeth-utils v0.0.0-20230706160122-cd41de354c46/go.mod h1:VpDN61dxy64zGff05F0adujR5enD/JEdXBkTQ+PaIsQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53/go.mod h1:+3IMCy2vIlbG1XG/0ggNQv0SvxCAIpPM5b1nCz56Xno= -github.com/CloudyKit/jet/v3 v3.0.0/go.mod h1:HKQPgSJmdK8hdoAbKUUWajkHyHo4RaU5rMdUywE7VMo= -github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= -github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= -github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= +github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= -github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= -github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= -github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= -github.com/btcsuite/btcd/btcec/v2 v2.2.0/go.mod h1:U7MHm051Al6XmscBQ0BoNydpOTsFAn707034b5nY8zU= +github.com/btcsuite/btcd/btcec/v2 v2.3.2 h1:5n0X6hX0Zk+6omWcihdYvdAlGf2DfasC0GMf7DClJ3U= +github.com/btcsuite/btcd/btcec/v2 v2.3.2/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cerc-io/go-ethereum v1.11.6-statediff-5.0.8 h1:a57yBLQOkIKTjC5coaPWtNHmM+nKT8yQfwL/4UNmrLU= -github.com/cerc-io/go-ethereum v1.11.6-statediff-5.0.8/go.mod h1:Jc6zFIJJFvhRMDxbj7kfUFlg6NbSQiS4RyEMDavuF1w= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -75,25 +74,19 @@ github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/cockroach-go/v2 v2.2.0 h1:/5znzg5n373N/3ESjHF5SMLxiW4RKB05Ql//KWfeTFs= github.com/cockroachdb/cockroach-go/v2 v2.2.0/go.mod h1:u3MiKYGupPPjkn3ozknpMUpxPaNLTFWAya419/zv6eI= -github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= -github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= -github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= -github.com/cockroachdb/errors v1.9.1/go.mod h1:2sxOtL2WIc096WSZqZ5h8fa17rdDq9HZOZLBCor4mBk= -github.com/cockroachdb/logtags v0.0.0-20211118104740-dabe8e521a4f/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/datadriven v1.0.3-0.20230413201302-be42291fc80f h1:otljaYPt5hWxV3MUfO5dFPFiOXg9CyG5/kCfayTqsJ4= +github.com/cockroachdb/errors v1.10.0 h1:lfxS8zZz1+OjtV4MtNWgboi/W5tyLEB6VQZBXN+0VUU= +github.com/cockroachdb/errors v1.10.0/go.mod h1:lknhIsEVQ9Ss/qKDBQS/UqFSvPQjOwNq2qyKAxtHRqE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811 h1:ytcWPaNPhNoGMWEhDvS3zToKcDpRsLuRolQJBVGdozk= -github.com/cockroachdb/pebble v0.0.0-20230209160836-829675f94811/go.mod h1:Nb5lgvnQ2+oGlE/EyZy4+2/CxRh9KfvCXnag1vtpxVM= -github.com/cockroachdb/redact v1.1.3 h1:AKZds10rFSIj7qADf0g46UixK8NNLwWTNdCIGS5wfSQ= -github.com/cockroachdb/redact v1.1.3/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= -github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cockroachdb/pebble v0.0.0-20230720154706-692f3b61a3c4 h1:hAtIkNbQFeZbK6KEjiqyuWbegSeuLOTD8+hK7wn6+pI= +github.com/cockroachdb/pebble v0.0.0-20230720154706-692f3b61a3c4/go.mod h1:FN5O47SBEz5+kO9fG8UTR64g2WS1u5ZFCgTvxGjoSks= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230613231145-182959a1fad6 h1:DJK8W/iB+s/qkTtmXSrHA49lp5O3OsR7E6z4byOLy34= +github.com/cockroachdb/tokenbucket v0.0.0-20230613231145-182959a1fad6/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= -github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= @@ -101,52 +94,36 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= -github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= -github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= -github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/deckarep/golang-set/v2 v2.3.0 h1:qs18EKUfHm2X9fA50Mr/M5hccg2tNnVqsiBImnyDs0g= +github.com/deckarep/golang-set/v2 v2.3.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= -github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= -github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= -github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= +github.com/fjl/memsize v0.0.1 h1:+zhkb+dhUgx0/e+M8sF0QqiouvMQUiKR+QYvdxIOKcQ= +github.com/fjl/memsize v0.0.1/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/georgysavva/scany v1.2.1 h1:91PAMBpwBtDjvn46TaLQmuVhxpAG6p6sjQaU4zPHPSM= github.com/georgysavva/scany v1.2.1/go.mod h1:vGBpL5XRLOocMFFa55pj0P04DrL3I7qKVRL49K6Eu5o= -github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= -github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= -github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= -github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= -github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= -github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/getsentry/sentry-go v0.22.0 h1:XNX9zKbv7baSEI65l+H1GEJgSeIC1c7EN5kluWaP6dM= +github.com/getsentry/sentry-go v0.22.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -156,23 +133,15 @@ github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/me github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= -github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt/v4 v4.3.0 h1:kHL1vqdqWNfATmA0FNMdmZNMyZI1U6O31X4rlIPoBog= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -201,13 +170,12 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -221,8 +189,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -239,39 +205,32 @@ github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/hashicorp/go-bexpr v0.1.12 h1:XrdVhmwu+9iYxIUWxsGVG7NQwrhzJZ0vR6nbN5bLgrA= +github.com/hashicorp/go-bexpr v0.1.12/go.mod h1:ACktpcSySkFNpcxWSClFrut7wicd9WzisnvHuw+g9K8= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= -github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c h1:DZfsyhDK1hnSS5lH8l+JggqzEleHteTYfutAiVlSUM8= -github.com/holiman/uint256 v1.2.2-0.20230321075855-87b91420868c/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= +github.com/holiman/uint256 v1.2.3 h1:K8UWO1HUJpRMXBxbmaY1Y8IAMZC/RsKB+ArEnnK4l5o= +github.com/holiman/uint256 v1.2.3/go.mod h1:SC8Ryt4n+UBbPbIBKaG9zbbDlp4jOru9xFZmPzLUTxw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= -github.com/hydrogen18/memlistener v0.0.0-20200120041712-dcc25e7acd91/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/huin/goupnp v1.2.0 h1:uOKW26NG1hsSSbXIZ1IR7XP9Gjd1U8pnLaCMgntmkmY= +github.com/huin/goupnp v1.2.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= +github.com/inconshreveable/log15 v2.16.0+incompatible h1:6nvMKxtGcpgm7q0KiGs+Vc+xDvUXaBqsPKHWKsinccw= +github.com/inconshreveable/log15 v2.16.0+incompatible/go.mod h1:cOaXtrgN4ScfRrD9Bre7U1thNq5RtJ8ZoP4iXVGRj6o= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/ipfs/go-cid v0.2.0 h1:01JTiihFq9en9Vz0lc0VDWvZe/uBonGpzo4THP0vcQ0= -github.com/ipfs/go-cid v0.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= -github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= -github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= -github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= -github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= -github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= +github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -336,37 +295,24 @@ github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dv github.com/jackc/puddle v1.2.1 h1:gI8os0wpRXFd4FiAY2dWiqRK037tjj3t7rKFeO4X5iw= github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= -github.com/kataras/golog v0.0.10/go.mod h1:yJ8YKCmyL+nWjERB90Qwn+bdyBZsaQwU3bTVFgkFIp8= -github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYbq3UhfoFmE= -github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= -github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= -github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.9.7/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7yIO+lw= -github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= -github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= -github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= +github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -375,80 +321,61 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= -github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= -github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= -github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= -github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= -github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= -github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= -github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQhoHZAz4x7TIw= +github.com/mitchellh/pointerstructure v1.2.1/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= -github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= -github.com/multiformats/go-base32 v0.0.4 h1:+qMh4a2f37b4xTNs6mqitDinryCI+tfO2dRVMN9mjSE= -github.com/multiformats/go-base32 v0.0.4/go.mod h1:jNLFzjPZtp3aIARHbJRZIaPuspdH0J6q39uUM5pnABM= -github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= -github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= -github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= -github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= -github.com/multiformats/go-multihash v0.1.0 h1:CgAgwqk3//SVEw3T+6DqI4mWMyRuDwZtOWcJT0q9+EA= -github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= -github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= -github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= +github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= +github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= +github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= +github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= +github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= +github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= +github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= +github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= +github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= @@ -459,14 +386,13 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= -github.com/pganalyze/pg_query_go/v2 v2.1.0 h1:donwPZ4G/X+kMs7j5eYtKjdziqyOLVp3pkUrzb9lDl8= +github.com/pganalyze/pg_query_go/v4 v4.2.1 h1:id/vuyIQccb9f6Yx3pzH5l4QYrxE3v6/m8RPlgMrprc= +github.com/pganalyze/pg_query_go/v4 v4.2.1/go.mod h1:aEkDNOXNM5j0YGzaAapwJ7LB3dLNj+bvbWcLv1hOVqA= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= -github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -474,71 +400,60 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= 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/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_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= -github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= -github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= -github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= -github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/procfs v0.11.0 h1:5EAgkfkMl659uZPbe9AS2N68a7Cc1TJbPEuGzFuRbyk= +github.com/prometheus/procfs v0.11.0/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rs/cors v1.9.0 h1:l9HGsTsHJcvW14Nk7J9KFz8bzeAWXn3CG6bgt7LsrAE= +github.com/rs/cors v1.9.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= -github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= -github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= -github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -546,46 +461,31 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.3.0 h1:mjC+YW8QpAdXibNi+vNWgzmgBH4+5l5dCXv8cNysBLI= github.com/subosito/gotenv v1.3.0/go.mod h1:YzJjq/33h7nrwdY+iHMhEOEEbW0ovIz0tB6t6PwAXzs= github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= -github.com/thoas/go-funk v0.9.2 h1:oKlNYv0AY5nyf9g+/GhMgS/UO2ces0QRdPKwkhY3VCk= -github.com/thoas/go-funk v0.9.2/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= +github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw= +github.com/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= -github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= -github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa h1:5SqCsI/2Qya2bCzK15ozrqo2sZxkh0FHynJZOTVoV6Q= -github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= -github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +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/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= -github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= -github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= -github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= -github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= -github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= +github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= @@ -604,28 +504,23 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -636,8 +531,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg= -golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= +golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -651,7 +546,6 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRu golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= @@ -666,11 +560,9 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -679,7 +571,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -702,10 +593,9 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -726,12 +616,11 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -742,7 +631,6 @@ golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -776,30 +664,29 @@ golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.10.0 h1:3R7pNqamzBraeqj/Tj8qt1aQ2HpmlC+Cx/qL/7hn4/c= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -809,22 +696,17 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -875,7 +757,6 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -909,7 +790,6 @@ google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -946,8 +826,6 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -964,7 +842,6 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -977,22 +854,18 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= -gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= -gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= @@ -1002,9 +875,7 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20191120175047-4206685974f2/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg= @@ -1017,9 +888,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= -lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= -lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= +lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= +lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/internal/mocks/gen_indexer.go b/internal/mocks/gen_indexer.go new file mode 100644 index 0000000..72f0414 --- /dev/null +++ b/internal/mocks/gen_indexer.go @@ -0,0 +1,256 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/cerc-io/plugeth-statediff/indexer (interfaces: Indexer) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + context "context" + big "math/big" + reflect "reflect" + time "time" + + interfaces "github.com/cerc-io/plugeth-statediff/indexer/interfaces" + models "github.com/cerc-io/plugeth-statediff/indexer/models" + types "github.com/cerc-io/plugeth-statediff/types" + common "github.com/ethereum/go-ethereum/common" + types0 "github.com/ethereum/go-ethereum/core/types" + gomock "github.com/golang/mock/gomock" +) + +// MockgenIndexer is a mock of Indexer interface. +type MockgenIndexer struct { + ctrl *gomock.Controller + recorder *MockgenIndexerMockRecorder +} + +// MockgenIndexerMockRecorder is the mock recorder for MockgenIndexer. +type MockgenIndexerMockRecorder struct { + mock *MockgenIndexer +} + +// NewMockgenIndexer creates a new mock instance. +func NewMockgenIndexer(ctrl *gomock.Controller) *MockgenIndexer { + mock := &MockgenIndexer{ctrl: ctrl} + mock.recorder = &MockgenIndexerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockgenIndexer) EXPECT() *MockgenIndexerMockRecorder { + return m.recorder +} + +// BeginTx mocks base method. +func (m *MockgenIndexer) BeginTx(arg0 *big.Int, arg1 context.Context) interfaces.Batch { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BeginTx", arg0, arg1) + ret0, _ := ret[0].(interfaces.Batch) + return ret0 +} + +// BeginTx indicates an expected call of BeginTx. +func (mr *MockgenIndexerMockRecorder) BeginTx(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeginTx", reflect.TypeOf((*MockgenIndexer)(nil).BeginTx), arg0, arg1) +} + +// ClearWatchedAddresses mocks base method. +func (m *MockgenIndexer) ClearWatchedAddresses() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ClearWatchedAddresses") + ret0, _ := ret[0].(error) + return ret0 +} + +// ClearWatchedAddresses indicates an expected call of ClearWatchedAddresses. +func (mr *MockgenIndexerMockRecorder) ClearWatchedAddresses() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ClearWatchedAddresses", reflect.TypeOf((*MockgenIndexer)(nil).ClearWatchedAddresses)) +} + +// Close mocks base method. +func (m *MockgenIndexer) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close. +func (mr *MockgenIndexerMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockgenIndexer)(nil).Close)) +} + +// CurrentBlock mocks base method. +func (m *MockgenIndexer) CurrentBlock() (*models.HeaderModel, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CurrentBlock") + ret0, _ := ret[0].(*models.HeaderModel) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CurrentBlock indicates an expected call of CurrentBlock. +func (mr *MockgenIndexerMockRecorder) CurrentBlock() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentBlock", reflect.TypeOf((*MockgenIndexer)(nil).CurrentBlock)) +} + +// DetectGaps mocks base method. +func (m *MockgenIndexer) DetectGaps(arg0, arg1 uint64) ([]*interfaces.BlockGap, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DetectGaps", arg0, arg1) + ret0, _ := ret[0].([]*interfaces.BlockGap) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DetectGaps indicates an expected call of DetectGaps. +func (mr *MockgenIndexerMockRecorder) DetectGaps(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DetectGaps", reflect.TypeOf((*MockgenIndexer)(nil).DetectGaps), arg0, arg1) +} + +// HasBlock mocks base method. +func (m *MockgenIndexer) HasBlock(arg0 common.Hash, arg1 uint64) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "HasBlock", arg0, arg1) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// HasBlock indicates an expected call of HasBlock. +func (mr *MockgenIndexerMockRecorder) HasBlock(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "HasBlock", reflect.TypeOf((*MockgenIndexer)(nil).HasBlock), arg0, arg1) +} + +// InsertWatchedAddresses mocks base method. +func (m *MockgenIndexer) InsertWatchedAddresses(arg0 []types.WatchAddressArg, arg1 *big.Int) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "InsertWatchedAddresses", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// InsertWatchedAddresses indicates an expected call of InsertWatchedAddresses. +func (mr *MockgenIndexerMockRecorder) InsertWatchedAddresses(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InsertWatchedAddresses", reflect.TypeOf((*MockgenIndexer)(nil).InsertWatchedAddresses), arg0, arg1) +} + +// LoadWatchedAddresses mocks base method. +func (m *MockgenIndexer) LoadWatchedAddresses() ([]common.Address, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LoadWatchedAddresses") + ret0, _ := ret[0].([]common.Address) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// LoadWatchedAddresses indicates an expected call of LoadWatchedAddresses. +func (mr *MockgenIndexerMockRecorder) LoadWatchedAddresses() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LoadWatchedAddresses", reflect.TypeOf((*MockgenIndexer)(nil).LoadWatchedAddresses)) +} + +// PushBlock mocks base method. +func (m *MockgenIndexer) PushBlock(arg0 *types0.Block, arg1 types0.Receipts, arg2 *big.Int) (interfaces.Batch, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PushBlock", arg0, arg1, arg2) + ret0, _ := ret[0].(interfaces.Batch) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PushBlock indicates an expected call of PushBlock. +func (mr *MockgenIndexerMockRecorder) PushBlock(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushBlock", reflect.TypeOf((*MockgenIndexer)(nil).PushBlock), arg0, arg1, arg2) +} + +// PushHeader mocks base method. +func (m *MockgenIndexer) PushHeader(arg0 interfaces.Batch, arg1 *types0.Header, arg2, arg3 *big.Int) (string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PushHeader", arg0, arg1, arg2, arg3) + ret0, _ := ret[0].(string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// PushHeader indicates an expected call of PushHeader. +func (mr *MockgenIndexerMockRecorder) PushHeader(arg0, arg1, arg2, arg3 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushHeader", reflect.TypeOf((*MockgenIndexer)(nil).PushHeader), arg0, arg1, arg2, arg3) +} + +// PushIPLD mocks base method. +func (m *MockgenIndexer) PushIPLD(arg0 interfaces.Batch, arg1 types.IPLD) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PushIPLD", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// PushIPLD indicates an expected call of PushIPLD. +func (mr *MockgenIndexerMockRecorder) PushIPLD(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushIPLD", reflect.TypeOf((*MockgenIndexer)(nil).PushIPLD), arg0, arg1) +} + +// PushStateNode mocks base method. +func (m *MockgenIndexer) PushStateNode(arg0 interfaces.Batch, arg1 types.StateLeafNode, arg2 string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "PushStateNode", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// PushStateNode indicates an expected call of PushStateNode. +func (mr *MockgenIndexerMockRecorder) PushStateNode(arg0, arg1, arg2 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "PushStateNode", reflect.TypeOf((*MockgenIndexer)(nil).PushStateNode), arg0, arg1, arg2) +} + +// RemoveWatchedAddresses mocks base method. +func (m *MockgenIndexer) RemoveWatchedAddresses(arg0 []types.WatchAddressArg) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RemoveWatchedAddresses", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// RemoveWatchedAddresses indicates an expected call of RemoveWatchedAddresses. +func (mr *MockgenIndexerMockRecorder) RemoveWatchedAddresses(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RemoveWatchedAddresses", reflect.TypeOf((*MockgenIndexer)(nil).RemoveWatchedAddresses), arg0) +} + +// ReportDBMetrics mocks base method. +func (m *MockgenIndexer) ReportDBMetrics(arg0 time.Duration, arg1 <-chan bool) { + m.ctrl.T.Helper() + m.ctrl.Call(m, "ReportDBMetrics", arg0, arg1) +} + +// ReportDBMetrics indicates an expected call of ReportDBMetrics. +func (mr *MockgenIndexerMockRecorder) ReportDBMetrics(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReportDBMetrics", reflect.TypeOf((*MockgenIndexer)(nil).ReportDBMetrics), arg0, arg1) +} + +// SetWatchedAddresses mocks base method. +func (m *MockgenIndexer) SetWatchedAddresses(arg0 []types.WatchAddressArg, arg1 *big.Int) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetWatchedAddresses", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetWatchedAddresses indicates an expected call of SetWatchedAddresses. +func (mr *MockgenIndexerMockRecorder) SetWatchedAddresses(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetWatchedAddresses", reflect.TypeOf((*MockgenIndexer)(nil).SetWatchedAddresses), arg0, arg1) +} diff --git a/internal/mocks/indexer.go b/internal/mocks/indexer.go new file mode 100644 index 0000000..2a1f194 --- /dev/null +++ b/internal/mocks/indexer.go @@ -0,0 +1,88 @@ +package mocks + +import ( + "context" + "fmt" + "math/big" + "sync" + "testing" + + "github.com/cerc-io/plugeth-statediff/indexer" + sdtypes "github.com/cerc-io/plugeth-statediff/types" + "github.com/ethereum/go-ethereum/core/types" + "github.com/golang/mock/gomock" +) + +// Indexer just caches data but wraps a gomock instance, so we can mock other methods if needed +type Indexer struct { + *MockgenIndexer + sync.RWMutex + + IndexerData +} + +type IndexerData struct { + Headers map[uint64]*types.Header + StateNodes []sdtypes.StateLeafNode + IPLDs []sdtypes.IPLD +} + +// no-op mock Batch +type Batch struct{} + +// NewIndexer returns a mock indexer that caches data in lists +func NewIndexer(t *testing.T) *Indexer { + ctl := gomock.NewController(t) + return &Indexer{ + MockgenIndexer: NewMockgenIndexer(ctl), + IndexerData: IndexerData{ + Headers: make(map[uint64]*types.Header), + }, + } +} + +func (i *Indexer) PushHeader(_ indexer.Batch, header *types.Header, _, _ *big.Int) (string, error) { + i.Lock() + defer i.Unlock() + i.Headers[header.Number.Uint64()] = header + return header.Hash().String(), nil +} + +func (i *Indexer) PushStateNode(_ indexer.Batch, stateNode sdtypes.StateLeafNode, _ string) error { + i.Lock() + defer i.Unlock() + i.StateNodes = append(i.StateNodes, stateNode) + return nil +} + +func (i *Indexer) PushIPLD(_ indexer.Batch, ipld sdtypes.IPLD) error { + i.Lock() + defer i.Unlock() + i.IPLDs = append(i.IPLDs, ipld) + return nil +} + +func (i *Indexer) BeginTx(_ *big.Int, _ context.Context) indexer.Batch { + return Batch{} +} + +func (Batch) Submit() error { return nil } +func (Batch) BlockNumber() string { return "0" } +func (Batch) RollbackOnFailure(error) {} + +// InterruptingIndexer triggers an artificial failure at a specific node count +type InterruptingIndexer struct { + *Indexer + + InterruptAfter uint +} + +func (i *InterruptingIndexer) PushStateNode(b indexer.Batch, stateNode sdtypes.StateLeafNode, h string) error { + i.RLock() + indexedCount := len(i.StateNodes) + i.RUnlock() + if indexedCount >= int(i.InterruptAfter) { + return fmt.Errorf("mock interrupt") + } + return i.Indexer.PushStateNode(b, stateNode, h) +} diff --git a/pkg/prom/db_stats_collector.go b/pkg/prom/db_stats_collector.go index 7c77494..fd4eb5b 100644 --- a/pkg/prom/db_stats_collector.go +++ b/pkg/prom/db_stats_collector.go @@ -19,7 +19,7 @@ package prom import ( "github.com/prometheus/client_golang/prometheus" - mets "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" + mets "github.com/cerc-io/plugeth-statediff/indexer/database/metrics" ) // DBStatsGetter is an interface that gets sql.DBStats. diff --git a/pkg/prom/tracker.go b/pkg/prom/tracker.go new file mode 100644 index 0000000..74bf6c6 --- /dev/null +++ b/pkg/prom/tracker.go @@ -0,0 +1,133 @@ +package prom + +import ( + "fmt" + "sync" + "sync/atomic" + + iterutil "github.com/cerc-io/eth-iterator-utils" + "github.com/cerc-io/eth-iterator-utils/tracker" + "github.com/ethereum/go-ethereum/trie" +) + +var trackedIterCount atomic.Int32 + +// Tracker which wraps a tracked iterators in metrics-reporting iterators +type MetricsTracker struct { + *tracker.TrackerImpl +} + +type metricsIterator struct { + trie.NodeIterator + id int32 + // count uint + done bool + lastPath []byte + sync.RWMutex +} + +func NewTracker(file string, bufsize uint) *MetricsTracker { + return &MetricsTracker{TrackerImpl: tracker.NewImpl(file, bufsize)} +} + +func (t *MetricsTracker) wrap(tracked *tracker.Iterator) *metricsIterator { + startPath, endPath := tracked.Bounds() + startDepth := max(len(startPath), len(endPath)) + ret := &metricsIterator{ + NodeIterator: tracked, + id: trackedIterCount.Add(1), + } + RegisterGaugeFunc( + fmt.Sprintf("tracked_iterator_%d", ret.id), + func() float64 { + ret.RLock() + if ret.done { + return 1 + } + lastPath := ret.lastPath + ret.RUnlock() + if lastPath == nil { + return 0 + } + // estimate remaining distance based on current position and node count + depth := max(startDepth, len(lastPath)) + startPath := normalizePath(startPath, depth) + endPath := normalizePath(endPath, depth) + progressed := subtractPaths(lastPath, startPath) + total := subtractPaths(endPath, startPath) + return float64(countSteps(progressed, depth)) / float64(countSteps(total, depth)) + }) + return ret +} + +func (t *MetricsTracker) Restore(ctor iterutil.IteratorConstructor) ( + []trie.NodeIterator, []trie.NodeIterator, error, +) { + iters, bases, err := t.TrackerImpl.Restore(ctor) + if err != nil { + return nil, nil, err + } + ret := make([]trie.NodeIterator, len(iters)) + for i, tracked := range iters { + ret[i] = t.wrap(tracked) + } + return ret, bases, nil +} + +func (t *MetricsTracker) Tracked(it trie.NodeIterator) trie.NodeIterator { + tracked := t.TrackerImpl.Tracked(it) + return t.wrap(tracked) +} + +func (it *metricsIterator) Next(descend bool) bool { + ret := it.NodeIterator.Next(descend) + it.Lock() + defer it.Unlock() + if ret { + it.lastPath = it.Path() + } else { + it.done = true + } + return ret +} + +func normalizePath(path []byte, depth int) []byte { + normalized := make([]byte, depth) + for i := 0; i < depth; i++ { + if i < len(path) { + normalized[i] = path[i] + } + } + return normalized +} + +// Subtract each component, right to left, carrying over if necessary. +func subtractPaths(a, b []byte) []byte { + diff := make([]byte, len(a)) + carry := false + for i := len(a) - 1; i >= 0; i-- { + diff[i] = a[i] - b[i] + if carry { + diff[i]-- + } + carry = a[i] < b[i] + } + return diff +} + +// count total steps in a path according to its depth (length) +func countSteps(path []byte, depth int) uint { + var steps uint + for _, b := range path { + steps *= 16 + steps += uint(b) + } + return steps +} + +func max(a int, b int) int { + if a > b { + return a + } + return b +} diff --git a/pkg/snapshot/config.go b/pkg/snapshot/config.go index d2449ff..72a4066 100644 --- a/pkg/snapshot/config.go +++ b/pkg/snapshot/config.go @@ -23,8 +23,9 @@ import ( "github.com/sirupsen/logrus" - "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" - ethNode "github.com/ethereum/go-ethereum/statediff/indexer/node" + "github.com/cerc-io/plugeth-statediff/indexer/database/file" + "github.com/cerc-io/plugeth-statediff/indexer/database/sql/postgres" + ethNode "github.com/cerc-io/plugeth-statediff/indexer/node" "github.com/spf13/viper" ) @@ -53,18 +54,15 @@ type EthConfig struct { NodeInfo ethNode.Info } -// DBConfig is config parameters for DB. -type DBConfig struct { - URI string - ConnConfig postgres.Config -} +// DBConfig contains options for DB output mode. +type DBConfig = postgres.Config -type FileConfig struct { - OutputDir string -} +// FileConfig contains options for file output mode. Note that this service currently only supports +// CSV output, and does not record watched addresses, so not all fields are used. +type FileConfig = file.Config type ServiceConfig struct { - AllowedAccounts map[common.Address]struct{} + AllowedAccounts []common.Address } func NewConfig(mode SnapshotMode) (*Config, error) { @@ -84,14 +82,14 @@ func NewInPlaceSnapshotConfig() *Config { &FileConfig{}, &ServiceConfig{}, } - ret.DB.Init() + InitDB(ret.DB) return ret } // Init Initialises config func (c *Config) Init(mode SnapshotMode) error { - viper.BindEnv(LOGRUS_FILE_TOML, LOGRUS_FILE) + viper.BindEnv(LOG_FILE_TOML, LOG_FILE) viper.BindEnv(ETH_NODE_ID_TOML, ETH_NODE_ID) viper.BindEnv(ETH_CLIENT_NAME_TOML, ETH_CLIENT_NAME) viper.BindEnv(ETH_GENESIS_BLOCK_TOML, ETH_GENESIS_BLOCK) @@ -106,24 +104,24 @@ func (c *Config) Init(mode SnapshotMode) error { ChainID: viper.GetUint64(ETH_CHAIN_ID_TOML), } - viper.BindEnv(ANCIENT_DB_PATH_TOML, ANCIENT_DB_PATH) - viper.BindEnv(LVL_DB_PATH_TOML, LVL_DB_PATH) + viper.BindEnv(LEVELDB_ANCIENT_TOML, LEVELDB_ANCIENT) + viper.BindEnv(LEVELDB_PATH_TOML, LEVELDB_PATH) - c.Eth.AncientDBPath = viper.GetString(ANCIENT_DB_PATH_TOML) - c.Eth.LevelDBPath = viper.GetString(LVL_DB_PATH_TOML) + c.Eth.AncientDBPath = viper.GetString(LEVELDB_ANCIENT_TOML) + c.Eth.LevelDBPath = viper.GetString(LEVELDB_PATH_TOML) switch mode { case FileSnapshot: - c.File.Init() + InitFile(c.File) case PgSnapshot: - c.DB.Init() + InitDB(c.DB) default: return fmt.Errorf("no output mode specified") } return c.Service.Init() } -func (c *DBConfig) Init() { +func InitDB(c *DBConfig) { viper.BindEnv(DATABASE_NAME_TOML, DATABASE_NAME) viper.BindEnv(DATABASE_HOSTNAME_TOML, DATABASE_HOSTNAME) viper.BindEnv(DATABASE_PORT_TOML, DATABASE_PORT) @@ -133,38 +131,38 @@ func (c *DBConfig) Init() { viper.BindEnv(DATABASE_MAX_OPEN_CONNECTIONS_TOML, DATABASE_MAX_OPEN_CONNECTIONS) viper.BindEnv(DATABASE_MAX_CONN_LIFETIME_TOML, DATABASE_MAX_CONN_LIFETIME) - dbParams := postgres.Config{} // DB params - dbParams.DatabaseName = viper.GetString(DATABASE_NAME_TOML) - dbParams.Hostname = viper.GetString(DATABASE_HOSTNAME_TOML) - dbParams.Port = viper.GetInt(DATABASE_PORT_TOML) - dbParams.Username = viper.GetString(DATABASE_USER_TOML) - dbParams.Password = viper.GetString(DATABASE_PASSWORD_TOML) + c.DatabaseName = viper.GetString(DATABASE_NAME_TOML) + c.Hostname = viper.GetString(DATABASE_HOSTNAME_TOML) + c.Port = viper.GetInt(DATABASE_PORT_TOML) + c.Username = viper.GetString(DATABASE_USER_TOML) + c.Password = viper.GetString(DATABASE_PASSWORD_TOML) // Connection config - dbParams.MaxIdle = viper.GetInt(DATABASE_MAX_IDLE_CONNECTIONS_TOML) - dbParams.MaxConns = viper.GetInt(DATABASE_MAX_OPEN_CONNECTIONS_TOML) - dbParams.MaxConnLifetime = time.Duration(viper.GetInt(DATABASE_MAX_CONN_LIFETIME_TOML)) * time.Second + c.MaxIdle = viper.GetInt(DATABASE_MAX_IDLE_CONNECTIONS_TOML) + c.MaxConns = viper.GetInt(DATABASE_MAX_OPEN_CONNECTIONS_TOML) + c.MaxConnLifetime = time.Duration(viper.GetInt(DATABASE_MAX_CONN_LIFETIME_TOML)) * time.Second - c.ConnConfig = dbParams - c.URI = dbParams.DbConnectionString() + c.Driver = postgres.SQLX } -func (c *FileConfig) Init() error { +func InitFile(c *FileConfig) error { viper.BindEnv(FILE_OUTPUT_DIR_TOML, FILE_OUTPUT_DIR) c.OutputDir = viper.GetString(FILE_OUTPUT_DIR_TOML) if c.OutputDir == "" { logrus.Infof("no output directory set, using default: %s", defaultOutputDir) c.OutputDir = defaultOutputDir } + // Only support CSV for now + c.Mode = file.CSV return nil } func (c *ServiceConfig) Init() error { viper.BindEnv(SNAPSHOT_BLOCK_HEIGHT_TOML, SNAPSHOT_BLOCK_HEIGHT) - viper.BindEnv(SNAPSHOT_START_HEIGHT_TOML, SNAPSHOT_START_HEIGHT) - viper.BindEnv(SNAPSHOT_END_HEIGHT_TOML, SNAPSHOT_END_HEIGHT) viper.BindEnv(SNAPSHOT_MODE_TOML, SNAPSHOT_MODE) viper.BindEnv(SNAPSHOT_WORKERS_TOML, SNAPSHOT_WORKERS) + viper.BindEnv(SNAPSHOT_RECOVERY_FILE_TOML, SNAPSHOT_RECOVERY_FILE) + viper.BindEnv(PROM_HTTP_TOML, PROM_HTTP) viper.BindEnv(PROM_HTTP_ADDR_TOML, PROM_HTTP_ADDR) viper.BindEnv(PROM_METRICS_TOML, PROM_METRICS) @@ -174,9 +172,9 @@ func (c *ServiceConfig) Init() error { viper.UnmarshalKey(SNAPSHOT_ACCOUNTS_TOML, &allowedAccounts) accountsLen := len(allowedAccounts) if accountsLen != 0 { - c.AllowedAccounts = make(map[common.Address]struct{}, accountsLen) + c.AllowedAccounts = make([]common.Address, 0, accountsLen) for _, allowedAccount := range allowedAccounts { - c.AllowedAccounts[common.HexToAddress(allowedAccount)] = struct{}{} + c.AllowedAccounts = append(c.AllowedAccounts, common.HexToAddress(allowedAccount)) } } else { logrus.Infof("no snapshot addresses specified, will perform snapshot of entire trie(s)") diff --git a/pkg/snapshot/config_test.go b/pkg/snapshot/config_test.go new file mode 100644 index 0000000..c5a1174 --- /dev/null +++ b/pkg/snapshot/config_test.go @@ -0,0 +1,27 @@ +package snapshot_test + +import ( + "github.com/cerc-io/plugeth-statediff/indexer/database/sql/postgres" + ethnode "github.com/cerc-io/plugeth-statediff/indexer/node" +) + +var ( + DefaultNodeInfo = ethnode.Info{ + ID: "test_nodeid", + ClientName: "test_client", + GenesisBlock: "TEST_GENESIS", + NetworkID: "test_network", + ChainID: 0, + } + DefaultPgConfig = postgres.Config{ + Hostname: "localhost", + Port: 8077, + DatabaseName: "cerc_testing", + Username: "vdbm", + Password: "password", + + MaxIdle: 0, + MaxConnLifetime: 0, + MaxConns: 4, + } +) diff --git a/pkg/snapshot/env.go b/pkg/snapshot/env.go index a592726..5ac202d 100644 --- a/pkg/snapshot/env.go +++ b/pkg/snapshot/env.go @@ -21,12 +21,10 @@ const ( SNAPSHOT_WORKERS = "SNAPSHOT_WORKERS" SNAPSHOT_RECOVERY_FILE = "SNAPSHOT_RECOVERY_FILE" SNAPSHOT_MODE = "SNAPSHOT_MODE" - SNAPSHOT_START_HEIGHT = "SNAPSHOT_START_HEIGHT" - SNAPSHOT_END_HEIGHT = "SNAPSHOT_END_HEIGHT" SNAPSHOT_ACCOUNTS = "SNAPSHOT_ACCOUNTS" - LOGRUS_LEVEL = "LOGRUS_LEVEL" - LOGRUS_FILE = "LOGRUS_FILE" + LOG_LEVEL = "LOG_LEVEL" + LOG_FILE = "LOG_FILE" PROM_METRICS = "PROM_METRICS" PROM_HTTP = "PROM_HTTP" @@ -36,8 +34,8 @@ const ( FILE_OUTPUT_DIR = "FILE_OUTPUT_DIR" - ANCIENT_DB_PATH = "ANCIENT_DB_PATH" - LVL_DB_PATH = "LVL_DB_PATH" + LEVELDB_ANCIENT = "LEVELDB_ANCIENT" + LEVELDB_PATH = "LEVELDB_PATH" ETH_CLIENT_NAME = "ETH_CLIENT_NAME" ETH_GENESIS_BLOCK = "ETH_GENESIS_BLOCK" @@ -61,12 +59,10 @@ const ( SNAPSHOT_WORKERS_TOML = "snapshot.workers" SNAPSHOT_RECOVERY_FILE_TOML = "snapshot.recoveryFile" SNAPSHOT_MODE_TOML = "snapshot.mode" - SNAPSHOT_START_HEIGHT_TOML = "snapshot.startHeight" - SNAPSHOT_END_HEIGHT_TOML = "snapshot.endHeight" SNAPSHOT_ACCOUNTS_TOML = "snapshot.accounts" - LOGRUS_LEVEL_TOML = "log.level" - LOGRUS_FILE_TOML = "log.file" + LOG_LEVEL_TOML = "log.level" + LOG_FILE_TOML = "log.file" PROM_METRICS_TOML = "prom.metrics" PROM_HTTP_TOML = "prom.http" @@ -76,8 +72,8 @@ const ( FILE_OUTPUT_DIR_TOML = "file.outputDir" - ANCIENT_DB_PATH_TOML = "leveldb.ancient" - LVL_DB_PATH_TOML = "leveldb.path" + LEVELDB_ANCIENT_TOML = "leveldb.ancient" + LEVELDB_PATH_TOML = "leveldb.path" ETH_CLIENT_NAME_TOML = "ethereum.clientName" ETH_GENESIS_BLOCK_TOML = "ethereum.genesisBlock" @@ -101,12 +97,10 @@ const ( SNAPSHOT_WORKERS_CLI = "workers" SNAPSHOT_RECOVERY_FILE_CLI = "recovery-file" SNAPSHOT_MODE_CLI = "snapshot-mode" - SNAPSHOT_START_HEIGHT_CLI = "start-height" - SNAPSHOT_END_HEIGHT_CLI = "end-height" SNAPSHOT_ACCOUNTS_CLI = "snapshot-accounts" - LOGRUS_LEVEL_CLI = "log-level" - LOGRUS_FILE_CLI = "log-file" + LOG_LEVEL_CLI = "log-level" + LOG_FILE_CLI = "log-file" PROM_METRICS_CLI = "prom-metrics" PROM_HTTP_CLI = "prom-http" @@ -116,8 +110,8 @@ const ( FILE_OUTPUT_DIR_CLI = "output-dir" - ANCIENT_DB_PATH_CLI = "ancient-path" - LVL_DB_PATH_CLI = "leveldb-path" + LEVELDB_ANCIENT_CLI = "ancient-path" + LEVELDB_PATH_CLI = "leveldb-path" ETH_CLIENT_NAME_CLI = "ethereum-client-name" ETH_GENESIS_BLOCK_CLI = "ethereum-genesis-block" diff --git a/pkg/snapshot/file/publisher.go b/pkg/snapshot/file/publisher.go deleted file mode 100644 index 61e8f5d..0000000 --- a/pkg/snapshot/file/publisher.go +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright © 2020 Vulcanize, Inc -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package publisher - -import ( - "encoding/csv" - "fmt" - "math/big" - "os" - "path/filepath" - "strconv" - "sync/atomic" - "time" - - "github.com/lib/pq" - - "github.com/ipfs/go-cid" - "github.com/sirupsen/logrus" - - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/statediff/indexer/ipld" - "github.com/ethereum/go-ethereum/statediff/indexer/models" - nodeinfo "github.com/ethereum/go-ethereum/statediff/indexer/node" - "github.com/ethereum/go-ethereum/statediff/indexer/shared/schema" - - "github.com/cerc-io/ipld-eth-state-snapshot/pkg/prom" - snapt "github.com/cerc-io/ipld-eth-state-snapshot/pkg/types" -) - -var _ snapt.Publisher = (*publisher)(nil) - -var ( - // tables written once per block - perBlockTables = []*schema.Table{ - &schema.TableIPLDBlock, - &schema.TableNodeInfo, - &schema.TableHeader, - } - // tables written during state iteration - perNodeTables = []*schema.Table{ - &schema.TableIPLDBlock, - &schema.TableStateNode, - &schema.TableStorageNode, - } -) - -const logInterval = 1 * time.Minute - -type publisher struct { - dir string // dir containing output files - writers fileWriters - - nodeInfo nodeinfo.Info - - startTime time.Time - currBatchSize uint - stateNodeCounter uint64 - storageNodeCounter uint64 - codeNodeCounter uint64 - txCounter uint32 -} - -type fileWriter struct { - *csv.Writer -} - -// fileWriters wraps the file writers for each output table -type fileWriters map[string]fileWriter - -type fileTx struct{ fileWriters } - -func (tx fileWriters) Commit() error { - for _, w := range tx { - w.Flush() - if err := w.Error(); err != nil { - return err - } - } - return nil -} -func (fileWriters) Rollback() error { return nil } // TODO: delete the file? - -func newFileWriter(path string) (ret fileWriter, err error) { - file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) - if err != nil { - return - } - ret = fileWriter{csv.NewWriter(file)} - return -} - -func (tx fileWriters) write(tbl *schema.Table, args ...interface{}) error { - row := tbl.ToCsvRow(args...) - return tx[tbl.Name].Write(row) -} - -func makeFileWriters(dir string, tables []*schema.Table) (fileWriters, error) { - if err := os.MkdirAll(dir, 0755); err != nil { - return nil, err - } - writers := fileWriters{} - for _, tbl := range tables { - w, err := newFileWriter(TableFile(dir, tbl.Name)) - if err != nil { - return nil, err - } - writers[tbl.Name] = w - } - return writers, nil -} - -// NewPublisher creates a publisher which writes to per-table CSV files which can be imported -// with the Postgres COPY command. -// The output directory will be created if it does not exist. -func NewPublisher(path string, node nodeinfo.Info) (*publisher, error) { - if err := os.MkdirAll(path, 0777); err != nil { - return nil, fmt.Errorf("unable to make MkdirAll for path: %s err: %s", path, err) - } - writers, err := makeFileWriters(path, perBlockTables) - if err != nil { - return nil, err - } - pub := &publisher{ - writers: writers, - dir: path, - nodeInfo: node, - startTime: time.Now(), - } - go pub.logNodeCounters() - return pub, nil -} - -func TableFile(dir, name string) string { return filepath.Join(dir, name+".csv") } - -func (p *publisher) txDir(index uint32) string { - return filepath.Join(p.dir, fmt.Sprintf("%010d", index)) -} - -func (p *publisher) BeginTx() (snapt.Tx, error) { - index := atomic.AddUint32(&p.txCounter, 1) - 1 - dir := p.txDir(index) - writers, err := makeFileWriters(dir, perNodeTables) - if err != nil { - return nil, err - } - - return fileTx{writers}, nil -} - -func (tx fileWriters) publishIPLD(c cid.Cid, raw []byte, height *big.Int) error { - return tx.write(&schema.TableIPLDBlock, height.String(), c.String(), raw) -} - -// PublishIPLD writes an IPLD to the ipld.blocks blockstore -func (p *publisher) PublishIPLD(c cid.Cid, raw []byte, height *big.Int, snapTx snapt.Tx) error { - tx := snapTx.(fileTx) - return tx.publishIPLD(c, raw, height) -} - -// PublishHeader writes the header to the ipfs backing pg datastore and adds secondary -// indexes in the header_cids table -func (p *publisher) PublishHeader(header *types.Header) error { - headerNode, err := ipld.NewEthHeader(header) - if err != nil { - return err - } - if err := p.writers.publishIPLD(headerNode.Cid(), headerNode.RawData(), header.Number); err != nil { - return err - } - - err = p.writers.write(&schema.TableNodeInfo, p.nodeInfo.GenesisBlock, p.nodeInfo.NetworkID, p.nodeInfo.ID, - p.nodeInfo.ClientName, p.nodeInfo.ChainID) - if err != nil { - return err - } - err = p.writers.write(&schema.TableHeader, - header.Number.String(), - header.Hash().Hex(), - header.ParentHash.Hex(), - headerNode.Cid().String(), - "0", - pq.StringArray([]string{p.nodeInfo.ID}), - "0", - header.Root.Hex(), - header.TxHash.Hex(), - header.ReceiptHash.Hex(), - header.UncleHash.Hex(), - header.Bloom.Bytes(), - strconv.FormatUint(header.Time, 10), - header.Coinbase.String(), - true, - ) - if err != nil { - return err - } - return p.writers.Commit() -} - -// PublishStateLeafNode writes the state node eth.state_cids -func (p *publisher) PublishStateLeafNode(stateNode *models.StateNodeModel, snapTx snapt.Tx) error { - tx := snapTx.(fileTx) - - err := tx.write(&schema.TableStateNode, - stateNode.BlockNumber, - stateNode.HeaderID, - stateNode.StateKey, - stateNode.CID, - false, - stateNode.Balance, - strconv.FormatUint(stateNode.Nonce, 10), - stateNode.CodeHash, - stateNode.StorageRoot, - false) - if err != nil { - return err - } - // increment state node counter. - atomic.AddUint64(&p.stateNodeCounter, 1) - prom.IncStateNodeCount() - - // increment current batch size counter - p.currBatchSize += 2 - return err -} - -// PublishStorageLeafNode writes the storage node to eth.storage_cids -func (p *publisher) PublishStorageLeafNode(storageNode *models.StorageNodeModel, snapTx snapt.Tx) error { - tx := snapTx.(fileTx) - - err := tx.write(&schema.TableStorageNode, - storageNode.BlockNumber, - storageNode.HeaderID, - storageNode.StateKey, - storageNode.StorageKey, - storageNode.CID, - false, - storageNode.Value, - false) - if err != nil { - return err - } - // increment storage node counter. - atomic.AddUint64(&p.storageNodeCounter, 1) - prom.IncStorageNodeCount() - - // increment current batch size counter - p.currBatchSize += 2 - return nil -} - -func (p *publisher) PrepareTxForBatch(tx snapt.Tx, maxBatchSize uint) (snapt.Tx, error) { - return tx, nil -} - -// logNodeCounters periodically logs the number of node processed. -func (p *publisher) logNodeCounters() { - t := time.NewTicker(logInterval) - for range t.C { - p.printNodeCounters("progress") - } -} - -func (p *publisher) printNodeCounters(msg string) { - logrus.WithFields(logrus.Fields{ - "runtime": time.Now().Sub(p.startTime).String(), - "state nodes": atomic.LoadUint64(&p.stateNodeCounter), - "storage nodes": atomic.LoadUint64(&p.storageNodeCounter), - "code nodes": atomic.LoadUint64(&p.codeNodeCounter), - }).Info(msg) -} diff --git a/pkg/snapshot/file/publisher_test.go b/pkg/snapshot/file/publisher_test.go deleted file mode 100644 index 69541e6..0000000 --- a/pkg/snapshot/file/publisher_test.go +++ /dev/null @@ -1,130 +0,0 @@ -package publisher - -import ( - "context" - "encoding/csv" - "fmt" - "io" - "os" - "path/filepath" - "testing" - - "github.com/ethereum/go-ethereum/statediff/indexer/shared/schema" - - "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" - "github.com/ethereum/go-ethereum/statediff/indexer/ipld" - "github.com/ethereum/go-ethereum/statediff/indexer/test_helpers" - - fixt "github.com/cerc-io/ipld-eth-state-snapshot/fixture" - "github.com/cerc-io/ipld-eth-state-snapshot/test" -) - -var ( - pgConfig = test.DefaultPgConfig - nodeInfo = test.DefaultNodeInfo - // tables ordered according to fkey depedencies - allTables = []*schema.Table{ - &schema.TableIPLDBlock, - &schema.TableNodeInfo, - &schema.TableHeader, - &schema.TableStateNode, - &schema.TableStorageNode, - } -) - -func writeFiles(t *testing.T, dir string) *publisher { - pub, err := NewPublisher(dir, nodeInfo) - test.NoError(t, err) - test.NoError(t, pub.PublishHeader(&fixt.Block1_Header)) - tx, err := pub.BeginTx() - test.NoError(t, err) - - test.NoError(t, pub.PublishStateLeafNode(&fixt.Block1_StateNode0, tx)) - - test.NoError(t, tx.Commit()) - return pub -} - -// verify that we can parse the csvs -// TODO check actual data -func verifyFileData(t *testing.T, path string, tbl *schema.Table) { - file, err := os.Open(path) - test.NoError(t, err) - r := csv.NewReader(file) - test.NoError(t, err) - r.FieldsPerRecord = len(tbl.Columns) - - for { - _, err := r.Read() - if err == io.EOF { - break - } - test.NoError(t, err) - } -} - -func TestWriting(t *testing.T) { - dir := t.TempDir() - // tempdir like /tmp/TempFoo/001/, TempFoo defaults to 0700 - test.NoError(t, os.Chmod(filepath.Dir(dir), 0755)) - - pub := writeFiles(t, dir) - - for _, tbl := range perBlockTables { - verifyFileData(t, TableFile(pub.dir, tbl.Name), tbl) - } - for i := uint32(0); i < pub.txCounter; i++ { - for _, tbl := range perNodeTables { - verifyFileData(t, TableFile(pub.txDir(i), tbl.Name), tbl) - } - } -} - -// Note: DB user requires role membership "pg_read_server_files" -func TestPgCopy(t *testing.T) { - test.NeedsDB(t) - - dir := t.TempDir() - test.NoError(t, os.Chmod(filepath.Dir(dir), 0755)) - pub := writeFiles(t, dir) - - ctx := context.Background() - driver, err := postgres.NewSQLXDriver(ctx, pgConfig, nodeInfo) - test.NoError(t, err) - db := postgres.NewPostgresDB(driver, false) - - test_helpers.TearDownDB(t, db) - - // copy from files - pgCopyStatement := `COPY %s FROM '%s' CSV` - for _, tbl := range perBlockTables { - stm := fmt.Sprintf(pgCopyStatement, tbl.Name, TableFile(pub.dir, tbl.Name)) - _, err = db.Exec(ctx, stm) - test.NoError(t, err) - } - for i := uint32(0); i < pub.txCounter; i++ { - for _, tbl := range perNodeTables { - stm := fmt.Sprintf(pgCopyStatement, tbl.Name, TableFile(pub.txDir(i), tbl.Name)) - _, err = db.Exec(ctx, stm) - test.NoError(t, err) - } - } - - // check header was successfully committed - pgQueryHeader := `SELECT cid, block_hash - FROM eth.header_cids - WHERE block_number = $1` - type res struct { - CID string - BlockHash string - } - var header res - err = db.QueryRow(ctx, pgQueryHeader, fixt.Block1_Header.Number.Uint64()).Scan( - &header.CID, &header.BlockHash) - test.NoError(t, err) - - headerNode, err := ipld.NewEthHeader(&fixt.Block1_Header) - test.NoError(t, err) - test.ExpectEqual(t, headerNode.Cid().String(), header.CID) - test.ExpectEqual(t, fixt.Block1_Header.Hash().String(), header.BlockHash) -} diff --git a/pkg/snapshot/mock/util.go b/pkg/snapshot/mock/util.go deleted file mode 100644 index e6f5430..0000000 --- a/pkg/snapshot/mock/util.go +++ /dev/null @@ -1,26 +0,0 @@ -package mock - -import ( - "fmt" - - "github.com/golang/mock/gomock" -) - -type anyOfMatcher struct { - values []interface{} -} - -func (m anyOfMatcher) Matches(x interface{}) bool { - for _, v := range m.values { - if gomock.Eq(v).Matches(x) { - return true - } - } - return false -} -func (m anyOfMatcher) String() string { - return fmt.Sprintf("is equal to any of %+v", m.values) -} -func AnyOf(xs ...interface{}) anyOfMatcher { - return anyOfMatcher{xs} -} diff --git a/pkg/snapshot/pg/publisher.go b/pkg/snapshot/pg/publisher.go deleted file mode 100644 index 12d98e2..0000000 --- a/pkg/snapshot/pg/publisher.go +++ /dev/null @@ -1,230 +0,0 @@ -// Copyright © 2020 Vulcanize, Inc -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package pg - -import ( - "context" - "math/big" - "strconv" - "sync/atomic" - "time" - - "github.com/ipfs/go-cid" - "github.com/lib/pq" - "github.com/sirupsen/logrus" - log "github.com/sirupsen/logrus" - - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" - "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" - "github.com/ethereum/go-ethereum/statediff/indexer/ipld" - "github.com/ethereum/go-ethereum/statediff/indexer/models" - "github.com/ethereum/go-ethereum/statediff/indexer/shared/schema" - - "github.com/cerc-io/ipld-eth-state-snapshot/pkg/prom" - snapt "github.com/cerc-io/ipld-eth-state-snapshot/pkg/types" -) - -var _ snapt.Publisher = (*publisher)(nil) - -const logInterval = 1 * time.Minute - -// Publisher is wrapper around DB. -type publisher struct { - db *postgres.DB - currBatchSize uint - stateNodeCounter uint64 - storageNodeCounter uint64 - codeNodeCounter uint64 - startTime time.Time -} - -// NewPublisher creates Publisher -func NewPublisher(db *postgres.DB) *publisher { - return &publisher{ - db: db, - startTime: time.Now(), - } -} - -type pubTx struct { - sql.Tx - callback func() -} - -func (tx pubTx) Rollback() error { return tx.Tx.Rollback(context.Background()) } -func (tx pubTx) Commit() error { - if tx.callback != nil { - defer tx.callback() - } - return tx.Tx.Commit(context.Background()) -} -func (tx pubTx) Exec(sql string, args ...interface{}) (sql.Result, error) { - return tx.Tx.Exec(context.Background(), sql, args...) -} - -func (p *publisher) BeginTx() (snapt.Tx, error) { - tx, err := p.db.Begin(context.Background()) - if err != nil { - return nil, err - } - go p.logNodeCounters() - return pubTx{tx, func() { - p.printNodeCounters("final stats") - }}, nil -} - -func (tx pubTx) publishIPLD(c cid.Cid, raw []byte, height *big.Int) error { - _, err := tx.Exec(schema.TableIPLDBlock.ToInsertStatement(false), height.Uint64(), c.String(), raw) - return err -} - -// PublishIPLD writes an IPLD to the ipld.blocks blockstore -func (p *publisher) PublishIPLD(c cid.Cid, raw []byte, height *big.Int, snapTx snapt.Tx) error { - tx := snapTx.(pubTx) - return tx.publishIPLD(c, raw, height) -} - -// PublishHeader writes the header to the ipfs backing pg datastore and adds secondary indexes in the header_cids table -func (p *publisher) PublishHeader(header *types.Header) (err error) { - headerNode, err := ipld.NewEthHeader(header) - if err != nil { - return err - } - - snapTx, err := p.db.Begin(context.Background()) - if err != nil { - return err - } - tx := pubTx{snapTx, nil} - // we must avoid overshadowing the `err` - defer func() { - err = snapt.CommitOrRollback(tx, err) - if err != nil { - logrus.Errorf("CommitOrRollback failed: %s", err) - } - }() - - if err = tx.publishIPLD(headerNode.Cid(), headerNode.RawData(), header.Number); err != nil { - return err - } - - _, err = tx.Exec(schema.TableHeader.ToInsertStatement(false), - header.Number.Uint64(), - header.Hash().Hex(), - header.ParentHash.Hex(), - headerNode.Cid().String(), - "0", - pq.StringArray([]string{p.db.NodeID()}), - "0", - header.Root.Hex(), - header.TxHash.Hex(), - header.ReceiptHash.Hex(), - header.UncleHash.Hex(), - header.Bloom.Bytes(), - strconv.FormatUint(header.Time, 10), - header.Coinbase.String(), - true, - ) - return err -} - -// PublishStateLeafNode writes the state leaf node to eth.state_cids -func (p *publisher) PublishStateLeafNode(stateNode *models.StateNodeModel, snapTx snapt.Tx) error { - tx := snapTx.(pubTx) - _, err := tx.Exec(schema.TableStateNode.ToInsertStatement(false), - stateNode.BlockNumber, - stateNode.HeaderID, - stateNode.StateKey, - stateNode.CID, - false, - stateNode.Balance, - stateNode.Nonce, - stateNode.CodeHash, - stateNode.StorageRoot, - false) - if err != nil { - return err - } - // increment state node counter. - atomic.AddUint64(&p.stateNodeCounter, 1) - prom.IncStateNodeCount() - - // increment current batch size counter - p.currBatchSize += 2 - return err -} - -// PublishStorageLeafNode writes the storage leaf node to eth.storage_cids -func (p *publisher) PublishStorageLeafNode(storageNode *models.StorageNodeModel, snapTx snapt.Tx) error { - tx := snapTx.(pubTx) - _, err := tx.Exec(schema.TableStorageNode.ToInsertStatement(false), - storageNode.BlockNumber, - storageNode.HeaderID, - storageNode.StateKey, - storageNode.StorageKey, - storageNode.CID, - false, - storageNode.Value, - false) - if err != nil { - return err - } - // increment storage node counter. - atomic.AddUint64(&p.storageNodeCounter, 1) - prom.IncStorageNodeCount() - - // increment current batch size counter - p.currBatchSize += 2 - return err -} - -func (p *publisher) PrepareTxForBatch(tx snapt.Tx, maxBatchSize uint) (snapt.Tx, error) { - var err error - // maximum batch size reached, commit the current transaction and begin a new transaction. - if maxBatchSize <= p.currBatchSize { - if err = tx.Commit(); err != nil { - return nil, err - } - - snapTx, err := p.db.Begin(context.Background()) - tx = pubTx{Tx: snapTx} - if err != nil { - return nil, err - } - - p.currBatchSize = 0 - } - - return tx, nil -} - -// logNodeCounters periodically logs the number of node processed. -func (p *publisher) logNodeCounters() { - t := time.NewTicker(logInterval) - for range t.C { - p.printNodeCounters("progress") - } -} - -func (p *publisher) printNodeCounters(msg string) { - log.WithFields(log.Fields{ - "runtime": time.Now().Sub(p.startTime).String(), - "state nodes": atomic.LoadUint64(&p.stateNodeCounter), - "storage nodes": atomic.LoadUint64(&p.storageNodeCounter), - "code nodes": atomic.LoadUint64(&p.codeNodeCounter), - }).Info(msg) -} diff --git a/pkg/snapshot/pg/publisher_test.go b/pkg/snapshot/pg/publisher_test.go deleted file mode 100644 index 5f44ea4..0000000 --- a/pkg/snapshot/pg/publisher_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package pg - -import ( - "context" - "testing" - - "github.com/ethereum/go-ethereum/statediff/indexer/shared/schema" - - "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" - "github.com/ethereum/go-ethereum/statediff/indexer/ipld" - "github.com/ethereum/go-ethereum/statediff/indexer/test_helpers" - - fixt "github.com/cerc-io/ipld-eth-state-snapshot/fixture" - "github.com/cerc-io/ipld-eth-state-snapshot/test" -) - -var ( - pgConfig = test.DefaultPgConfig - nodeInfo = test.DefaultNodeInfo - // tables ordered according to fkey depedencies - allTables = []*schema.Table{ - &schema.TableIPLDBlock, - &schema.TableNodeInfo, - &schema.TableHeader, - &schema.TableStateNode, - &schema.TableStorageNode, - } -) - -func writeData(t *testing.T, db *postgres.DB) *publisher { - pub := NewPublisher(db) - test.NoError(t, pub.PublishHeader(&fixt.Block1_Header)) - tx, err := pub.BeginTx() - test.NoError(t, err) - - test.NoError(t, pub.PublishStateLeafNode(&fixt.Block1_StateNode0, tx)) - - test.NoError(t, tx.Commit()) - return pub -} - -// Note: DB user requires role membership "pg_read_server_files" -func TestBasic(t *testing.T) { - test.NeedsDB(t) - - ctx := context.Background() - driver, err := postgres.NewSQLXDriver(ctx, pgConfig, nodeInfo) - test.NoError(t, err) - db := postgres.NewPostgresDB(driver, false) - - test_helpers.TearDownDB(t, db) - - _ = writeData(t, db) - - // check header was successfully committed - pgQueryHeader := `SELECT cid, block_hash - FROM eth.header_cids - WHERE block_number = $1` - type res struct { - CID string - BlockHash string - } - var header res - err = db.QueryRow(ctx, pgQueryHeader, fixt.Block1_Header.Number.Uint64()).Scan( - &header.CID, &header.BlockHash) - test.NoError(t, err) - - headerNode, err := ipld.NewEthHeader(&fixt.Block1_Header) - test.NoError(t, err) - test.ExpectEqual(t, headerNode.Cid().String(), header.CID) - test.ExpectEqual(t, fixt.Block1_Header.Hash().String(), header.BlockHash) -} diff --git a/pkg/snapshot/service.go b/pkg/snapshot/service.go index dd96728..a1658ce 100644 --- a/pkg/snapshot/service.go +++ b/pkg/snapshot/service.go @@ -16,28 +16,26 @@ package snapshot import ( - "bytes" "context" - "errors" "fmt" "math/big" + "os" + "os/signal" + "sync" + "syscall" + "github.com/cerc-io/ipld-eth-state-snapshot/pkg/prom" + statediff "github.com/cerc-io/plugeth-statediff" + "github.com/cerc-io/plugeth-statediff/adapt" + "github.com/cerc-io/plugeth-statediff/indexer" + "github.com/cerc-io/plugeth-statediff/types" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/statediff/indexer/ipld" - "github.com/ethereum/go-ethereum/statediff/indexer/models" - "github.com/ethereum/go-ethereum/trie" - iter "github.com/ethereum/go-ethereum/trie/concurrent_iterator" log "github.com/sirupsen/logrus" - "golang.org/x/sync/errgroup" - - "github.com/cerc-io/ipld-eth-state-snapshot/pkg/prom" - . "github.com/cerc-io/ipld-eth-state-snapshot/pkg/types" ) var ( @@ -51,551 +49,123 @@ var ( // Service holds ethDB and stateDB to read data from lvldb and Publisher // to publish trie in postgres DB. type Service struct { - watchingAddresses bool - ethDB ethdb.Database - stateDB state.Database - ipfsPublisher Publisher - maxBatchSize uint - tracker iteratorTracker - recoveryFile string + ethDB ethdb.Database + stateDB state.Database + indexer indexer.Indexer + maxBatchSize uint + recoveryFile string } func NewLevelDB(con *EthConfig) (ethdb.Database, error) { - kvdb, _ := rawdb.NewLevelDBDatabase(con.LevelDBPath, 1024, 256, "ipld-eth-state-snapshot", true) + kvdb, err := rawdb.NewLevelDBDatabase(con.LevelDBPath, 1024, 256, "ipld-eth-state-snapshot", true) + if err != nil { + return nil, fmt.Errorf("failed to connect LevelDB: %s", err) + } edb, err := rawdb.NewDatabaseWithFreezer(kvdb, con.AncientDBPath, "ipld-eth-state-snapshot", true) if err != nil { - return nil, fmt.Errorf("unable to create NewLevelDBDatabaseWithFreezer: %s", err) + return nil, fmt.Errorf("failed to connect LevelDB freezer: %s", err) } return edb, nil } // NewSnapshotService creates Service. -func NewSnapshotService(edb ethdb.Database, pub Publisher, recoveryFile string) (*Service, error) { +func NewSnapshotService(edb ethdb.Database, indexer indexer.Indexer, recoveryFile string) (*Service, error) { return &Service{ - ethDB: edb, - stateDB: state.NewDatabase(edb), - ipfsPublisher: pub, - maxBatchSize: defaultBatchSize, - recoveryFile: recoveryFile, + ethDB: edb, + stateDB: state.NewDatabase(edb), + indexer: indexer, + maxBatchSize: defaultBatchSize, + recoveryFile: recoveryFile, }, nil } type SnapshotParams struct { - WatchedAddresses map[common.Address]struct{} + WatchedAddresses []common.Address Height uint64 Workers uint } func (s *Service) CreateSnapshot(params SnapshotParams) error { - paths := make([][]byte, 0, len(params.WatchedAddresses)) - for addr := range params.WatchedAddresses { - paths = append(paths, keybytesToHex(crypto.Keccak256(addr.Bytes()))) - } - s.watchingAddresses = len(paths) > 0 // extract header from lvldb and publish to PG-IPFS // hold onto the headerID so that we can link the state nodes to this header - log.Infof("Creating snapshot at height %d", params.Height) hash := rawdb.ReadCanonicalHash(s.ethDB, params.Height) header := rawdb.ReadHeader(s.ethDB, hash, params.Height) if header == nil { return fmt.Errorf("unable to read canonical header at height %d", params.Height) } + log.WithField("height", params.Height).WithField("hash", hash).Info("Creating snapshot") - log.Infof("head hash: %s head height: %d", hash.Hex(), params.Height) - - err := s.ipfsPublisher.PublishHeader(header) - if err != nil { - return err - } - - tree, err := s.stateDB.OpenTrie(header.Root) - if err != nil { - return err - } - - headerID := header.Hash().String() - + // Context for snapshot work ctx, cancelCtx := context.WithCancel(context.Background()) - s.tracker = newTracker(s.recoveryFile, int(params.Workers)) - s.tracker.captureSignal(cancelCtx) + defer cancelCtx() + // Cancel context on receiving a signal. On cancellation, all tracked iterators complete + // processing of their current node before stopping. + captureSignal(cancelCtx) - var iters []trie.NodeIterator - // attempt to restore from recovery file if it exists - iters, err = s.tracker.restore(tree) + var err error + tx := s.indexer.BeginTx(header.Number, ctx) + defer tx.RollbackOnFailure(err) + + var headerid string + headerid, err = s.indexer.PushHeader(tx, header, big.NewInt(0), big.NewInt(0)) if err != nil { - log.Errorf("restore error: %s", err.Error()) return err } - if iters != nil { - log.Debugf("restored iterators; count: %d", len(iters)) - if params.Workers < uint(len(iters)) { - return fmt.Errorf( - "number of recovered workers (%d) is greater than number configured (%d)", - len(iters), params.Workers, - ) - } - } else { - // nothing to restore - log.Debugf("no iterators to restore") - if params.Workers > 1 { - iters = iter.SubtrieIterators(tree.NodeIterator, params.Workers) - } else { - iters = []trie.NodeIterator{tree.NodeIterator(nil)} - } - for i, it := range iters { - // recovered path is nil for fresh iterators - iters[i] = s.tracker.tracked(it, nil) - } - } - + tr := prom.NewTracker(s.recoveryFile, params.Workers) defer func() { - err := s.tracker.haltAndDump() + err := tr.CloseAndSave() if err != nil { log.Errorf("failed to write recovery file: %v", err) } }() - switch { - case len(iters) > 1: - return s.createSnapshotAsync(ctx, iters, headerID, new(big.Int).SetUint64(params.Height), paths) - case len(iters) == 1: - return s.createSnapshot(ctx, iters[0], headerID, new(big.Int).SetUint64(params.Height), paths) - default: - return nil + var nodeMtx, ipldMtx sync.Mutex + nodeSink := func(node types.StateLeafNode) error { + nodeMtx.Lock() + defer nodeMtx.Unlock() + return s.indexer.PushStateNode(tx, node, headerid) } + ipldSink := func(c types.IPLD) error { + ipldMtx.Lock() + defer ipldMtx.Unlock() + return s.indexer.PushIPLD(tx, c) + } + + sdparams := statediff.Params{ + WatchedAddresses: params.WatchedAddresses, + } + sdparams.ComputeWatchedAddressesLeafPaths() + builder := statediff.NewBuilder(adapt.GethStateView(s.stateDB)) + builder.SetSubtrieWorkers(params.Workers) + if err = builder.WriteStateSnapshot(header.Root, sdparams, nodeSink, ipldSink, tr); err != nil { + return err + } + + if err = tx.Submit(); err != nil { + return fmt.Errorf("batch transaction submission failed: %w", err) + } + return err } // CreateLatestSnapshot snapshot at head (ignores height param) -func (s *Service) CreateLatestSnapshot(workers uint, watchedAddresses map[common.Address]struct{}) error { +func (s *Service) CreateLatestSnapshot(workers uint, watchedAddresses []common.Address) error { log.Info("Creating snapshot at head") hash := rawdb.ReadHeadHeaderHash(s.ethDB) height := rawdb.ReadHeaderNumber(s.ethDB, hash) if height == nil { - return fmt.Errorf("unable to read header height for header hash %s", hash.String()) + return fmt.Errorf("unable to read header height for header hash %s", hash) } return s.CreateSnapshot(SnapshotParams{Height: *height, Workers: workers, WatchedAddresses: watchedAddresses}) } -// Full-trie concurrent snapshot -func (s *Service) createSnapshotAsync(ctx context.Context, iters []trie.NodeIterator, headerID string, height *big.Int, seekingPaths [][]byte) error { - // use errgroup with a context to stop all concurrent iterators if one runs into an error - // each concurrent iterator completes processing it's current node before stopping - g, ctx := errgroup.WithContext(ctx) - for _, it := range iters { - func(it trie.NodeIterator) { - g.Go(func() error { - return s.createSnapshot(ctx, it, headerID, height, seekingPaths) - }) - }(it) - } +func captureSignal(cb func()) { + sigChan := make(chan os.Signal, 1) - return g.Wait() -} - -// createSnapshot performs traversal using the given iterator and indexes the nodes -// optionally filtering them according to a list of paths -func (s *Service) createSnapshot(ctx context.Context, it trie.NodeIterator, headerID string, height *big.Int, seekingPaths [][]byte) error { - tx, err := s.ipfsPublisher.BeginTx() - if err != nil { - return err - } - // we must avoid overshadowing the `err` - defer func() { - err = CommitOrRollback(tx, err) - if err != nil { - log.Errorf("CommitOrRollback failed: %s", err) - } + signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) + go func() { + sig := <-sigChan + log.Errorf("Signal received (%v), stopping", sig) + cb() }() - - // path (from recovery dump) to be seeked on recovery - // nil in case of a fresh iterator - var recoveredPath []byte - - // latest path seeked from the concurrent iterator - // (updated after a node processed) - // nil in case of a fresh iterator; initially holds the recovered path in case of a recovered iterator - var seekedPath *[]byte - - // end path for the concurrent iterator - var endPath []byte - - if i, ok := it.(*trackedIter); ok { - seekedPath = &i.seekedPath - recoveredPath = append(recoveredPath, *seekedPath...) - endPath = i.endPath - } else { - err = errors.New("untracked iterator") - return err - } - - tx, err = s.createSubTrieSnapshot(ctx, tx, nil, it, recoveredPath, seekedPath, endPath, headerID, height, seekingPaths) - return err -} - -// createSubTrieSnapshot processes nodes at the next level of a trie using the given subtrie iterator -// continually updating seekedPath with path of the latest processed node -func (s *Service) createSubTrieSnapshot(ctx context.Context, tx Tx, prefixPath []byte, subTrieIt trie.NodeIterator, - recoveredPath []byte, seekedPath *[]byte, endPath []byte, headerID string, height *big.Int, seekingPaths [][]byte) (Tx, error) { - prom.IncActiveIterCount() - defer prom.DecActiveIterCount() - - // descend in the first loop iteration to reach first child node - var err error - descend := true - for { - select { - case <-ctx.Done(): - return tx, errors.New("ctx cancelled") - default: - if ok := subTrieIt.Next(descend); !ok { - return tx, subTrieIt.Error() - } - - // to avoid descending further - descend = false - - // move on to next node if current path is empty - // occurs when reaching root node or just before reaching the first child of a subtrie in case of some concurrent iterators - if bytes.Equal(subTrieIt.Path(), []byte{}) { - // if node path is empty and prefix is nil, it's the root node - if prefixPath == nil { - // create snapshot of node, if it is a leaf this will also create snapshot of entire storage trie - tx, err = s.createNodeSnapshot(tx, subTrieIt, headerID, height, seekingPaths, prefixPath) - if err != nil { - return tx, err - } - updateSeekedPath(seekedPath, subTrieIt.Path()) - } - - if ok := subTrieIt.Next(true); !ok { - // return if no further nodes available - return tx, subTrieIt.Error() - } - } - - // create the full node path as it.Path() doesn't include the path before subtrie root - nodePath := append(prefixPath, subTrieIt.Path()...) - - // check iterator upper bound before processing the node - // required to avoid processing duplicate nodes: - // if a node is considered more than once, - // it's whole subtrie is re-processed giving large number of duplicate nodoes - if !checkUpperPathBound(nodePath, endPath) { - // fmt.Println("failed checkUpperPathBound", nodePath, endPath) - // explicitly stop the iterator in tracker if upper bound check fails - // required since it won't be marked as stopped if further nodes are still available - if trackedSubtrieIt, ok := subTrieIt.(*trackedIter); ok { - s.tracker.stopIter(trackedSubtrieIt) - } - return tx, subTrieIt.Error() - } - - // skip the current node if it's before recovered path and not along the recovered path - // nodes at the same level that are before recovered path are ignored to avoid duplicate nodes - // however, nodes along the recovered path are re-considered for redundancy - if bytes.Compare(recoveredPath, nodePath) > 0 && - // a node is along the recovered path if it's path is shorter or equal in length - // and is part of the recovered path - !(len(nodePath) <= len(recoveredPath) && bytes.Equal(recoveredPath[:len(nodePath)], nodePath)) { - continue - } - - // ignore node if it is not along paths of interest - if s.watchingAddresses && !validPath(nodePath, seekingPaths) { - // consider this node as processed since it is getting ignored - // and update the seeked path - updateSeekedPath(seekedPath, nodePath) - // move on to the next node - continue - } - - // if the node is along paths of interest - // create snapshot of node, if it is a leaf this will also create snapshot of entire storage trie - tx, err = s.createNodeSnapshot(tx, subTrieIt, headerID, height, seekingPaths, prefixPath) - if err != nil { - return tx, err - } - // update seeked path after node has been processed - updateSeekedPath(seekedPath, nodePath) - - // create an iterator to traverse and process the next level of this subTrie - nextSubTrieIt, err := s.createSubTrieIt(nodePath, subTrieIt.Hash(), recoveredPath) - if err != nil { - return tx, err - } - // pass on the seekedPath of the tracked concurrent iterator to be updated - tx, err = s.createSubTrieSnapshot(ctx, tx, nodePath, nextSubTrieIt, recoveredPath, seekedPath, endPath, headerID, height, seekingPaths) - if err != nil { - return tx, err - } - } - } -} - -// createSubTrieIt creates an iterator to traverse the subtrie of node with the given hash -// the subtrie iterator is initialized at a node from the recovered path at corresponding level (if avaiable) -func (s *Service) createSubTrieIt(prefixPath []byte, hash common.Hash, recoveredPath []byte) (trie.NodeIterator, error) { - // skip directly to the node from the recovered path at corresponding level - // applicable if: - // node path is behind recovered path - // and recovered path includes the prefix path - var startPath []byte - if bytes.Compare(recoveredPath, prefixPath) > 0 && - len(recoveredPath) > len(prefixPath) && - bytes.Equal(recoveredPath[:len(prefixPath)], prefixPath) { - startPath = append(startPath, recoveredPath[len(prefixPath):len(prefixPath)+1]...) - // force the lower bound path to an even length - // (required by HexToKeyBytes()) - if len(startPath)&0b1 == 1 { - // decrement first to avoid skipped nodes - decrementPath(startPath) - startPath = append(startPath, 0) - } - } - - // create subTrie iterator with the given hash - subTrie, err := s.stateDB.OpenTrie(hash) - if err != nil { - return nil, err - } - - return subTrie.NodeIterator(iter.HexToKeyBytes(startPath)), nil -} - -// createNodeSnapshot indexes the current node -// entire storage trie is also indexed (if available) -func (s *Service) createNodeSnapshot(tx Tx, it trie.NodeIterator, headerID string, height *big.Int, - watchedAddressesLeafPaths [][]byte, prefixPath []byte) (Tx, error) { - tx, err := s.ipfsPublisher.PrepareTxForBatch(tx, s.maxBatchSize) - if err != nil { - return tx, err - } - - // index values by leaf key - if it.Leaf() { - // if it is a "value" node, we will index the value by leaf key - // publish codehash => code mappings - // take storage snapshot - if err := s.processStateValueNode(it, headerID, height, prefixPath, watchedAddressesLeafPaths, tx); err != nil { - return tx, err - } - } else { // trie nodes will be written to blockstore only - // reminder that this includes leaf nodes, since the geth iterator.Leaf() actually signifies a "value" node - // so this is also where we publish the IPLD block corresponding to the "value" nodes indexed above - if IsNullHash(it.Hash()) { - // skip null node - return tx, nil - } - nodeVal := make([]byte, len(it.NodeBlob())) - copy(nodeVal, it.NodeBlob()) - if len(watchedAddressesLeafPaths) > 0 { - var elements []interface{} - if err := rlp.DecodeBytes(nodeVal, &elements); err != nil { - return tx, err - } - ok, err := isLeaf(elements) - if err != nil { - return tx, err - } - if ok { - // create the full node path as it.Path() doesn't include the path before subtrie root - nodePath := append(prefixPath, it.Path()...) - partialPath := trie.CompactToHex(elements[0].([]byte)) - valueNodePath := append(nodePath, partialPath...) - if !isWatchedAddress(watchedAddressesLeafPaths, valueNodePath) { - // skip this node - return tx, nil - } - } - } - nodeHash := make([]byte, len(it.Hash().Bytes())) - copy(nodeHash, it.Hash().Bytes()) - if err := s.ipfsPublisher.PublishIPLD(ipld.Keccak256ToCid(ipld.MEthStateTrie, nodeHash), nodeVal, height, tx); err != nil { - return tx, err - } - } - - return tx, it.Error() -} - -// reminder: it.Leaf() == true when the iterator is positioned at a "value node" which is not something that actually exists in an MMPT -func (s *Service) processStateValueNode(it trie.NodeIterator, headerID string, height *big.Int, prefixPath []byte, - watchedAddressesLeafPaths [][]byte, tx Tx) error { - // create the full node path as it.Path() doesn't include the path before subtrie root - nodePath := append(prefixPath, it.Path()...) - // skip if it is not a watched address - // If we aren't watching any specific addresses, we are watching everything - if len(watchedAddressesLeafPaths) > 0 && !isWatchedAddress(watchedAddressesLeafPaths, nodePath) { - return nil - } - - // since this is a "value node", we need to move up to the "parent" node which is the actual leaf node - // it should be in the fastcache since it necessarily was recently accessed to reach the current "node" - parentNodeRLP, err := s.stateDB.TrieDB().Node(it.Parent()) - if err != nil { - return err - } - var nodeElements []interface{} - if err = rlp.DecodeBytes(parentNodeRLP, &nodeElements); err != nil { - return err - } - parentSubPath := make([]byte, len(it.ParentPath())) - copy(parentSubPath, it.ParentPath()) - parentPath := append(prefixPath, parentSubPath...) - partialPath := trie.CompactToHex(nodeElements[0].([]byte)) - valueNodePath := append(parentPath, partialPath...) - encodedPath := trie.HexToCompact(valueNodePath) - leafKey := encodedPath[1:] - - // created vs updated is important for leaf nodes since we need to diff their storage - // so we need to map all changed accounts at B to their leafkey, since account can change pathes but not leafkey - var account types.StateAccount - accountRLP := make([]byte, len(it.LeafBlob())) - copy(accountRLP, it.LeafBlob()) - if err := rlp.DecodeBytes(accountRLP, &account); err != nil { - return fmt.Errorf("error decoding account for leaf value at leaf key %x\nerror: %v", leafKey, err) - } - - // write codehash => code mappings if we have a contract - if !bytes.Equal(account.CodeHash, emptyCodeHash) { - codeHash := common.BytesToHash(account.CodeHash) - code, err := s.stateDB.ContractCode(common.Hash{}, codeHash) - if err != nil { - return fmt.Errorf("failed to retrieve code for codehash %s\r\n error: %v", codeHash.String(), err) - } - if err := s.ipfsPublisher.PublishIPLD(ipld.Keccak256ToCid(ipld.RawBinary, codeHash.Bytes()), code, height, tx); err != nil { - return err - } - } - - // publish the state leaf model - stateKeyStr := common.BytesToHash(leafKey).String() - stateLeafNodeModel := &models.StateNodeModel{ - BlockNumber: height.String(), - HeaderID: headerID, - StateKey: stateKeyStr, - Removed: false, - CID: ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(parentNodeRLP)).String(), - Diff: false, - Balance: account.Balance.String(), - Nonce: account.Nonce, - CodeHash: common.BytesToHash(account.CodeHash).String(), - StorageRoot: account.Root.String(), - } - if err := s.ipfsPublisher.PublishStateLeafNode(stateLeafNodeModel, tx); err != nil { - return fmt.Errorf("failed publishing state leaf node for leaf key %s\r\nerror: %w", stateKeyStr, err) - } - // create storage snapshot - // this short circuits if storage is empty - if _, err := s.storageSnapshot(account.Root, stateKeyStr, headerID, height, tx); err != nil { - return fmt.Errorf("failed building storage snapshot for account %+v\r\nerror: %w", account, err) - } - return nil -} - -func (s *Service) storageSnapshot(sr common.Hash, stateKey, headerID string, height *big.Int, tx Tx) (Tx, error) { - if bytes.Equal(sr.Bytes(), emptyContractRoot.Bytes()) { - return tx, nil - } - - sTrie, err := s.stateDB.OpenTrie(sr) - if err != nil { - return nil, err - } - - it := sTrie.NodeIterator(make([]byte, 0)) - for it.Next(true) { - if it.Leaf() { - if err := s.processStorageValueNode(it, stateKey, headerID, height, tx); err != nil { - return nil, err - } - } else { - nodeVal := make([]byte, len(it.NodeBlob())) - copy(nodeVal, it.NodeBlob()) - nodeHash := make([]byte, len(it.Hash().Bytes())) - copy(nodeHash, it.Hash().Bytes()) - if err := s.ipfsPublisher.PublishIPLD(ipld.Keccak256ToCid(ipld.MEthStorageTrie, nodeHash), nodeVal, height, tx); err != nil { - return nil, err - } - } - } - - return tx, it.Error() -} - -// reminder: it.Leaf() == true when the iterator is positioned at a "value node" which is not something that actually exists in an MMPT -func (s *Service) processStorageValueNode(it trie.NodeIterator, stateKey, headerID string, height *big.Int, tx Tx) error { - // skip if it is not a watched address - leafKey := make([]byte, len(it.LeafKey())) - copy(leafKey, it.LeafKey()) - value := make([]byte, len(it.LeafBlob())) - copy(value, it.LeafBlob()) - - // since this is a "value node", we need to move up to the "parent" node which is the actual leaf node - // it should be in the fastcache since it necessarily was recently accessed to reach the current node - parentNodeRLP, err := s.stateDB.TrieDB().Node(it.Parent()) - if err != nil { - return err - } - - // publish storage leaf node model - storageLeafKeyStr := common.BytesToHash(leafKey).String() - storageLeafNodeModel := &models.StorageNodeModel{ - BlockNumber: height.String(), - HeaderID: headerID, - StateKey: stateKey, - StorageKey: storageLeafKeyStr, - Removed: false, - CID: ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(parentNodeRLP)).String(), - Diff: false, - Value: value, - } - if err := s.ipfsPublisher.PublishStorageLeafNode(storageLeafNodeModel, tx); err != nil { - return fmt.Errorf("failed to publish storage leaf node for state leaf key %s and storage leaf key %s\r\nerr: %w", stateKey, storageLeafKeyStr, err) - } - return nil -} - -// validPath checks if a path is prefix to any one of the paths in the given list -func validPath(currentPath []byte, seekingPaths [][]byte) bool { - for _, seekingPath := range seekingPaths { - if bytes.HasPrefix(seekingPath, currentPath) { - return true - } - } - return false -} - -// isWatchedAddress is used to check if a state account corresponds to one of the addresses the builder is configured to watch -func isWatchedAddress(watchedAddressesLeafPaths [][]byte, valueNodePath []byte) bool { - for _, watchedAddressPath := range watchedAddressesLeafPaths { - if bytes.Equal(watchedAddressPath, valueNodePath) { - return true - } - } - - return false -} - -// isLeaf checks if the node we are at is a leaf -func isLeaf(elements []interface{}) (bool, error) { - if len(elements) > 2 { - return false, nil - } - if len(elements) < 2 { - return false, fmt.Errorf("node cannot be less than two elements in length") - } - switch elements[0].([]byte)[0] / 16 { - case '\x00': - return false, nil - case '\x01': - return false, nil - case '\x02': - return true, nil - case '\x03': - return true, nil - default: - return false, fmt.Errorf("unknown hex prefix") - } } diff --git a/pkg/snapshot/service_test.go b/pkg/snapshot/service_test.go index 7dc16dd..1ab12d8 100644 --- a/pkg/snapshot/service_test.go +++ b/pkg/snapshot/service_test.go @@ -1,672 +1,273 @@ -package snapshot +package snapshot_test import ( - "errors" "fmt" - "math/big" "math/rand" - "os" "path/filepath" - "sync" - "sync/atomic" + "sort" "testing" "time" - "github.com/ipfs/go-cid" - + "github.com/cerc-io/eth-testing/chaindata" + "github.com/cerc-io/plugeth-statediff/indexer/models" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/statediff/indexer/models" - "github.com/golang/mock/gomock" + "github.com/ethereum/go-ethereum/crypto" + "github.com/stretchr/testify/require" - fixt "github.com/cerc-io/ipld-eth-state-snapshot/fixture" - mock "github.com/cerc-io/ipld-eth-state-snapshot/mocks/snapshot" - snapt "github.com/cerc-io/ipld-eth-state-snapshot/pkg/types" - "github.com/cerc-io/ipld-eth-state-snapshot/test" + "github.com/cerc-io/ipld-eth-state-snapshot/internal/mocks" + . "github.com/cerc-io/ipld-eth-state-snapshot/pkg/snapshot" + fixture "github.com/cerc-io/ipld-eth-state-snapshot/test" ) var ( - stateNodeDuplicateErr = "state node indexed multiple times (%d) for state key %v" - storageNodeDuplicateErr = "storage node indexed multiple times (%d) for state key %v and storage key %v" - stateNodeNotIndexedErr = "state node not indexed for state key %v" - storageNodeNotIndexedErr = "storage node not indexed for state key %v, storage key %v" + // Note: block 1 doesn't have storage nodes. TODO: add fixtures with storage nodes + // chainAblock1StateKeys = sliceToSet(fixture.ChainA_Block1_StateNodeLeafKeys) + chainAblock1IpldCids = sliceToSet(fixture.ChainA_Block1_IpldCids) - unexpectedStateNodeErr = "got unexpected state node for state key %v" - unexpectedStorageNodeErr = "got unexpected storage node for state key %v, storage key %v" - - extraNodesIndexedErr = "number of nodes indexed (%v) is more than expected (max %v)" + subtrieWorkerCases = []uint{1, 4, 8, 16, 32} ) +type selectiveData struct { + StateNodes map[string]*models.StateNodeModel + StorageNodes map[string]map[string]*models.StorageNodeModel +} + +func init() { + rand.Seed(time.Now().UnixNano()) +} + func testConfig(leveldbpath, ancientdbpath string) *Config { return &Config{ Eth: &EthConfig{ LevelDBPath: leveldbpath, AncientDBPath: ancientdbpath, - NodeInfo: test.DefaultNodeInfo, - }, - DB: &DBConfig{ - URI: test.DefaultPgConfig.DbConnectionString(), - ConnConfig: test.DefaultPgConfig, + NodeInfo: DefaultNodeInfo, }, + DB: &DefaultPgConfig, } } -func makeMocks(t *testing.T) (*mock.MockPublisher, *mock.MockTx) { - ctl := gomock.NewController(t) - pub := mock.NewMockPublisher(ctl) - tx := mock.NewMockTx(ctl) - return pub, tx -} - -func TestCreateSnapshot(t *testing.T) { - runCase := func(t *testing.T, workers int) { - expectedStateLeafKeys := sync.Map{} - for _, key := range fixt.Block1_StateNodeLeafKeys { - expectedStateLeafKeys.Store(key, struct{}{}) - } - - pub, tx := makeMocks(t) - pub.EXPECT().PublishHeader(gomock.Eq(&fixt.Block1_Header)) - pub.EXPECT().BeginTx().Return(tx, nil). - Times(workers) - pub.EXPECT().PrepareTxForBatch(gomock.Any(), gomock.Any()).Return(tx, nil). - AnyTimes() - tx.EXPECT().Commit(). - Times(workers) - pub.EXPECT().PublishStateLeafNode( - gomock.Any(), - gomock.Eq(tx)). - Do(func(stateNode *models.StateNodeModel, _ snapt.Tx) error { - if stateNode.BlockNumber != fixt.Block1_Header.Number.String() { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - if stateNode.HeaderID != fixt.Block1_Header.Hash().String() { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - if _, ok := expectedStateLeafKeys.Load(stateNode.StateKey); ok { - expectedStateLeafKeys.Delete(stateNode.StateKey) - } else { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - return nil - }). - AnyTimes() - pub.EXPECT().PublishIPLD(gomock.Any(), gomock.Any(), gomock.Eq(fixt.Block1_Header.Number), gomock.Eq(tx)). - AnyTimes() - // Note: block 1 doesn't have storage nodes. TODO: add fixtures with storage nodes - - chainDataPath, ancientDataPath := fixt.GetChainDataPath("chaindata") - config := testConfig(chainDataPath, ancientDataPath) - edb, err := NewLevelDB(config.Eth) - if err != nil { - t.Fatal(err) - } - defer edb.Close() - - recovery := filepath.Join(t.TempDir(), "recover.csv") - service, err := NewSnapshotService(edb, pub, recovery) - if err != nil { - t.Fatal(err) - } - - params := SnapshotParams{Height: 1, Workers: uint(workers)} - err = service.CreateSnapshot(params) - if err != nil { - t.Fatal(err) - } - - // Check if all expected state nodes are indexed - expectedStateLeafKeys.Range(func(key, value any) bool { - t.Fatalf(stateNodeNotIndexedErr, key.(string)) - return true - }) +func TestSnapshot(t *testing.T) { + runCase := func(t *testing.T, workers uint) { + params := SnapshotParams{Height: 1, Workers: workers} + data := doSnapshot(t, fixture.ChainA, params) + verify_chainAblock1(t, data) } - testCases := []int{1, 4, 8, 16, 32} - for _, tc := range testCases { - t.Run("case", func(t *testing.T) { runCase(t, tc) }) + for _, tc := range subtrieWorkerCases { + t.Run(fmt.Sprintf("with %d subtries", tc), func(t *testing.T) { runCase(t, tc) }) } } -type indexedStateLeafNode struct { - value models.StateNodeModel - isIndexed bool -} - -type indexedStorageLeafNode struct { - value models.StorageNodeModel - isIndexed bool -} - -type storageNodeKey struct { - stateKey string - storageKey string -} - func TestAccountSelectiveSnapshot(t *testing.T) { - snapShotHeight := uint64(32) - watchedAddresses := map[common.Address]struct{}{ - common.HexToAddress("0x825a6eec09e44Cb0fa19b84353ad0f7858d7F61a"): {}, - common.HexToAddress("0x0616F59D291a898e796a1FAD044C5926ed2103eC"): {}, - } - expectedStateNodeIndexes := []int{0, 4} + height := uint64(32) + watchedAddresses, expected := watchedAccountData_chainBblock32() - stateKey33 := common.HexToHash("0x33153abc667e873b6036c8a46bdd847e2ade3f89b9331c78ef2553fea194c50d").String() - expectedStorageNodeIndexes33 := []int{0, 1, 2, 4, 6} - - stateKey12 := common.HexToHash("0xcabc5edb305583e33f66322ceee43088aa99277da772feb5053512d03a0a702b").String() - expectedStorageNodeIndexes12 := []int{9, 11} - - runCase := func(t *testing.T, workers int) { - expectedStateNodes := sync.Map{} - - for _, expectedStateNodeIndex := range expectedStateNodeIndexes { - key := fixt.Chain2_Block32_StateNodes[expectedStateNodeIndex].StateKey - expectedStateNodes.Store(key, indexedStateLeafNode{ - value: fixt.Chain2_Block32_StateNodes[expectedStateNodeIndex], - isIndexed: false, - }) + runCase := func(t *testing.T, workers uint) { + params := SnapshotParams{ + Height: height, + Workers: workers, + WatchedAddresses: watchedAddresses, } - - expectedStorageNodes := sync.Map{} - - for _, expectedStorageNodeIndex := range expectedStorageNodeIndexes33 { - key := fixt.Chain2_Block32_StorageNodes[expectedStorageNodeIndex].StorageKey - keys := storageNodeKey{ - stateKey: stateKey33, - storageKey: key, - } - value := indexedStorageLeafNode{ - value: fixt.Chain2_Block32_StorageNodes[expectedStorageNodeIndex], - isIndexed: false, - } - expectedStorageNodes.Store(keys, value) - } - - for _, expectedStorageNodeIndex := range expectedStorageNodeIndexes12 { - key := fixt.Chain2_Block32_StorageNodes[expectedStorageNodeIndex].StorageKey - keys := storageNodeKey{ - stateKey: stateKey12, - storageKey: key, - } - value := indexedStorageLeafNode{ - value: fixt.Chain2_Block32_StorageNodes[expectedStorageNodeIndex], - isIndexed: false, - } - expectedStorageNodes.Store(keys, value) - } - - pub, tx := makeMocks(t) - pub.EXPECT().PublishHeader(gomock.Eq(&fixt.Chain2_Block32_Header)) - pub.EXPECT().BeginTx().Return(tx, nil). - Times(workers) - pub.EXPECT().PrepareTxForBatch(gomock.Any(), gomock.Any()).Return(tx, nil). - AnyTimes() - tx.EXPECT().Commit(). - Times(workers) - pub.EXPECT().PublishStateLeafNode( - gomock.Any(), - gomock.Eq(tx)). - Do(func(stateNode *models.StateNodeModel, _ snapt.Tx) error { - if stateNode.BlockNumber != fixt.Chain2_Block32_Header.Number.String() { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - if stateNode.HeaderID != fixt.Chain2_Block32_Header.Hash().String() { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - key := stateNode.StateKey - // Check published nodes - if expectedStateNode, ok := expectedStateNodes.Load(key); ok { - expectedVal := expectedStateNode.(indexedStateLeafNode).value - test.ExpectEqual(t, expectedVal, *stateNode) - - // Mark expected node as indexed - expectedStateNodes.Store(key, indexedStateLeafNode{ - value: expectedVal, - isIndexed: true, - }) - } else { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - return nil - }). - AnyTimes() - pub.EXPECT().PublishStorageLeafNode( - gomock.Any(), - gomock.Eq(tx)). - Do(func(storageNode *models.StorageNodeModel, _ snapt.Tx) error { - if storageNode.BlockNumber != fixt.Chain2_Block32_Header.Number.String() { - t.Fatalf(unexpectedStorageNodeErr, storageNode.StateKey, storageNode.StorageKey) - } - if storageNode.HeaderID != fixt.Chain2_Block32_Header.Hash().String() { - t.Fatalf(unexpectedStorageNodeErr, storageNode.StateKey, storageNode.StorageKey) - } - key := storageNodeKey{ - stateKey: storageNode.StateKey, - storageKey: storageNode.StorageKey, - } - // Check published nodes - if expectedStorageNode, ok := expectedStorageNodes.Load(key); ok { - expectedVal := expectedStorageNode.(indexedStorageLeafNode).value - test.ExpectEqual(t, expectedVal, *storageNode) - - // Mark expected node as indexed - expectedStorageNodes.Store(key, indexedStorageLeafNode{ - value: expectedVal, - isIndexed: true, - }) - } else { - t.Fatalf(unexpectedStorageNodeErr, storageNode.StateKey, storageNode.StorageKey) - } - return nil - }). - AnyTimes() - pub.EXPECT().PublishIPLD(gomock.Any(), gomock.Any(), gomock.Eq(fixt.Chain2_Block32_Header.Number), gomock.Eq(tx)). - Do(func(_ cid.Cid, _ []byte, height *big.Int, _ snapt.Tx) { - if height.String() != fixt.Chain2_Block32_Header.Number.String() { - t.Fatalf("wrong blockheight for ipld publish: %s", height.String()) - } - }). - MaxTimes(len(fixt.Chain2_Block32_StateIPLDs) + len(fixt.Chain2_Block32_StorageIPLDs) + 1 + 2) - - chainDataPath, ancientDataPath := fixt.GetChainDataPath("chain2data") - config := testConfig(chainDataPath, ancientDataPath) - edb, err := NewLevelDB(config.Eth) - if err != nil { - t.Fatal(err) - } - defer edb.Close() - - recovery := filepath.Join(t.TempDir(), "recover.csv") - service, err := NewSnapshotService(edb, pub, recovery) - if err != nil { - t.Fatal(err) - } - - params := SnapshotParams{Height: snapShotHeight, Workers: uint(workers), WatchedAddresses: watchedAddresses} - err = service.CreateSnapshot(params) - if err != nil { - t.Fatal(err) - } - - expectedStateNodes.Range(func(key, value any) bool { - if !value.(indexedStateLeafNode).isIndexed { - t.Fatalf(stateNodeNotIndexedErr, key) - return false - } - return true - }) - expectedStorageNodes.Range(func(key, value any) bool { - if !value.(indexedStorageLeafNode).isIndexed { - t.Fatalf(storageNodeNotIndexedErr, key.(storageNodeKey).stateKey, key.(storageNodeKey).storageKey) - return false - } - return true - }) + data := doSnapshot(t, fixture.ChainB, params) + expected.verify(t, data) } - testCases := []int{1, 4, 8, 16, 32} - for _, tc := range testCases { - t.Run("case", func(t *testing.T) { runCase(t, tc) }) + for _, tc := range subtrieWorkerCases { + t.Run(fmt.Sprintf("with %d subtries", tc), func(t *testing.T) { runCase(t, tc) }) } } -func TestRecovery(t *testing.T) { - runCase := func(t *testing.T, workers int, interruptAt int32) { - // map: expected state path -> number of times it got published - expectedStateNodeKeys := sync.Map{} - for _, key := range fixt.Block1_StateNodeLeafKeys { - expectedStateNodeKeys.Store(key, 0) - } - var indexedStateNodesCount int32 - - pub, tx := makeMocks(t) - pub.EXPECT().PublishHeader(gomock.Eq(&fixt.Block1_Header)) - pub.EXPECT().BeginTx().Return(tx, nil).MaxTimes(workers) - pub.EXPECT().PrepareTxForBatch(gomock.Any(), gomock.Any()).Return(tx, nil).AnyTimes() - tx.EXPECT().Rollback().MaxTimes(workers) - tx.EXPECT().Commit().MaxTimes(workers) - pub.EXPECT().PublishStateLeafNode( - gomock.Any(), - gomock.Eq(tx)). - DoAndReturn(func(stateNode *models.StateNodeModel, _ snapt.Tx) error { - if stateNode.BlockNumber != fixt.Block1_Header.Number.String() { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - if stateNode.HeaderID != fixt.Block1_Header.Hash().String() { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - // Start throwing an error after a certain number of state nodes have been indexed - if indexedStateNodesCount >= interruptAt { - return errors.New("failingPublishStateLeafNode") - } else { - if prevCount, ok := expectedStateNodeKeys.Load(stateNode.StateKey); ok { - expectedStateNodeKeys.Store(stateNode.StateKey, prevCount.(int)+1) - atomic.AddInt32(&indexedStateNodesCount, 1) - } else { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - } - return nil - }). - MaxTimes(int(interruptAt) + workers) - pub.EXPECT().PublishIPLD(gomock.Any(), gomock.Any(), gomock.Eq(fixt.Block1_Header.Number), gomock.Eq(tx)). - AnyTimes() - - chainDataPath, ancientDataPath := fixt.GetChainDataPath("chaindata") - config := testConfig(chainDataPath, ancientDataPath) - edb, err := NewLevelDB(config.Eth) - if err != nil { - t.Fatal(err) - } - defer edb.Close() - - recovery := filepath.Join(t.TempDir(), "recover.csv") - service, err := NewSnapshotService(edb, pub, recovery) - if err != nil { - t.Fatal(err) - } - - params := SnapshotParams{Height: 1, Workers: uint(workers)} - err = service.CreateSnapshot(params) - if err == nil { - t.Fatal("expected an error") - } - - if _, err = os.Stat(recovery); err != nil { - t.Fatal("cannot stat recovery file:", err) - } - - // Create new mocks for recovery - recoveryPub, tx := makeMocks(t) - recoveryPub.EXPECT().PublishHeader(gomock.Eq(&fixt.Block1_Header)) - recoveryPub.EXPECT().BeginTx().Return(tx, nil).AnyTimes() - recoveryPub.EXPECT().PrepareTxForBatch(gomock.Any(), gomock.Any()).Return(tx, nil).AnyTimes() - tx.EXPECT().Commit().AnyTimes() - recoveryPub.EXPECT().PublishStateLeafNode( - gomock.Any(), - gomock.Eq(tx)). - DoAndReturn(func(stateNode *models.StateNodeModel, _ snapt.Tx) error { - if stateNode.BlockNumber != fixt.Block1_Header.Number.String() { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - if stateNode.HeaderID != fixt.Block1_Header.Hash().String() { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - if prevCount, ok := expectedStateNodeKeys.Load(stateNode.StateKey); ok { - expectedStateNodeKeys.Store(stateNode.StateKey, prevCount.(int)+1) - atomic.AddInt32(&indexedStateNodesCount, 1) - } else { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - return nil - }). - AnyTimes() - recoveryPub.EXPECT().PublishIPLD(gomock.Any(), gomock.Any(), gomock.Eq(fixt.Block1_Header.Number), gomock.Eq(tx)). - AnyTimes() - - // Create a new snapshot service for recovery - recoveryService, err := NewSnapshotService(edb, recoveryPub, recovery) - if err != nil { - t.Fatal(err) - } - err = recoveryService.CreateSnapshot(params) - if err != nil { - t.Fatal(err) - } - - // Check if recovery file has been deleted - _, err = os.Stat(recovery) - if err == nil { - t.Fatal("recovery file still present") - } else { - if !os.IsNotExist(err) { - t.Fatal(err) - } - } - - // Check if all state nodes are indexed after recovery - expectedStateNodeKeys.Range(func(key, value any) bool { - if value.(int) == 0 { - t.Fatalf(stateNodeNotIndexedErr, key.(string)) - } - return true - }) - - // nodes along the recovery path get reindexed - maxStateNodesCount := len(fixt.Block1_StateNodeLeafKeys) - if indexedStateNodesCount > int32(maxStateNodesCount) { - t.Fatalf(extraNodesIndexedErr, indexedStateNodesCount, maxStateNodesCount) - } +func TestSnapshotRecovery(t *testing.T) { + runCase := func(t *testing.T, workers uint, interruptAt uint) { + params := SnapshotParams{Height: 1, Workers: workers} + data := doSnapshotWithRecovery(t, fixture.ChainA, params, interruptAt) + verify_chainAblock1(t, data) } - testCases := []int{1, 2, 4, 8, 16, 32} - numInterrupts := 3 - interrupts := make([]int32, numInterrupts) - for i := 0; i < numInterrupts; i++ { - rand.Seed(time.Now().UnixNano()) - interrupts[i] = rand.Int31n(int32(len(fixt.Block1_StateNodeLeafKeys) / 2)) + interrupts := make([]uint, 4) + for i := 0; i < len(interrupts); i++ { + N := len(fixture.ChainA_Block1_StateNodeLeafKeys) + interrupts[i] = uint(rand.Intn(N/2) + N/4) } - for _, tc := range testCases { - for _, interrupt := range interrupts { - t.Run(fmt.Sprint("case", tc, interrupt), func(t *testing.T) { runCase(t, tc, interrupt) }) + for _, tc := range subtrieWorkerCases { + for i, interrupt := range interrupts { + t.Run( + fmt.Sprintf("with %d subtries %d", tc, i), + func(t *testing.T) { runCase(t, tc, interrupt) }, + ) } } } -func TestAccountSelectiveRecovery(t *testing.T) { - snapShotHeight := uint64(32) - watchedAddresses := map[common.Address]struct{}{ - common.HexToAddress("0x825a6eec09e44Cb0fa19b84353ad0f7858d7F61a"): {}, - common.HexToAddress("0x0616F59D291a898e796a1FAD044C5926ed2103eC"): {}, +func TestAccountSelectiveSnapshotRecovery(t *testing.T) { + height := uint64(32) + watchedAddresses, expected := watchedAccountData_chainBblock32() + + runCase := func(t *testing.T, workers uint, interruptAt uint) { + params := SnapshotParams{ + Height: height, + Workers: workers, + WatchedAddresses: watchedAddresses, + } + data := doSnapshotWithRecovery(t, fixture.ChainB, params, interruptAt) + expected.verify(t, data) } - expectedStateNodeIndexes := []int{0, 4} - expectedStorageNodeIndexes := []int{0, 1, 2, 4, 6, 9, 11} - - runCase := func(t *testing.T, workers int, interruptAt int32) { - // map: expected state path -> number of times it got published - expectedStateNodeKeys := sync.Map{} - for _, expectedStateNodeIndex := range expectedStateNodeIndexes { - key := fixt.Chain2_Block32_StateNodes[expectedStateNodeIndex].StateKey - expectedStateNodeKeys.Store(key, 0) - } - expectedStorageNodeKeys := sync.Map{} - for _, expectedStorageNodeIndex := range expectedStorageNodeIndexes { - stateKey := fixt.Chain2_Block32_StorageNodes[expectedStorageNodeIndex].StateKey - storageKey := fixt.Chain2_Block32_StorageNodes[expectedStorageNodeIndex].StorageKey - keys := storageNodeKey{ - stateKey: stateKey, - storageKey: storageKey, - } - expectedStorageNodeKeys.Store(keys, 0) - } - var indexedStateNodesCount, indexedStorageNodesCount int32 - - pub, tx := makeMocks(t) - pub.EXPECT().PublishHeader(gomock.Eq(&fixt.Chain2_Block32_Header)) - pub.EXPECT().BeginTx().Return(tx, nil).Times(workers) - pub.EXPECT().PrepareTxForBatch(gomock.Any(), gomock.Any()).Return(tx, nil).AnyTimes() - tx.EXPECT().Commit().MaxTimes(workers) - tx.EXPECT().Rollback().MaxTimes(workers) - pub.EXPECT().PublishStateLeafNode( - gomock.Any(), - gomock.Eq(tx)). - DoAndReturn(func(stateNode *models.StateNodeModel, _ snapt.Tx) error { - if stateNode.BlockNumber != fixt.Chain2_Block32_Header.Number.String() { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - if stateNode.HeaderID != fixt.Chain2_Block32_Header.Hash().String() { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - // Start throwing an error after a certain number of state nodes have been indexed - if indexedStateNodesCount >= interruptAt { - return errors.New("failingPublishStateLeafNode") - } else { - if prevCount, ok := expectedStateNodeKeys.Load(stateNode.StateKey); ok { - expectedStateNodeKeys.Store(stateNode.StateKey, prevCount.(int)+1) - atomic.AddInt32(&indexedStateNodesCount, 1) - } else { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - } - return nil - }). - MaxTimes(int(interruptAt) + workers) - pub.EXPECT().PublishStorageLeafNode( - gomock.Any(), - gomock.Eq(tx)). - Do(func(storageNode *models.StorageNodeModel, _ snapt.Tx) error { - if storageNode.BlockNumber != fixt.Chain2_Block32_Header.Number.String() { - t.Fatalf(unexpectedStorageNodeErr, storageNode.StateKey, storageNode.StorageKey) - } - if storageNode.HeaderID != fixt.Chain2_Block32_Header.Hash().String() { - t.Fatalf(unexpectedStorageNodeErr, storageNode.StateKey, storageNode.StorageKey) - } - keys := storageNodeKey{ - stateKey: storageNode.StateKey, - storageKey: storageNode.StorageKey, - } - if prevCount, ok := expectedStorageNodeKeys.Load(keys); ok { - expectedStorageNodeKeys.Store(keys, prevCount.(int)+1) - atomic.AddInt32(&indexedStorageNodesCount, 1) - } else { - t.Fatalf(unexpectedStorageNodeErr, storageNode.StateKey, storageNode.StorageKey) - } - return nil - }). - AnyTimes() - pub.EXPECT().PublishIPLD(gomock.Any(), gomock.Any(), gomock.Eq(fixt.Chain2_Block32_Header.Number), gomock.Eq(tx)). - AnyTimes() - - chainDataPath, ancientDataPath := fixt.GetChainDataPath("chain2data") - config := testConfig(chainDataPath, ancientDataPath) - edb, err := NewLevelDB(config.Eth) - if err != nil { - t.Fatal(err) - } - defer edb.Close() - - recovery := filepath.Join(t.TempDir(), "recover.csv") - service, err := NewSnapshotService(edb, pub, recovery) - if err != nil { - t.Fatal(err) - } - - params := SnapshotParams{Height: snapShotHeight, Workers: uint(workers), WatchedAddresses: watchedAddresses} - err = service.CreateSnapshot(params) - if err == nil { - t.Fatal("expected an error") - } - - if _, err = os.Stat(recovery); err != nil { - t.Fatal("cannot stat recovery file:", err) - } - - // Create new mocks for recovery - recoveryPub, tx := makeMocks(t) - recoveryPub.EXPECT().PublishHeader(gomock.Eq(&fixt.Chain2_Block32_Header)) - recoveryPub.EXPECT().BeginTx().Return(tx, nil).MaxTimes(workers) - recoveryPub.EXPECT().PrepareTxForBatch(gomock.Any(), gomock.Any()).Return(tx, nil).AnyTimes() - tx.EXPECT().Commit().MaxTimes(workers) - recoveryPub.EXPECT().PublishStateLeafNode( - gomock.Any(), - gomock.Eq(tx)). - DoAndReturn(func(stateNode *models.StateNodeModel, _ snapt.Tx) error { - if stateNode.BlockNumber != fixt.Chain2_Block32_Header.Number.String() { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - if stateNode.HeaderID != fixt.Chain2_Block32_Header.Hash().String() { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - if prevCount, ok := expectedStateNodeKeys.Load(stateNode.StateKey); ok { - expectedStateNodeKeys.Store(stateNode.StateKey, prevCount.(int)+1) - atomic.AddInt32(&indexedStateNodesCount, 1) - } else { - t.Fatalf(unexpectedStateNodeErr, stateNode.StateKey) - } - return nil - }). - AnyTimes() - recoveryPub.EXPECT().PublishStorageLeafNode( - gomock.Any(), - gomock.Eq(tx)). - Do(func(storageNode *models.StorageNodeModel, _ snapt.Tx) error { - if storageNode.BlockNumber != fixt.Chain2_Block32_Header.Number.String() { - t.Fatalf(unexpectedStorageNodeErr, storageNode.StateKey, storageNode.StorageKey) - } - if storageNode.HeaderID != fixt.Chain2_Block32_Header.Hash().String() { - t.Fatalf(unexpectedStorageNodeErr, storageNode.StateKey, storageNode.StorageKey) - } - keys := storageNodeKey{ - stateKey: storageNode.StateKey, - storageKey: storageNode.StorageKey, - } - if prevCount, ok := expectedStorageNodeKeys.Load(keys); ok { - expectedStorageNodeKeys.Store(keys, prevCount.(int)+1) - atomic.AddInt32(&indexedStorageNodesCount, 1) - } else { - t.Fatalf(unexpectedStorageNodeErr, storageNode.StateKey, storageNode.StorageKey) - } - return nil - }). - AnyTimes() - recoveryPub.EXPECT().PublishIPLD(gomock.Any(), gomock.Any(), gomock.Eq(fixt.Chain2_Block32_Header.Number), gomock.Eq(tx)). - AnyTimes() - - // Create a new snapshot service for recovery - recoveryService, err := NewSnapshotService(edb, recoveryPub, recovery) - if err != nil { - t.Fatal(err) - } - err = recoveryService.CreateSnapshot(params) - if err != nil { - t.Fatal(err) - } - - // Check if recovery file has been deleted - _, err = os.Stat(recovery) - if err == nil { - t.Fatal("recovery file still present") - } else { - if !os.IsNotExist(err) { - t.Fatal(err) - } - } - - // Check if all expected state nodes are indexed after recovery, but not in duplicate - expectedStateNodeKeys.Range(func(key, value any) bool { - if value.(int) == 0 { - t.Fatalf(stateNodeNotIndexedErr, key.(string)) - } - /* TODO: fix/figure out - if value.(int) > 1 { - t.Fatalf(stateNodeDuplicateErr, value.(int), key.(string)) - } - */ - return true - }) - expectedStorageNodeKeys.Range(func(key, value any) bool { - if value.(int) == 0 { - t.Fatalf(storageNodeNotIndexedErr, key.(storageNodeKey).stateKey, key.(storageNodeKey).storageKey) - } - /* TODO: fix/figure out - if value.(int) > 1 { - t.Fatalf(storageNodeDuplicateErr, value.(int), key.(storageNodeKey).stateKey, key.(storageNodeKey).storageKey) - } - */ - return true - }) - - maxStateNodesCount := len(expectedStateNodeIndexes) + workers - if indexedStateNodesCount > int32(maxStateNodesCount) { - t.Fatalf(extraNodesIndexedErr, indexedStateNodesCount, maxStateNodesCount) - } - } - - testCases := []int{1, 2, 4, 8, 16, 32} - - for _, tc := range testCases { - t.Run(fmt.Sprint("case", tc, 1), func(t *testing.T) { runCase(t, tc, 1) }) + for _, tc := range subtrieWorkerCases { + t.Run( + fmt.Sprintf("with %d subtries", tc), + func(t *testing.T) { runCase(t, tc, 1) }, + ) } } + +func verify_chainAblock1(t *testing.T, data mocks.IndexerData) { + // Extract indexed keys and sort them for comparison + var indexedStateKeys []string + for _, stateNode := range data.StateNodes { + stateKey := common.BytesToHash(stateNode.AccountWrapper.LeafKey).String() + indexedStateKeys = append(indexedStateKeys, stateKey) + } + sort.Slice(indexedStateKeys, func(i, j int) bool { return indexedStateKeys[i] < indexedStateKeys[j] }) + require.Equal(t, fixture.ChainA_Block1_StateNodeLeafKeys, indexedStateKeys) + + ipldCids := make(map[string]struct{}) + for _, ipld := range data.IPLDs { + ipldCids[ipld.CID] = struct{}{} + } + require.Equal(t, chainAblock1IpldCids, ipldCids) +} + +func watchedAccountData_chainBblock32() ([]common.Address, selectiveData) { + watchedAddresses := []common.Address{ + // hash 0xcabc5edb305583e33f66322ceee43088aa99277da772feb5053512d03a0a702b + common.HexToAddress("0x825a6eec09e44Cb0fa19b84353ad0f7858d7F61a"), + // hash 0x33153abc667e873b6036c8a46bdd847e2ade3f89b9331c78ef2553fea194c50d + common.HexToAddress("0x0616F59D291a898e796a1FAD044C5926ed2103eC"), + } + var expected selectiveData + expected.StateNodes = make(map[string]*models.StateNodeModel) + for _, index := range []int{0, 4} { + node := &fixture.ChainB_Block32_StateNodes[index] + expected.StateNodes[node.StateKey] = node + } + + // Map account leaf keys to corresponding storage + expectedStorageNodeIndexes := []struct { + address common.Address + indexes []int + }{ + {watchedAddresses[0], []int{9, 11}}, + {watchedAddresses[1], []int{0, 1, 2, 4, 6}}, + } + expected.StorageNodes = make(map[string]map[string]*models.StorageNodeModel) + for _, account := range expectedStorageNodeIndexes { + leafKey := crypto.Keccak256Hash(account.address[:]).String() + storageNodes := make(map[string]*models.StorageNodeModel) + for _, index := range account.indexes { + node := &fixture.ChainB_Block32_StorageNodes[index] + storageNodes[node.StorageKey] = node + } + expected.StorageNodes[leafKey] = storageNodes + } + return watchedAddresses, expected +} + +func (expected selectiveData) verify(t *testing.T, data mocks.IndexerData) { + // check that all indexed nodes are expected and correct + indexedStateKeys := make(map[string]struct{}) + for _, stateNode := range data.StateNodes { + stateKey := common.BytesToHash(stateNode.AccountWrapper.LeafKey).String() + indexedStateKeys[stateKey] = struct{}{} + require.Contains(t, expected.StateNodes, stateKey, "unexpected state node") + + model := expected.StateNodes[stateKey] + require.Equal(t, model.CID, stateNode.AccountWrapper.CID) + require.Equal(t, model.Balance, stateNode.AccountWrapper.Account.Balance.String()) + require.Equal(t, model.StorageRoot, stateNode.AccountWrapper.Account.Root.String()) + + expectedStorage := expected.StorageNodes[stateKey] + indexedStorageKeys := make(map[string]struct{}) + for _, storageNode := range stateNode.StorageDiff { + storageKey := common.BytesToHash(storageNode.LeafKey).String() + indexedStorageKeys[storageKey] = struct{}{} + require.Contains(t, expectedStorage, storageKey, "unexpected storage node") + + require.Equal(t, expectedStorage[storageKey].CID, storageNode.CID) + require.Equal(t, expectedStorage[storageKey].Value, storageNode.Value) + } + // check for completeness + for storageNode := range expectedStorage { + require.Contains(t, indexedStorageKeys, storageNode, "missing storage node") + } + } + // check for completeness + for stateNode := range expected.StateNodes { + require.Contains(t, indexedStateKeys, stateNode, "missing state node") + } +} + +func doSnapshot(t *testing.T, chain *chaindata.Paths, params SnapshotParams) mocks.IndexerData { + chainDataPath, ancientDataPath := chain.ChainData, chain.Ancient + config := testConfig(chainDataPath, ancientDataPath) + edb, err := NewLevelDB(config.Eth) + require.NoError(t, err) + defer edb.Close() + + idx := mocks.NewIndexer(t) + recovery := filepath.Join(t.TempDir(), "recover.csv") + service, err := NewSnapshotService(edb, idx, recovery) + require.NoError(t, err) + + err = service.CreateSnapshot(params) + require.NoError(t, err) + return idx.IndexerData +} + +func doSnapshotWithRecovery( + t *testing.T, + chain *chaindata.Paths, + params SnapshotParams, + failAfter uint, +) mocks.IndexerData { + chainDataPath, ancientDataPath := chain.ChainData, chain.Ancient + config := testConfig(chainDataPath, ancientDataPath) + edb, err := NewLevelDB(config.Eth) + require.NoError(t, err) + defer edb.Close() + + indexer := &mocks.InterruptingIndexer{ + Indexer: mocks.NewIndexer(t), + InterruptAfter: failAfter, + } + t.Logf("Will interrupt after %d state nodes", failAfter) + + recoveryFile := filepath.Join(t.TempDir(), "recover.csv") + service, err := NewSnapshotService(edb, indexer, recoveryFile) + require.NoError(t, err) + err = service.CreateSnapshot(params) + require.Error(t, err) + + require.FileExists(t, recoveryFile) + // We should only have processed nodes up to the break, plus an extra node per worker + require.LessOrEqual(t, len(indexer.StateNodes), int(indexer.InterruptAfter+params.Workers)) + + // use the nested mock indexer, to continue where it left off + recoveryIndexer := indexer.Indexer + service, err = NewSnapshotService(edb, recoveryIndexer, recoveryFile) + require.NoError(t, err) + err = service.CreateSnapshot(params) + require.NoError(t, err) + + return recoveryIndexer.IndexerData +} + +func sliceToSet[T comparable](slice []T) map[T]struct{} { + set := make(map[T]struct{}) + for _, v := range slice { + set[v] = struct{}{} + } + return set +} diff --git a/pkg/snapshot/tracker.go b/pkg/snapshot/tracker.go deleted file mode 100644 index 13780e7..0000000 --- a/pkg/snapshot/tracker.go +++ /dev/null @@ -1,277 +0,0 @@ -package snapshot - -import ( - "bytes" - "context" - "encoding/csv" - "fmt" - "os" - "os/signal" - "sync" - "sync/atomic" - "syscall" - - "github.com/cerc-io/ipld-eth-state-snapshot/pkg/prom" - - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/trie" - iter "github.com/ethereum/go-ethereum/trie/concurrent_iterator" - log "github.com/sirupsen/logrus" -) - -var trackedIterCount int32 - -type trackedIter struct { - id int32 - mu sync.Mutex - done atomic.Bool - trie.NodeIterator - tracker *iteratorTracker - - seekedPath []byte // latest full node path seeked from the tracked iterator - startPath []byte // startPath for the tracked iterator - endPath []byte // endPath for the tracked iterator - lastPath []byte // latest it.Path() (not the full node path) seeked -} - -func (it *trackedIter) getLastPath() []byte { - it.mu.Lock() - defer it.mu.Unlock() - - return it.lastPath -} - -func (it *trackedIter) setLastPath(val []byte) { - it.mu.Lock() - defer it.mu.Unlock() - - it.lastPath = val -} - -func (it *trackedIter) Next(descend bool) bool { - ret := it.NodeIterator.Next(descend) - - if !ret { - if it.tracker.running { - it.tracker.stopChan <- it - } else { - log.Errorf("iterator stopped after tracker halted: path=%x", it.Path()) - } - it.done.Store(true) - } else { - it.setLastPath(it.Path()) - } - return ret -} - -type iteratorTracker struct { - recoveryFile string - - startChan chan *trackedIter - stopChan chan *trackedIter - started map[*trackedIter]struct{} - stopped []*trackedIter - running bool -} - -func newTracker(file string, buf int) iteratorTracker { - return iteratorTracker{ - recoveryFile: file, - startChan: make(chan *trackedIter, buf), - stopChan: make(chan *trackedIter, buf), - started: map[*trackedIter]struct{}{}, - running: true, - } -} - -func (tr *iteratorTracker) captureSignal(cancelCtx context.CancelFunc) { - sigChan := make(chan os.Signal, 1) - - signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) - go func() { - sig := <-sigChan - log.Errorf("Signal received (%v), stopping", sig) - // cancel context on receiving a signal - // on ctx cancellation, all the iterators complete processing of their current node before stopping - cancelCtx() - }() -} - -// Wraps an iterator in a trackedIter. This should not be called once halts are possible. -func (tr *iteratorTracker) tracked(it trie.NodeIterator, recoveredPath []byte) (ret *trackedIter) { - // create seeked path of max capacity (65) - iterSeekedPath := make([]byte, 0, 65) - // intially populate seeked path with the recovered path - // to be used in trie traversal - if recoveredPath != nil { - iterSeekedPath = append(iterSeekedPath, recoveredPath...) - } - - // if the iterator being tracked is a PrefixBoundIterator, capture it's end path - // to be used in trie traversal - var endPath []byte - var startPath []byte - if boundedIter, ok := it.(*iter.PrefixBoundIterator); ok { - startPath = boundedIter.StartPath - endPath = boundedIter.EndPath - } - - ret = &trackedIter{ - atomic.AddInt32(&trackedIterCount, 1), - sync.Mutex{}, - atomic.Bool{}, - it, - tr, - iterSeekedPath, - startPath, - endPath, - nil, - } - tr.startChan <- ret - - if prom.Enabled() { - pathDepth := max(max(len(startPath), len(endPath)), 1) - totalSteps := estimateSteps(startPath, endPath, pathDepth) - prom.RegisterGaugeFunc( - fmt.Sprintf("tracked_iterator_%d", ret.id), - func() float64 { - if ret.done.Load() { - return 100.0 - } - lastPath := ret.getLastPath() - if nil == lastPath { - return 0.0 - } - remainingSteps := estimateSteps(lastPath, endPath, pathDepth) - return (float64(totalSteps) - float64(remainingSteps)) / float64(totalSteps) * 100.0 - }) - } - - return -} - -// explicitly stops an iterator -func (tr *iteratorTracker) stopIter(it *trackedIter) { - tr.stopChan <- it -} - -// dumps iterator path and bounds to a text file so it can be restored later -func (tr *iteratorTracker) dump() error { - log.Debug("Dumping recovery state to: ", tr.recoveryFile) - var rows [][]string - for it := range tr.started { - var startPath []byte - var endPath []byte - if impl, ok := it.NodeIterator.(*iter.PrefixBoundIterator); ok { - // if the iterator being tracked is a PrefixBoundIterator, - // initialize start and end paths with its bounds - startPath = impl.StartPath - endPath = impl.EndPath - } - - // if seeked path and iterator path are non-empty, use iterator's path as startpath - if !bytes.Equal(it.seekedPath, []byte{}) && !bytes.Equal(it.Path(), []byte{}) { - startPath = it.Path() - } - - rows = append(rows, []string{ - fmt.Sprintf("%x", startPath), - fmt.Sprintf("%x", endPath), - fmt.Sprintf("%x", it.seekedPath), - }) - } - - file, err := os.Create(tr.recoveryFile) - if err != nil { - return err - } - defer file.Close() - out := csv.NewWriter(file) - - return out.WriteAll(rows) -} - -// attempts to read iterator state from file -// if file doesn't exist, returns an empty slice with no error -func (tr *iteratorTracker) restore(tree state.Trie) ([]trie.NodeIterator, error) { - file, err := os.Open(tr.recoveryFile) - if err != nil { - if os.IsNotExist(err) { - return nil, nil - } - return nil, err - } - log.Debug("Restoring recovery state from: ", tr.recoveryFile) - defer file.Close() - in := csv.NewReader(file) - in.FieldsPerRecord = 3 - rows, err := in.ReadAll() - if err != nil { - return nil, err - } - - var ret []trie.NodeIterator - for _, row := range rows { - // pick up where each interval left off - var startPath []byte - var endPath []byte - var recoveredPath []byte - - if len(row[0]) != 0 { - if _, err = fmt.Sscanf(row[0], "%x", &startPath); err != nil { - return nil, err - } - } - if len(row[1]) != 0 { - if _, err = fmt.Sscanf(row[1], "%x", &endPath); err != nil { - return nil, err - } - } - if len(row[2]) != 0 { - if _, err = fmt.Sscanf(row[2], "%x", &recoveredPath); err != nil { - return nil, err - } - } - - // force the lower bound path to an even length - // (required by HexToKeyBytes()) - if len(startPath)&0b1 == 1 { - // decrement first to avoid skipped nodes - decrementPath(startPath) - startPath = append(startPath, 0) - } - - it := iter.NewPrefixBoundIterator(tree.NodeIterator(iter.HexToKeyBytes(startPath)), startPath, endPath) - ret = append(ret, tr.tracked(it, recoveredPath)) - } - return ret, nil -} - -func (tr *iteratorTracker) haltAndDump() error { - tr.running = false - - // drain any pending iterators - close(tr.startChan) - for start := range tr.startChan { - tr.started[start] = struct{}{} - } - close(tr.stopChan) - for stop := range tr.stopChan { - tr.stopped = append(tr.stopped, stop) - } - - for _, stop := range tr.stopped { - delete(tr.started, stop) - } - - if len(tr.started) == 0 { - // if the tracker state is empty, erase any existing recovery file - err := os.Remove(tr.recoveryFile) - if os.IsNotExist(err) { - err = nil - } - return err - } - - return tr.dump() -} diff --git a/pkg/snapshot/util.go b/pkg/snapshot/util.go index b517166..6fe4ac9 100644 --- a/pkg/snapshot/util.go +++ b/pkg/snapshot/util.go @@ -2,56 +2,8 @@ package snapshot import ( "bytes" - "context" - "fmt" - - "github.com/cerc-io/ipld-eth-state-snapshot/pkg/prom" - file "github.com/cerc-io/ipld-eth-state-snapshot/pkg/snapshot/file" - "github.com/cerc-io/ipld-eth-state-snapshot/pkg/snapshot/pg" - snapt "github.com/cerc-io/ipld-eth-state-snapshot/pkg/types" - "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" ) -func NewPublisher(mode SnapshotMode, config *Config) (snapt.Publisher, error) { - switch mode { - case PgSnapshot: - driver, err := postgres.NewPGXDriver(context.Background(), config.DB.ConnConfig, config.Eth.NodeInfo) - if err != nil { - return nil, err - } - - prom.RegisterDBCollector(config.DB.ConnConfig.DatabaseName, driver) - - return pg.NewPublisher(postgres.NewPostgresDB(driver, false)), nil - case FileSnapshot: - return file.NewPublisher(config.File.OutputDir, config.Eth.NodeInfo) - } - return nil, fmt.Errorf("invalid snapshot mode: %s", mode) -} - -// Subtracts 1 from the last byte in a path slice, carrying if needed. -// Does nothing, returning false, for all-zero inputs. -func decrementPath(path []byte) bool { - // check for all zeros - allzero := true - for i := 0; i < len(path); i++ { - allzero = allzero && path[i] == 0 - } - if allzero { - return false - } - for i := len(path) - 1; i >= 0; i-- { - val := path[i] - path[i]-- - if val == 0 { - path[i] = 0xf - } else { - return true - } - } - return true -} - // Estimate the number of iterations necessary to step from start to end. func estimateSteps(start []byte, end []byte, depth int) uint64 { // We see paths in several forms (nil, 0600, 06, etc.). We need to adjust them to a comparable form. @@ -122,45 +74,3 @@ func estimateSteps(start []byte, end []byte, depth int) uint64 { return ret } - -// https://github.com/ethereum/go-ethereum/blob/master/trie/encoding.go#L97 -func keybytesToHex(str []byte) []byte { - l := len(str)*2 + 1 - var nibbles = make([]byte, l) - for i, b := range str { - nibbles[i*2] = b / 16 - nibbles[i*2+1] = b % 16 - } - nibbles[l-1] = 16 - return nibbles -} - -func updateSeekedPath(seekedPath *[]byte, nodePath []byte) { - // assumes len(nodePath) <= max len(*seekedPath) - *seekedPath = (*seekedPath)[:len(nodePath)] - copy(*seekedPath, nodePath) -} - -// checks that the provided node path is before the end path -func checkUpperPathBound(nodePath, endPath []byte) bool { - // every path is before nil endPath - if endPath == nil { - return true - } - - if len(endPath)%2 == 0 { - // in case of even length endpath - // apply open interval filter since the node at endpath will be covered by the next iterator - return bytes.Compare(nodePath, endPath) < 0 - } - - return bytes.Compare(nodePath, endPath) <= 0 -} - -func max(a int, b int) int { - if a > b { - return a - } - - return b -} diff --git a/pkg/types/node_type.go b/pkg/types/node_type.go deleted file mode 100644 index d72fcf6..0000000 --- a/pkg/types/node_type.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright © 2020 Vulcanize, Inc -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -package types - -import ( - "fmt" -) - -// NodeType for explicitly setting type of node -type NodeType int - -const ( - Branch NodeType = iota - Extension - Leaf - Removed - Unknown -) - -// CheckKeyType checks what type of key we have -func CheckKeyType(elements []interface{}) (NodeType, error) { - if len(elements) > 2 { - return Branch, nil - } - if len(elements) < 2 { - return Unknown, fmt.Errorf("node cannot be less than two elements in length") - } - switch elements[0].([]byte)[0] / 16 { - case '\x00': - return Extension, nil - case '\x01': - return Extension, nil - case '\x02': - return Leaf, nil - case '\x03': - return Leaf, nil - default: - return Unknown, fmt.Errorf("unknown hex prefix") - } -} diff --git a/pkg/types/publisher.go b/pkg/types/publisher.go deleted file mode 100644 index 679cca3..0000000 --- a/pkg/types/publisher.go +++ /dev/null @@ -1,24 +0,0 @@ -package types - -import ( - "math/big" - - "github.com/ethereum/go-ethereum/statediff/indexer/models" - "github.com/ipfs/go-cid" - - "github.com/ethereum/go-ethereum/core/types" -) - -type Publisher interface { - PublishHeader(header *types.Header) error - PublishStateLeafNode(node *models.StateNodeModel, tx Tx) error - PublishStorageLeafNode(node *models.StorageNodeModel, tx Tx) error - PublishIPLD(c cid.Cid, raw []byte, height *big.Int, tx Tx) error - BeginTx() (Tx, error) - PrepareTxForBatch(tx Tx, batchSize uint) (Tx, error) -} - -type Tx interface { - Rollback() error - Commit() error -} diff --git a/pkg/types/util.go b/pkg/types/util.go deleted file mode 100644 index 32fe245..0000000 --- a/pkg/types/util.go +++ /dev/null @@ -1,33 +0,0 @@ -package types - -import ( - "bytes" - - "github.com/sirupsen/logrus" - - "github.com/ethereum/go-ethereum/common" -) - -var nullHash = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000") - -func IsNullHash(hash common.Hash) bool { - return bytes.Equal(hash.Bytes(), nullHash.Bytes()) -} - -func CommitOrRollback(tx Tx, err error) error { - var rberr error - defer func() { - if rberr != nil { - logrus.Errorf("rollback failed: %s", rberr) - } - }() - if rec := recover(); rec != nil { - rberr = tx.Rollback() - panic(rec) - } else if err != nil { - rberr = tx.Rollback() - } else { - err = tx.Commit() - } - return err -} diff --git a/scripts/README.md b/scripts/README.md index a0f0f43..392f0af 100644 --- a/scripts/README.md +++ b/scripts/README.md @@ -2,13 +2,13 @@ * For a given table in the `ipld-eth-db` schema, we know the number of columns to be expected in each row in the data dump: - | Table | Expected columns | - | ----------------- |:----------------:| - | public.nodes | 5 | - | public.blocks | 3 | - | eth.header_cids | 16 | - | eth.state_cids | 8 | - | eth.storage_cids | 9 | + | Table | Expected columns | + |--------------------|:----------------:| + | `public.nodes` | 5 | + | `ipld.blocks` | 3 | + | `eth.header_cids` | 16 | + | `eth.state_cids` | 8 | + | `eth.storage_cids` | 9 | ### Find Bad Data @@ -29,7 +29,7 @@ ```bash ./scripts/find-bad-rows.sh -i eth.state_cids.csv -c 8 -o res.txt -d true ``` - + Output: ``` @@ -40,7 +40,7 @@ ```bash ./scripts/find-bad-rows.sh -i public.nodes.csv -c 5 -o res.txt -d true - ./scripts/find-bad-rows.sh -i public.blocks.csv -c 3 -o res.txt -d true + ./scripts/find-bad-rows.sh -i ipld.blocks.csv -c 3 -o res.txt -d true ./scripts/find-bad-rows.sh -i eth.header_cids.csv -c 16 -o res.txt -d true ./scripts/find-bad-rows.sh -i eth.state_cids.csv -c 8 -o res.txt -d true ./scripts/find-bad-rows.sh -i eth.storage_cids.csv -c 9 -o res.txt -d true @@ -66,7 +66,7 @@ ```bash ./scripts/filter-bad-rows.sh -i public.nodes.csv -c 5 -o cleaned-public.nodes.csv - ./scripts/filter-bad-rows.sh -i public.blocks.csv -c 3 -o cleaned-public.blocks.csv + ./scripts/filter-bad-rows.sh -i ipld.blocks.csv -c 3 -o cleaned-ipld.blocks.csv ./scripts/filter-bad-rows.sh -i eth.header_cids.csv -c 16 -o cleaned-eth.header_cids.csv ./scripts/filter-bad-rows.sh -i eth.state_cids.csv -c 8 -o cleaned-eth.state_cids.csv ./scripts/filter-bad-rows.sh -i eth.storage_cids.csv -c 9 -o cleaned-eth.storage_cids.csv diff --git a/scripts/compare-snapshots.sh b/scripts/compare-snapshots.sh new file mode 100755 index 0000000..6ce0029 --- /dev/null +++ b/scripts/compare-snapshots.sh @@ -0,0 +1,87 @@ +#!/bin/bash +# Compare the full snapshot output from two versions of the service +# +# Usage: compare-versions.sh [-d ] +# +# Configure the input data using environment vars. +( + set -u + : $SNAPSHOT_BLOCK_HEIGHT + : $LEVELDB_PATH + : $LEVELDB_ANCIENT + : $ETH_GENESIS_BLOCK +) + +while getopts d: opt; do + case $opt in + d) output_dir="$OPTARG" + esac +done +shift $((OPTIND - 1)) + +binary_A=$1 +binary_B=$2 +shift 2 + +if [[ -z $output_dir ]]; then + output_dir=$(mktemp -d) +fi + +export SNAPSHOT_MODE=postgres +export SNAPSHOT_WORKERS=32 +export SNAPSHOT_RECOVERY_FILE='compare-snapshots-recovery.txt' + +export DATABASE_NAME="cerc_testing" +export DATABASE_HOSTNAME="localhost" +export DATABASE_PORT=8077 +export DATABASE_USER="vdbm" +export DATABASE_PASSWORD="password" + +export ETH_CLIENT_NAME=test-client +export ETH_NODE_ID=test-node +export ETH_NETWORK_ID=test-network +export ETH_CHAIN_ID=4242 + +dump_table() { + statement="copy (select * from $1) to stdout with csv" + docker exec -e PGPASSWORD=password test-ipld-eth-db-1 \ + psql -q cerc_testing -U vdbm -c "$statement" | sort -u > "$2/$1.csv" +} + +clear_table() { + docker exec -e PGPASSWORD=password test-ipld-eth-db-1 \ + psql -q cerc_testing -U vdbm -c "truncate $1" +} + +tables=( + eth.log_cids + eth.receipt_cids + eth.state_cids + eth.storage_cids + eth.transaction_cids + eth.uncle_cids + ipld.blocks + public.nodes +) + +for table in "${tables[@]}"; do + clear_table $table +done + +$binary_A stateSnapshot + +mkdir -p $output_dir/A +for table in "${tables[@]}"; do + dump_table $table $output_dir/A + clear_table $table +done + +$binary_B stateSnapshot + +mkdir -p $output_dir/B +for table in "${tables[@]}"; do + dump_table $table $output_dir/B + clear_table $table +done + +diff -rs $output_dir/A $output_dir/B diff --git a/startup_script.sh b/startup_script.sh index 290bf9e..5d2d3dd 100755 --- a/startup_script.sh +++ b/startup_script.sh @@ -11,7 +11,7 @@ fi # Check the database variables are set test "$VDB_COMMAND" -# docker must be run in privilaged mode for mounts to work +# docker must be run in privileged mode for mounts to work echo "Setting up /app/geth-rw overlayed /app/geth-ro" mkdir -p /tmp/overlay mount -t tmpfs tmpfs /tmp/overlay @@ -32,8 +32,8 @@ fi START_TIME=`date -u +"%Y-%m-%dT%H:%M:%SZ"` echo "Running the snapshot service" && \ -if [[ ! -z "$LOGRUS_FILE" ]]; then - $SETUID /app/ipld-eth-state-snapshot "$VDB_COMMAND" $* |& $SETUID tee ${LOGRUS_FILE}.console +if [[ -n "$LOG_FILE" ]]; then + $SETUID /app/ipld-eth-state-snapshot "$VDB_COMMAND" $* |& $SETUID tee ${LOG_FILE}.console rc=$? else $SETUID /app/ipld-eth-state-snapshot "$VDB_COMMAND" $* diff --git a/test/ci-config.toml b/test/ci-config.toml new file mode 100644 index 0000000..d4cf968 --- /dev/null +++ b/test/ci-config.toml @@ -0,0 +1,23 @@ +[database] + name = "cerc_testing" + hostname = "127.0.0.1" + port = 8077 + user = "vdbm" + password = "password" + +[log] + level = "debug" + +[snapshot] + workers = 4 + recoveryFile = "snapshot_recovery_file" + # Note: these are overriden in the workflow step + # mode = "postgres" + # blockHeight = 0 + +[ethereum] + clientName = "test-client" + nodeID = "test-node" + networkID = "test-network" + chainID = 1 + genesisBlock = "0x37cbb63c7150a7b60f2878433963ed8ba7e5f82fb2683ec7a945c974e1cf4e05" diff --git a/docker-compose.yml b/test/compose.yml similarity index 93% rename from docker-compose.yml rename to test/compose.yml index b0f113e..f0b0d84 100644 --- a/docker-compose.yml +++ b/test/compose.yml @@ -1,5 +1,3 @@ -version: '3.2' - services: migrations: restart: on-failure @@ -22,6 +20,6 @@ services: POSTGRES_DB: "cerc_testing" POSTGRES_PASSWORD: "password" ports: - - "127.0.0.1:8077:5432" + - 0.0.0.0:8077:5432 volumes: - /tmp:/tmp diff --git a/test/fixture_chain_A.go b/test/fixture_chain_A.go new file mode 100644 index 0000000..e15c1c6 --- /dev/null +++ b/test/fixture_chain_A.go @@ -0,0 +1,438 @@ +package test + +import ( + "sort" + + "github.com/cerc-io/eth-testing/chaindata/small2" + "github.com/ethereum/go-ethereum/common" +) + +func init() { + for _, path := range small2.Block1_StateNodeLeafKeys { + hex := common.BytesToHash(path).String() + ChainA_Block1_StateNodeLeafKeys = append(ChainA_Block1_StateNodeLeafKeys, hex) + } + // sort it + sort.Slice(ChainA_Block1_StateNodeLeafKeys, func(i, j int) bool { + return ChainA_Block1_StateNodeLeafKeys[i] < ChainA_Block1_StateNodeLeafKeys[j] + }) +} + +var ( + ChainA = small2.ChainData + + ChainA_Block1_StateNodeLeafKeys []string + // ChainA_Block1_StateNodeLeafKeys = small2.Block1_StateNodeLeafKeys + + ChainA_Block1_IpldCids = []string{ + "baglacgzamidvfvv6vdpeagumkeadfy4sek3fwba5wnuegt6mcsrcl2y3qxfq", + "baglacgzakk2zjdmtcwpduxyzd5accfkyebufm3j3eldwon6e3gosyps4nmia", + "baglacgzaxt5p24gzgsgqqpd5fyheuufvaex4gfojqntngvewfdhe54poe7jq", + "baglacgzapngkev2hcarm7bmcwdrvagxu27mgu5tp25y76kzkvjmrggrora4a", + "baglacgza5fhbdiu6o3ibtl7jahjwagqs27knhtmehxvoyt6qg7wuodaek2qq", + "baglacgzakho5pd5qpbxs7mo3ujd7ejcjyhstznb3xx3fluukdjyybxn4aexa", + "baglacgza2dbonmaqxik2vhbnfzd4dhcpyjm47rlbuz35cha3jy7jyxvrsoxa", + "baglacgza5gn7vz4ksy4go5joxn3zn2hgzf7sudxlq7fthztqhj2ikql3spva", + "baglacgzas6yxvcp5fqb65gglmrm4bd2rwju5uxhoizsq5bchb5rl7a5uh37a", + "baglacgzamzsn226lwcfyh6cdetnyzoxsz2zcdze6m2lrg2o5ejl6sr5dwe6q", + "baglacgzasogvybtxh67x26ob42m56mlgnxwdelfb24oobk3po3te6yysmmca", + "baglacgzab7rmzczswht4isr63gea5uoww4pmqsxrvgzn74wheqwopl36mela", + "baglacgza2ovtxz2bp6yccm56iacbpp4kgthyz4k6evyp5lq4rzmp2c23mnhq", + "baglacgzajf3sy2bvf2vu2d4hqvj3rvq5lblzp4qptxfb4ulcyayhrrdszghq", + "baglacgza4wczwxeuvdhklly5renpmti4x34ilhhmgdlcro5jjpyhowgvdwpa", + "baglacgzazikph4bqhr7vgs2xiqpebvoyazj27mftysmy6mzoigkutxdxt7ma", + "baglacgzasvwqbzd4k6hoheken36oszbb6b6dvfc46acsyhfqssajcqd4xzcq", + "baglacgzaui2r4k54xxqxadyjt25kzovmlelw4obn3fpda6gecswheklvrhia", + "baglacgzacq4j5rfibfkuxvwa5ui6zpeq7h6edgmquy3oguz6zxxbdkfw6upa", + "baglacgzalihtntqwaqxyc5z3olm3odzztqlq6d27rx5mdt4gu2bdxgwwp7xa", + "baglacgzat5btacphq4ie5kecajgxjfgvooqza4zb47w24ibv5yvz2dy7zyea", + "baglacgzaet376qv35issfdnd44lpe3xxtmzycg56mibqh3ehd6pxbxj6bpda", + "baglacgzafkeckix5qfiuuorchl6xdg2o6vis2qknjirq63vryuqcyl24kwxa", + "baglacgzayesgx5kytkdemwcwmhxd435ka4aqqpwm6qugtirlnpyoyjexg2ka", + "baglacgzamknqvkqe37lskybr6dimt5ngmihfsmnoe5mi4yvtu7dq7tylh5ua", + "baglacgzaniotnde2dyyjhdnud5batwqnq3njuh2gotx6hivafivq4qtt22oq", + "baglacgzaov7f7oz4onncim5hhnlbjlz7ozpom26kfh66vjow3w2s2cok6ska", + "baglacgzai2u7cil4gzmzbas3pulb7qr4vzlirt5wwiyh57slomwhepqdpfma", + "baglacgza6twdmxbxie5v7ht5hdb4mqezel5cuwjxk7xwc5vxfepn4wxcwllq", + "baglacgzanax447kk5lah6ed5gqzg2eefwyygfn3l3w6n7eio3w5ohhluo7ca", + "baglacgzawxgpzpbsbi43icxcrchpoxxcaugcsvh6eusiswwjrtkdlugveana", + "baglacgzajshfqz2lgrejfi37nhstsxmjeh7c2jfok4znn4fezhmr2mlwpzhq", + "baglacgza3ask2jt3sjqfdiuxxx3fjipnxzp2u3in6z5d3qflo5fxh7ihmf6a", + "baglacgzavtfwj5dsgw4vpplzv3zsw6fwiykcpz2lpclspzq55u42vij2g2pq", + "baglacgzaelxcuf3wfrqavkk2uunaqjwp3wiuisjreuarwnbiqtdbrq5kwkuq", + "baglacgzajieha4wgbglqnmt4wbooug3ffnvayz2lqkqpop36elnocsvprkeq", + "baglacgza424ea7tewjqbcwi5fwcticsbiinwh7ffdf2jeqrmjzrpv7xpo75q", + "baglacgzajg3cp7yoxohz7luw4hzvg5cnzcduabrogcqy7ilhwhp64nmsn72a", + "baglacgza6ogjls57pq4k35agbzpeydujoq65lpoimp4iv2d6cegrdjk4frwa", + "baglacgzaqr6cfr453mxviwkqsjfz3riq3nw3lrh7lmev2nuwoop34mjmgjta", + "baglacgza5wvocvjvd6bdjteyzt3y7sdimlfxra6c4ndihqlk3oewgwclny3q", + "baglacgzamxpcef5svw5bshjcmx5dtw3jvdnsqxyqdoystvutgpk3dbxaddsa", + "baglacgzaihrnrw2zuaucifxzmpyg5kz2evaagrybgq2nm4sif3jhr7mljnka", + "baglacgzaydqlktfraw5nig2lsjmigudumpo7vzy4mgn2fza5nvl5ukri577a", + "baglacgzab2orhwmiw5gxfsqb3bwckhf3tf5jztbbdn2i5eyk2kvd3zfi7hlq", + "baglacgzamfflp7uex2uddjuoly44nywthhnugk4u3tjjvr2542km7rtecsla", + "baglacgzasfy3a6qvsisuwzgjm3w7vukbubffxx7ei3eqh7f3v2ftrqrfhiwa", + "baglacgzayrdorxqktwlfykcpqo3uhyfds3rlsjy6rcapz42x2lsc64otdonq", + "baglacgzajwya3t5k5mqyvipqqlahodjmmsljwe4df42igrc7pdgqzbc725sa", + "baglacgzalc6y4rmk42q6ix5cxhpinwyhlbnjobwb4knsqr3xe6qv7m6qkibq", + "baglacgzaidbvljbgsc2tpdyjwzcsqpszjotijnbls37ropeazffsoi2wamkq", + "baglacgzacuyuir4l6vee5vuf5elh7tvnwzymf44c4qpzu2ipo2tbbyp4e3oq", + "baglacgza6coc33lehemkv73byblozayqgaclz6xko4kla5pcptbgwhkyoibq", + "baglacgza7uco7rtze752545y336slgt7pczgdpmkb6j65x3yydfsprerba5a", + "baglacgza4eanzp6ludjfoqr4h67bzlsxjartrqqeq5t4pv2q3b4x2padxbiq", + "baglacgzaoocvbederlpqaufwkwso5pl7qkfnrpd76zj6zbwgj5f4qcygis3a", + "baglacgzavx7pxqr4m7pfzcn6tcc7o5pq4g5tp6qvsykkhe6rugqat4a2kuxq", + "baglacgzaljiw3say55ek5m3x64e66wcifr5na7vbutyuu3m74gimlh47g44q", + "baglacgzaqrzyy5uetfwsqgfvv624scsdw7dx7z42pf47p2m3xuhqwuei27ha", + "baglacgzayxrz3npxgaz2byd4onx5phnjyfwxfovjbztg6ddrhwew7pvynq7q", + "baglacgzac2cndcn3vq5mnjfoz7kdnboebmshmdmvnb6aatzkwnegyfug3cqq", + "baglacgza66vjwzsh6wgfv72zygbwgh2vufhfuagmf36q6r3ycnwxx7yaxqnq", + "baglacgzac5uhfzgshqvvqme5iw5rx4n3g5lij4eapzaejzpgm6njrec45qaa", + "baglacgza6ta2auxqjgh7o2oj6x3ogcrx4cgfxlupdccrq4j3p5zjnahnq7mq", + "baglacgzaaokqnkj6sgq57ikquob6w6uhvo6v7ni6uy677pqzr24f3nyll5eq", + "baglacgzavwymwhn2owqnbm43vvqtxgd3ab5caqalvs4sz2tzc4cs74b43q5q", + "baglacgzahlzt3rfhisvv5xkcyxc73sm6ijh54n42zfsq76ysi3jisro646fa", + "baglacgzaqhglxiq5ptweegtm64wuezj7spc2u2g5prw6zdgnwmjwfxdbn5nq", + "baglacgzadztftc3rxrphupebphkbwuzdtnthtyl4pfxga7wghxthe463ncya", + "baglacgzaz6agggjviebqoyw3sdos6z3jprjr5fe5vprt7dlarq5gxm2swdvq", + "baglacgzasdc5a3pa4mtp46bpsru56aojakeucvy57654mq5o2bjp5mop6l3a", + "baglacgzaqwwwnlav6alcw7r2umugzbxppixu6mqp6w6qyriffo27mummjmca", + "baglacgzabmrd6yhbgxhmghn5nguatwnzhrondlaxmagzxyzqdm24gooneucq", + "baglacgzajblmw25dyrzwsfymo74y5h67v4nrfgxs35eevemvqfui3y7rkszq", + "baglacgzaivgvcrgjwicuf4aremv2hbggrnzntrddmydzud6rkbpb3xrbpdia", + "baglacgzagpnopg2w6cmfzi3avh7c7ovd6rlwmnpu45kkb3wmlx3etchiggkq", + "baglacgzaom4zyvyb6kn2hoiyvwg2ywrwgr7o5fe5c3p42z4vuhfzuxmlaoaa", + "baglacgzawj7icprvylimlisn2p2626vxy7ukwps4t67gvrhduz5hlk4aecyq", + "baglacgzatnjb6dg7fsz4pesso63i63c3t2agwybbgd3i5u4ezthjuvddspea", + "baglacgza5oahzgmmqeqqszmqsfbwaq36gbirizq6aii3zm3jyud3pgndchlq", + "baglacgzaxyyowwmsdsveoyjw7ywj67krm3x77iqyy3gzj7fdc4xnzjyirsfa", + "baglacgzaew7pv5vcxev3udk3dh4eaezwpjgi2pxwqa3umwmtoiw25q5foqwq", + "baglacgzapexdm6koz42fosvv4qjbqhnhsuevh7oqmqwonspl63t2vpjqitha", + "baglacgzaixcais2z6gwyafi6bpptra65xswthhpd5g26yr3d6ahn3bl2uvca", + "baglacgzaimssao3zceshkgh6gltjqqqh2x5qiodirixcvjqutgvdphog7dma", + "baglacgzacgrm2zlg4dogiza57lwcti5r7ga6ucswdsp3mp2277jfa7yx77fa", + "baglacgzapsts4gledg5dyjaileaqdcffv5zcw6qooifqxgl26bxsoi2n4waq", + "baglacgzagz2qudg5ucppkpoeu5iq5nu6q7527mltt5i5kldaeffx4djhnxoq", + "baglacgzao3ht5gq4vbud5g5wbwsx5wejlbvgecqqadditqhk5yhbgw4tkbna", + "baglacgzacuetfnthnppfxkfzgfza3exvy7gselbqv2s5b6czidll5exmqwza", + "baglacgzaqbgeg6rmbd2zxpucpdd73kb5bmmo6p2p6eonafojtqkwi563ycoq", + "baglacgzape6j3mhckl4plr42twds57ctqwvwgku5ymjboy33gue7z5xqwaia", + "baglacgzazy26zckarnz3jfpcwpqo6rwr5r4wy7bonmc3rljbkr77uoiyoxca", + "baglacgzabadhauzo4lxjpslyal3fb5gfrs55hsycsd5r2mj4mkvcgypcvs4q", + "baglacgzao7aftivtmdu4sz3inijqfjajstgwhka2vafiigmr3dz5on43ndvq", + "baglacgzahtfb5mhojo7zknjhyhnf6o6d65wkz22ellgvxvz2cf32dhrno35q", + "baglacgzasx2czupgncbldxwxkqkxez6tt2oldw4iocqrhc7gk6bgp26g2slq", + "baglacgzaqeijuarx6vrtycc5267h5g3xzgskgaylrftmyjq7vjouxvkb5cvq", + "baglacgzalc42jtx44sibtcvjjhz6drbt54y6lcxy6ucmngi7cvdbajiebndq", + "baglacgzahbvb5fbnx2ddikyx4lulfcrftvw3mxpy4bpziskruce3xhz5tcpq", + "baglacgzafgf6pv43422ibuujti24hazwtn3ohwylzgo3mt6qu7dven4zlqdq", + "baglacgzamet5xv7ury7dnkqy5yltgbvalcl4ricsvdduy7hskmyxslvsa5sa", + "baglacgzakxelvpgmk3loheqewteco3z4pusavgv3cjj4xzylahmsiqkwovxq", + "baglacgzacqbsc6t7cqligdehacd4kjg2xlpdtbjhd5xtngqswaiiqpdrsj5a", + "baglacgza72em77piwedfycox3l4y7qbskqlptpcy7r725im2tpsj23si57ga", + "baglacgza636axkok5ao37hjupoeksmk73f3rpimd745avfcoxzwz53bp3xiq", + "baglacgza5n7yqni36tyi7clfxxfqciib6j4e3fru6ye3eticdb4b5i6k4m4q", + "baglacgzanbkitjrv36vsbyxc2fazsncuapltoqi5yxyntfjtp52dfmw5z64a", + "baglacgzazswo2typlq7izwoll6w4xnd3dszwktreiszh3b7w2kt2ucll5okq", + "baglacgza44bydaixin7ymaidhsaawjsemc2wkds62ahiaqrtctpvzo6xitaq", + "baglacgzay2b7jkphp4kufkhmwiriduyg5kgmqyzjojikd6hvib4bycl6fkga", + "baglacgza245jp2gg7wvxvbuvdxxynbsfzynj767o5dv6tkgsaghgsfsmvfya", + "baglacgza7hvenpvtima4lqksljjfeiou2lwhy6h7qvmdaxrvp6iglprd5ecq", + "baglacgzarrbzhd34po574cixc6tk2wd4escxarqzoqnlmplqkirhq2ms6wla", + "baglacgza6wjkyvgipgaxhclghpthoftpkarjiprp4g2smf5b2foc6nj7e7oq", + "baglacgzavtod2r5swzrok7fapkssy4mufrtid37trvz2jxzhnifxh7rdgxdq", + "baglacgzaaju4hfbrfcsgxp2dqrqdjrrfdjwjhbcubmmum3wsveqgsisv5sjq", + "baglacgzagfnw4qkfwuqlrd7v7nryxergohxb5s6lmw2xxgsl4zikwh6odu4q", + "baglacgza3ieihinvg2srwi7dupigwsahksvrlhninkyxt4ewb426uqmqtjnq", + "baglacgzaapcyag7sitbiyxcdbbj5m6l64vhx4gt4hbhvdwgjuhoezwlmw5hq", + "baglacgzam3qbvtektatlypk7kkdidh6fra67umeugmy7dz77fful7rl6ulia", + "baglacgzaeifznjadvk52cuv3qvbitazdkkavu4q3detg7xqhmsuykaemme3q", + "baglacgzaqdcmhkhjwdwatfshq4axfenrhggqceqrz47yiupwweqknnrvqfya", + "baglacgzanr74m4zutwqp4ybkpgdyborqoccfnigwlv6ze3hyou5jlrrnxchq", + "baglacgza5zaewwegrxjtaezosakyqpplolmav35eqfdyjju5okk3tmogbtkq", + "baglacgzavsgqcwu6m2hvq574yoi7vyzzqhaak5yjn4cflnbn6t4oqce6zysa", + "baglacgzafnsgu5ksxa4sv2kcmn2x62m2e7losf3ljqdlt7akoixyso4wi6kq", + "baglacgzatcbgkfcnzesrtyfe5hxe2yuqek2hvgmwvla2zjo3i4rvhnb2k7yq", + "baglacgzavzdzgv2mihwc6qop5hkv37hhx26dmnq75sfg3jf4nkq5vd4pjvja", + "baglacgza3oids2arkgomy6bblcggrwooaqyj3foxbxiawhckxhyc5phxqzgq", + "baglacgzaj2yfzqrtpjd6luyv7spcs4xyrmrifsxm663zznegzt2omto7ktgq", + "baglacgzaegino24jsful2fjnpe3haf3hhztdzzm626rdtmksxauccfzv335a", + "baglacgzazvm5p6m3ynh74glcwhuxtw7b3hv47ml5y6mtif2whmklebfd2mka", + "baglacgzak7v5o37lheriih5julg5c37gc3wpxmxudysjo6fttnju65efl4ma", + "baglacgzafkusmmr2rw7vijysdeldocemzrvwszho6nbvxakcy3buf3ytk4oq", + "baglacgzafiiwa2wygo4qm76xt3tekscp4ioub4u34vz2aqptp56frudzgjkq", + "baglacgza5vqm4jugxseggsbniznupli2bivz4drwupzzyfubqmt2cggrk7wa", + "baglacgzae27ionu7mlu3ojudqd4a2ywhyrenxw7zrshr4jhy4ld2fqpgkkia", + "baglacgzajdmyteoo6aovcp4w2wfnqlwp7hhncrgkajtqm3fzbxo3zhoko5na", + "baglacgzaan3c7frug6yo5tyyv7kzn6bzrxtwkwy35bmuvikkq3v4i6suovpa", + "baglacgza7p3a62673mtcsidsps3ep3atul26nzldgscxv66rvkmqj2gjdejq", + "baglacgza37tily665vel2tvvcavpqtj7n3qot3zxvpsog63iqkxmfldastva", + "baglacgzaeuvjvxxqf42qg44zjlnpje3ls7kpu2hx36uho45n27jjikys2jiq", + "baglacgzab5yedqfwm3pczaqnqfvsondxhdyorywu27q6strjbc4ixq3glizq", + "baglacgzanynqqlgddfsdtm27kvidm35d75yocvndtsdeijt7z64xkilxin4a", + "baglacgzai5bxsipie422mzr6u2itm3wgfyg7p425rcqn2hg4453fxnepaa2q", + "baglacgzaarg23ok2cd5nr6jc4ocetujiqb7nnrft42xvfuh2vbs35dfyqr2a", + "baglacgza4ztanbjvytkd7462vy5jbgwoqypahkw6gzi6a2h3ktsisf4wajla", + "baglacgzaqp33qaf7bfj5w6e4k63cbrc3oqemubyxgjmv7wjcroatsqflba3q", + "baglacgzamwsrbjbo7pyf4ftaizzj2lsqdqhivh7pu2evcgraenjg6sx573oa", + "baglacgzagf4zu7uebnql22h7pmuxotzjcs2y7y7o3dz3nsogfou4dqxa7pja", + "baglacgzaaqveulltjfdqenhsig3nzfwdwxso3ndbgovg2gnczkqop7vpbbvq", + "baglacgza22ifq7h6bot66tpn5xudjfcqtydvk7bcang7lxosyfum4ifhd4cq", + "baglacgzarr6a6fovyug5em3cqkzmggna2nvjohihdin5ffn4f7k3cm2qc5gq", + "baglacgzaao5djij6f4x3jp3qszkawqwusvofe2mhloopb55yoyzfqxkezgsq", + "baglacgzavcbrgucanfxqhbshrz2hv62vfkrtrhlv5qx6swbc3zavqvcn6zta", + "baglacgzark7ier7445klswjg5eqx5qxoiibq5mrmbctybd2ffu4gwffqkwyq", + "baglacgzacahqtmufgqhyzdgynhxsezldqc4merrerrf3y4jw5d64umjg24oa", + "baglacgzasfdhsvcjbujhmmosulzzu3w2xvyccu66qf76rwrkxgrqke7fy3oq", + "baglacgzast2lxo3sgtk5qtnp64mwxyjuozwyt5v3rg4ytrnleporcqmb62ua", + "baglacgzauwwnb3h5pxhm2h3tmcxrc3t52jlbpibalnpywnu34p74pbge6wuq", + "baglacgzasb5vgdsv56jygtmspwoswmezrfnp2kray7xhuszshqa2dfrs3ypa", + "baglacgzabhaasbte4bwnubvxduslb4am2dotafbel5lxvzki3wn5rs4dl24q", + "baglacgzaqm53klhsbyfek6wnzmzsah7iz2km2euk75yapvez7fyl73gfxhxa", + "baglacgzawaf7gawvue34nkiksyyrpizlmtkuu275e2xxhaxiirhsmmoeo5zq", + "baglacgzaaqtskzrmoaoexhra66tmvdxne353oxcxuzq2dca75ldjrqqhoiaq", + "baglacgzao4txzget4reg6nj6uwptwdu2n6sohzyfeivkdwdzvziouna2uvua", + "baglacgzanm2vfedt2eqsljbb3iwri7hu73bnb3rqgrurkmrsacfzejju2nda", + "baglacgzavxzbb6zhtlf42msx27zozxk4a6twphs4qsxchlrt2ny6t5we2t3q", + "baglacgza267mwypnyml7gmua2bifcmpndmtwzzw2dfjox3dfixo25uopnmda", + "baglacgzat2wiom6pryjqdoptciek3ckt3ctgdeujprivuey6ypgfsjypr65a", + "baglacgzavz4xq4u5fosiyz7ldtzluikmtco4k3mv4xsrnppjz5omgutz6abq", + "baglacgzacj4uv2ru2opsecdduklxkbxl4vkvyk3ercuunh7nsgfxit3h23mq", + "baglacgzav3o4q33y7amd7bgpfs5xc3kog57nnhbruh2s36pziymkmv32dpgq", + "baglacgza7hx5cpakzowq2h26ocionl2t2p6ifhui6pju5xug6wgifi2xkv7a", + "baglacgzaty5w2ykcxoxf2zfdcr742hzezg32vyanvv2qz6hbox7atjqknqrq", + "baglacgzaoyoxana7gxkhxwj47iiqjv76y3ktnk3kootf3pzfpxcpmzp6ptma", + "baglacgza4x65ftjd3telo3eyyzrgosshvnlu7kj7enzezkwiowxsentq2twa", + "baglacgza2u7imlxl3apzarjovwuegtp52a5h546qnvw3hzumxr6qlx7yd3aa", + "baglacgzay2imkpytg6m7kmq7oloogxzgfc6t7sm77spappsm2iajkdsqif7a", + "baglacgza2gxxoee4k2cxdf24whfylc7x2eb6eshvrunugemjp766sxhbx6qq", + "baglacgzaz6sqay6zefbflfsyrt43nsszivnrywlokmridmcox45ehavr2bxq", + "baglacgzawx34khb3fvi5s7yxduvtrjg7dj6avtc6wdpenpxp6tih6xwsbymq", + "baglacgzaxh6czvlet4gmuorror6l6m7qrr4ymkolyr4lzofbme763w2peijq", + "baglacgzaw7it5iumtdpxyfxvlizcwsthfsemmyjqmb5cq24hemei6dftsjtq", + "baglacgzapevdnthqwueqltoge7dt2cuxvijmhep7rw6cnp44pemp6sluitka", + "baglacgzaesu7doagjxn3mknma6nifhvfjoznwlgjqomq6jpxlcejioxu2upq", + "baglacgzahojkgpcys6csj4cos62mt6fwb32xsoca3l42qci34zqjmtyvd7gq", + "baglacgzauefudv2ingzufqe36jloewm3xketyjvnc4e4djtpbathwjm66a2a", + "baglacgza6z2kpaqbk2lezgrkqrznv3c7uaomvab6646z7qo6n3rsbz3qpbka", + "baglacgzaeqh6atyhyht4qqqvcyuxdg3uqfu5x2mujowput5bjcuor4vnzrla", + "baglacgzatwt5s5k74dcvrm6d32p5zx47fcxgihzyzf4hwbnxhkzcvzj26pra", + "baglacgzaszpquuoaaaq3auktxvag6h3fuwpnnrv3chfrymdwb5khdqwfxa7q", + "baglacgzaf2bu6l5bt57gstxyudjbbrj6jddfac3qmr5jnkt6tgwbj3qpfavq", + "baglacgzaeph54ay7tbgyox3437nbngzluz2k4kkqmjh6ymgbuakg2c3mf2da", + "baglacgza2wso6cd6qxxk7kwtcgcx6gg3nztqk7h3kepb7if653mn7magazfq", + "baglacgzax6ioorxkqyls3kmv2ntmfhsbptavrrtit2vy6zmgbnltjjbyogpa", + "baglacgzawf46giyla7nssrdtvzl7afycmj4y7dcvdr2vwvtfvtqscxhocdfa", + "baglacgzamyk5sdzyg2vnuzaqmbwwzqbbh2xxgfcouukhmcjcudy2jdw2dy7q", + "baglacgzaizfqoqu2aubz4iutcsjnnrrfdkdayamouoiaixkznmnmcg24pktq", + "baglacgzazcudtwhvet6q264rgjonf6nt2a3omigym5wpabkq23kdeyvxqr6a", + "baglacgzatymnlewdcj7uqohfdcrcszva7nzezhgib6risqpenllqdfch3i3q", + "baglacgzat2pxiuhdayqh4ma4ss3wxk2uyipuciqonxig3z6jitc5kdmrozha", + "baglacgzafokb5hx5vy5ltj4ee6ndad7c5fbak3j34ap2j4u2i3mbt5oeqkzq", + "baglacgzakuwsijjghgtk4522uhpxad73slbechnou4ug6fmniqebzals2bza", + "baglacgzaxl62rn4xijbrpvuzkbb5awzhuasuihynltlwwau4lij3rn64rb3a", + "baglacgzairaleq3xeadqowm7ec7kvxmbjsmqrltobjcqjso545a3zdcge72a", + "baglacgzao4vipuem6ogey2f73z3qs2cxdk6rn7jygxfzajegxuxfcxktyewq", + "baglacgzafufkadgo6qcmddvnavloopfzmozwxi3p4h3mjn5jw2xmj5ws2ipq", + "baglacgzai3dvv53agiud47vx3fs6gpqg5gvjze5xsecatnh5l34e6pgocbia", + "baglacgzawug56abirtemcm2skgyexstfmmrvivru3xjcgdyxqtj7ef3jxnjq", + "baglacgzau4tmywowb37dv47edd7pl5af222ba23pfrlukvkbersc6vrv4qwa", + "baglacgzabqzaabcpgd4pnucu3izbykoognju5kc5qwtfkualy5r6todywowq", + "baglacgza2g5mo2mblvbfjjrm6xk2ppf6jplupamowaqb4j67szvaytx3wfra", + "baglacgzaw7ftkn6xzbnwyvievvi5xuoqeodvbdwirel2cvx4a6kracedtiza", + "baglacgza6anvax7pis7sukuzo6t27drgmckh2ahdork3wmzhqquidlakjpqq", + "baglacgzaywc4cisesa54dmxrzulfzvg37ldoe3vebiqoncqtrhdxaypepf6q", + "baglacgza5ndtrasv47fgrnbpuvqyaam4mhrn2ma37yqce3lkotlzl5vqc2ta", + "baglacgzargpxdk5rrrwjkyiyx5lh7ldctn27p2ksnbz6ikot3cv3nw5vqaqq", + "baglacgza4rw4nllzvg5j3kvvrsisd3jcwgq7htdege42ris6ddkpiti65ala", + "baglacgzaoao7i2mmwuopg2gfx5m3xn34fayjdrov2yolscqtz7vi5emdqdna", + "baglacgzavwgvvyakic262434m7kigrzlmqautwbknymr4fyngjkobh3cyl7a", + "baglacgza6gta5cebz7fs3riluwgde3gmtjw2qkd4dzpvnuqbovr344aaldca", + "baglacgzao6ru6zkgi7lknzzc4xogdvi5bkoux6gaoj4rejbazar7yavge5ta", + "baglacgza2lsx6yk2i5iiy3tasnjvgqult7a4y5lhpi7lr5pxhvq52cvp6x2q", + "baglacgzatou7j5blylumwrr5hfsck3hqrasegy55ewwgldtwew3uykaszcmq", + "baglacgzaqi5dqutwokxefveag2nibmfzylw6szglsntiybeh4e2bmb6f2xxa", + "baglacgzaovkdfxjerufbq24zzqm767juiyt4hcu4ivlpvxh447w66rpfvtka", + "baglacgzawez7iipzfpgi2jirdwusmbvhdjporhu77ejvoam7duwmequa4isa", + "baglacgzazlnsvtqu4zd5tjtz5bct7d2aqiotmfsfg4eg62bki6qiti6fdl4q", + "baglacgzagfqonr7vtlbdofwm34pkoz325axn2v4pxyxbdly5enjbfnwo6eyq", + "baglacgzaljokkpwqxdoaoyrmsml6b7b7zfiqefbhwxlmexxepy2d5wuyekya", + "baglacgzabu6rq7xkdr5uoe2eunlx773yg2kk2h2lho53ef3c4adky2jhs6fq", + "baglacgzab2hdhand5g57pqt4uslpy2mz6rqnkwlvw27bczvsc2tj2m3pr3ba", + "baglacgzaugsxw7cthfl3fg2rlhemgut2hhitktn3bovkjd5hawrvi5ss7gsa", + "baglacgza6wtl5yiy32ruo22c75ysjtnxrghptmimp6fp2pq3ilpaxqyn6c2q", + "baglacgzauokbnjmp7gn4sz7e247j7ift5hrueq4zzq577m557j3bmqnwfixq", + "baglacgzac2lofvuakrf675xzz6hh2ahgbd3z77gxc3ofrjolqjqj7dqhzopa", + "baglacgzabsc4xuh7rbvblytwkhn4swzctyu43ba36xoehvuc7cpmbnkd3ska", + "baglacgzayunrwjhott4rnqk7fniizbsv55apaqalgup2fnf66qip6aartkcq", + "baglacgza3zbafsnpvwa5xw4xpjmx3ndhmuhynaoxxrzwcnfxi6o4rbwpu2hq", + "baglacgzaqm4ijihatant626rqycd33xaerqj77zivb5iwmgyaqwgysc3zf6q", + "baglacgzal6llyltmvocfvqgxq5ltwunaus5ntfhl5ze5f35kd67oj6y5lq6q", + "baglacgzauyqu2gqzcc2xtmahbe4bnlubzp2thteevnp6bfd3kxpnxozq74rq", + "baglacgzazklwtf65v4dpdcms6yqh4t3kawlz2b5m5lmwk2afq6eqc7gg2bvq", + "baglacgzaoyn5xje7zjq52lswouegf3w64k4zhyqp6iclfsyj7wgjfjwyvicq", + "baglacgzanrcxybniprkx7bhw3ggpwn2uuigb33ifkdxuavbt2niu6mzmo7pq", + "baglacgzaxxsmknpbqxei7ffyjb7fhqtvfrwxr4t6zloyavtkt3jygvsldlra", + "baglacgzaaiqagvbyp2jrclsjllilvba5ajksvpj6rsygtcx5suskigolta4q", + "baglacgzatghruydgf4lodn6vmjtvfpvf755goj3jkeusdwia5pixldcqjmtq", + "baglacgzamfrwerukgoisehrxqlnefyww7ohkihngxxjnm6pcbpydoxagcwda", + "baglacgza4ypfm4rxwsoejwhza3housicojqliaimccsupm4nrmjrxhj3n6ca", + "baglacgzagp3wukeubt7wqrdq5okknvbyh6rueyo5t2np5rg2whot573jq2qq", + "baglacgzaxjrq5medoijedijmlrkevn32vsthf6vhgtojvtlttxo2ze5brbja", + "baglacgzarwmkoc2al7nxgjxdysbzdiq4yfcbthxhbs4hkquxxnevsoxnwc7a", + "baglacgza2jleouo2qqbrfv7uc73q6aw4svm74ltjhzhsqhpmqdcsxmvjxurq", + "baglacgzajno3x77dsi7inf4voolwgevuslix7ays2u6oh3z5mq2klkwbj6hq", + "baglacgzar2p263trvudcq3qwjppcpfgzmxc4taacjtekhkfzsqtatl2wp27q", + "baglacgza5efjepjsmz2y65dfccco56i5jvrkn3wochllzfze6k3o54qkvlaq", + "baglacgzaxrwu73uyvnvmbfuepvcxeryunic3ozbn6t5uxwypoy4puej6z52a", + "baglacgza5ux3uey7vxvn5miif5lf77ywz2yar5utavxdcqbai4lma4446hqa", + "baglacgzaufpcg6e6rm62ybb2a35vwtk2ptqt4z74pj3zmii6rx3a3dwnnw7a", + "baglacgzabnitw6kehgnmpyrjdk343qnzt4cekjlmypymhnvvylkq5k2ptcdq", + "baglacgzauckhnf4srmqecrryxiflfpf6kavfhm3d4qmjzkxg27f5dj3546cq", + "baglacgzapxzpwc5xrysx6y74fs6pybyqlfly3olnv5zaazqsbuztbopuc6jq", + "baglacgzaqtea7gzv2h3jroibscowoifdm64hvqievgvxg4v6kymat7e22ncq", + "baglacgzantxg5ciyqddbw2tjz5kwrbh2lmxikruq5ifa4xcfsiwfgs2fheja", + "baglacgzajv4bm22iarh5ykhneljp2ooi35xyvkqezny5hilsq2cw62et76bq", + "baglacgzajiyfhc7uqabfypgpvip6dildryb7c4epz3tzxsoejbliwozlbphq", + "baglacgzahsh7cceh3en65fkgjesotsxs3pqbhflxzv5kdkxnz67jd7c4pczq", + "baglacgzaz7hm3bnvwozlapazmwe5hu5zxtin37ab6aam32p6hsvudxdkbila", + "baglacgzaz5yvtye7y27sz7oitmxfgt5yvqdzcn6z6x2vxar7rvluzqoh6dfa", + "baglacgzafelbojewhho2qlzz2d7txvh7ycbjntfmqkwdxkiw6raesraqfznq", + "baglacgzawat7pexa2n2lq74lyoq6axky2qzzyf3h6sa6hrucjc3z45elm6zq", + "baglacgzahwk3er5cckpklgmlw57cna2p5hkwwekjkkh4iz62pm5ybievfqta", + "baglacgzabi63cfckdctmkqdhbcdwszzatr3bfcyyuaocrgnypedvjmjog2za", + "baglacgza4fxgurqdgfxs7ja427ikr7e2rxfhzi3hmov6hg4z55l3qow7kaiq", + "baglacgzaxq3k23qmqsllx7iz2ymhliqz2jewob2nckhdd2wkxtf3rb5drpwq", + "baglacgza5nzqr7e7b3h2gmbxz24vdcmfcoadnzbie6nbtvigpyfigqerrxja", + "bagmacgzakvveqidigvmttsk2gqjl3mqscorqcsb63mnwiqbpwzvmt42ygwmq", + "baglacgzalodtjmdplb7dy2p5arsxk7nyszh6lhsyzxe4lgkdgrp6rymxzela", + "baglacgzauzvc7x64vjf6wlwaisddf4vf6hjsfmtlypnadtb5i7kbbasizmma", + "baglacgzaixlti7he2ffvgp6raqotxkdsekh5qy4duv3tmtn6kvn4n6sjuu2a", + "baglacgzathtbu757wgovtxofbnlsnsyad662vbnn6aqk3oyyx6xixtxsw3oq", + "baglacgzaz6ajmdnij27zbfrxugyesam5i6m6cezxfveoxjadnolwjelszw4a", + "baglacgzaxzceixddm72q4dlup2gwlsoxfykcejxavmskrbravtwa5xcvnktq", + "bagmacgzavl6vwffg5wwncspbcc5go5vgktznx76kgqeqfputhuarce7soubq", + "baglacgzawksvmxhdtwfx7k5silyip4c3ojz255cast2bmycgzxozpb2rys7a", + "baglacgzaywze5wn2o5cvdrdekjdjeet3tt36r3wfzwpcop54iumbvrex6zpa", + "baglacgzakbsr5nin4suyz7r3xxzcxkuel6fghs6zrbw2yi5ez2xo7nloerpa", + "baglacgzay5ujimrt4qi2ksavtfjysqjsn5m6ysxizi6hg3gqhpnuj362d7nq", + "baglacgza7q5xdqz6fzvxprpesta5w763wrduopyahwxtpdd2mo5jx47qasoq", + "baglacgzaisv2zdtclyzxlffct55zevsfb6wxmu462ft7et5qahpdqrnmcsba", + "baglacgza5yyio2rxxtbrkpk7vvv2iyp7pfp4bkismdma3mk6qkxlhsiy4f2a", + "bagmacgzaugn6dwvyjeqblgmuhrlxoerqgrzpev6uhsmi5f752q7kfsdiuqxa", + "baglacgzaq4oyzbuduaeeg3ww6bzspstpbtcb7tiyswmaaymfpvao2hqwxcva", + "baglacgzabqho5affvmsfef3cnd4xsw66l42d6ena4g2xedujct6qsd7o4a2q", + "baglacgzapohhuiobc6gsqb2pcv5vb7fil3rfyeswr74os4dnzpg2zn337bka", + "baglacgzaovc4t2yesyqvzvdsybtp5k2y4tb6xy676gwnwsr5qoztogehxj4q", + "baglacgzami2ovudshhpsyi6vbuq5fycfgmv3hyx3bjacvlsxqc4chz6vgcda", + "bagmacgzafb27j6ni6j5vwm7kfxfwfuqau7m4raff5v44ulu77z5wwp2bpnaq", + "baglacgzaqw7dbrzdyxhjsdn22orpgfzxxwdqcf7hn7ugy4hl665cckc5oxja", + "baglacgza5psrwfh6u2vklqex6jigq5hjscatynwnge4z5y6xeztn4lo6h7ga", + "baglacgzauiscf2uzdir25zlogw4qpzwriy6mtgsyzl7omehok3jpmskk3knq", + "baglacgzas4zhiutice4t5if7jai4vedxkmo3adigxbrdpixm22b7kw5exsya", + "baglacgza3tax6aemhf6t2lqknaazzsksu2c4fjllgjx2izlkv47qmhzfgtwq", + "baglacgzakncmprlqvhlj4nfejd7odbude6hmeykm6wspwqpm7bg3xoqi5dxq", + "baglacgzaa5igkis4qk25v4ko6eryts6watdot3ark5uzlxm3o7j3izolxala", + "bagmacgzaomwzsxiv5cwrrjquk4ryb6z4u4xhuu5xhpznph2oyb53ixrsvvca", + "baglacgzafjhvq54vejfj2vrvtidr6nlt3e4azkw5jg6kdnr2dot6edm6mzsa", + "baglacgzasvs7p7bsxtnrb5fz25cx5gyh43tqja74ywrhwpmt27gnni4z3qda", + "baglacgzagrolvdnsflcwzcmqnbbyon3enber2hlamdf77kvhwousoyznwika", + "baglacgzahkj5ojwxjb4hjzi3klmnkngghkrknco7ddr3gb6a23fquoeladzq", + "baglacgza2zihxbb2gl2daaft5miumsjqbps3xgmip2r52ubrpii5zkpshpvq", + "baglacgzakhvmbzxior7nsroicglbhkbvts3weihhcrqqz54dhcgosaavgiea", + "baglacgzaqlswzpybvsbc3fqkr4iekizldlug3ak6qsuthtu5qtybmtij2lia", + "baglacgzaajspycacn5bhe4dpspprjoayo72z54wmrxz5n7m2g7of3eazijqq", + "baglacgzax7i3elt7nndzjenb5xkogpgelmcmmtn6lqp5v6kvyfqe7m5k5sya", + "bagmacgzauubmsoyzddcmmu2niwj24a5fui72cdv4gd73ocalff576jcg4qwq", + "baglacgzasqqcuuppbzjikphak2gz56fnuysk4vnlq6andul7yvwolmswisiq", + "baglacgzam2xbzezi7l6vlyicgx6i3kpiqceh5veonhmpa4pjny3eibaeolwq", + "baglacgzabirgkutruwdjfcpl6bkujicvpsixkwfjh5hmuy7xoamdysl23dsq", + "bagmacgzayktazfgfoa6a7g5ijetwofgbp4aphqxbok53sqoc7pfydslq2moa", + "baglacgzalvkdmoxvvqpflgq235nahqiw4xofhxzhuio2eljusr7uhrch7nnq", + "baglacgzazsxzdrr4wtg24th2crzvzt66fhg7dy3zppagpy2nn5eesdrsaq5a", + "baglacgza2vpmjbvshqsmj3qfuh2qfcx5kg654uhqbknb3ok25ppmhnfd35sa", + "baglacgzadcjenr5pr6xnfr6t7b64rnnfdv4h634k2zm2y34roiuuwpp75vga", + "bagmacgzau7hv4cknn43r7hxusbijdicen3yvpftldneg5zc2xmstgvhft2ra", + "baglacgza4fxgo45wl7zhyqula5ahuljoi6lreftfcwskipwmhrcejv35j42a", + "baglacgzasoghibkt6mikv6sjvnvv6zci47gjmnkumjzxhlei4tvq53e4jstq", + "baglacgzaivd7643lhy6s535ukinqa24onqywzkfnfhhi5r7uvawxtiw7urza", + "baglacgzaqwe44wrh2zpa7ogoka44yx6hox6w55jnndhymz4nerazqjgxedua", + "bagmacgzaha7rcryssphnazakbiunmc42bokxd5sgzrbo5cnilp3g2zt3vnxq", + "baglacgzab7lroi2stb2cmi6awpfpwpsl3bwawwvr64ijpng5dhz5nes5owgq", + "baglacgza6l4kyy7nsrg2lahabyhvclpuncic2sqtzvmefqofpuq5lnsdhmra", + "baglacgzacsbz24qw6iy2vviclvzaegksg22ryng66bhuxpj4dl6pcg32wzxq", + "baglacgzazrli3jvfluavjdjwgkt3qktktnuh6set2t7ib7hzhanobmwxwvla", + "baglacgzankthcaoqchi4el7hhhxyhmclkikkhyxy4grgexml7wyrnnch5bxq", + "bagmacgzaf2zl6rp5iq55dx4ln6oas4tkjrrffihxrfvbggqidy42p5sewoeq", + "baglacgzav7vn47ouq6zebmg3img7nmada6ag4hx25uouzqxttyptyudr46bq", + "bagmacgzasc5m55cldco577of6ixny4h6fggfrzpfeptodx67pw6g2zl7punq", + "baglacgzaerhefaw75qz4to3wkfrm53spfzrzaaz2ss3cbvikf7djipv5ql6a", + "baglacgzahax3xfs4df4ywelodmzk2zgztppqt6hu5vgihyntrd722dxixrra", + "baglacgzaeqyhcnkoumzym36selclrief3po2p4yj62juga6r7ueszzq7fsaq", + "baglacgza6oydtjhtene6qxdyfuiwjqmjbzn7c25nzhxez6bh3nvp2irj3xta", + "bagmacgzae3xnnb2gakf4g2plivvx2pxeowvbn42ol2vazgh55w44lhv4koya", + "baglacgza3esavhjnlbi5awux74zqkm2n7wybahq6gip4e6osxm6k22x2r7ea", + "baglacgzatxyuvssxlehlznynti47jiaoyj5kqevfdmu7yj4npmjr6l6uyhfq", + "bagmacgzattugdfyxhykoayz5xbgor3vdfrkfj3v6svdxsjkwis2fw4l6rbaq", + "baglacgzaf4sjbg7ya3pq737z7im3pmp5vubrly25hfkvea6n7pfapib63kyq", + "bagmacgzagkghv6zmldxt7dcbc6uoxuzw6gtb2jczcbt63hc2v2khs3fmtb6q", + "baglacgzavy2t2fxjdf7pgnx6dzz46eczpnjdwveeiihq5ev42guggtnivpxa", + "bagmacgzajkxbxnhzvomtm3vz3rtsokavrzinenk3anvvqwog6tg6byve76nq", + "baglacgzahkjgb63xoh6ke37ztl4npobu2gkyh3ae3jjii4daodh7utnujiqa", + "baglacgzacthcbn5p3sqfzmpzrndyhbcmneuptrfwr7s5disl54oz5nxm5s2q", + "baglacgzam24ldzjqb3puomhwshglrtjcyrcpkpva2wybbkltfws6tor5tp7a", + "baglacgzaqkecamlmyav757mjtk5ecnaglh6qnxy6bidzmkd6yksbcarz63ja", + "bagmacgzaquqfnzlnbsk5idejdyvjpchlahovlbrt3degno72rl4dc6htsymq", + "baglacgzaecczvtf4q7l2mhitw2tn4y26ysaolmicnoc542wkyvvrs47o7a3a", + "baglacgzavs7qjikqvxuxkpz5liqdyqrzaonkllqw6kd4lf2cxjltxxlgz2gq", + "baglacgzawwi2ftqcgz7numopfulozj6cp7ke3pyims3e5kbftljwnfxlfica", + "bagmacgzavhhx6zz2bphhn7kagmvp5bqbkqurbnen5jcosojtups6smg2lumq", + "bagmacgzao5vkivv2triaryb3qk4edkopf7a6qv4m7lgvzeavqbhk4mk7c75q", + "bagmacgzaolr6fbgupow3wcs4ufbb4elz2pvjbtaqpbnsnn2pxcub6d46qqma", + "bagmacgza3x3z3mfdnugicnf2cq54wva42r4vvgrlv2fmuc5cjogysy6cu56q", + "bagmacgzagatdibfm73qqhufragifh7zsid6oim6gtnyjqmlhgkc7uwehzzga", + "bagmacgzamsaplavqsdtlvhzyovqewgkyk26azgp6tfdbzz5ux3423eajsita", + "bagmacgzarsrnwni34m76ucixyqhwmzjzdoj4xyqzcepbbxzzg5kim7edr7dq", + "bagmacgza7dy7xmpxwsbntbqeqd7oxob76vfiw3wb5llbzr6s6joxyalft6oa", + "bagmacgzaxfz6yd2i64il66pwg2eeqv2vzpuh7hkmnazgxob4e2xwecacvaha", + "bagmacgzaxrdsjyn4vafqvzadwgre564iakz2owgrueiyjr7nh7evfwksnizq", + "bagmacgzaxqrzefztg4772fnaxzrwhela4py4iybnsucowa2ybg3jolflfdba", + "bagmacgza6ccvgsnpnp4ev7elzixnumoi56gfcon6deu65m62jotlncubrsya", + "bagmacgzayjy6dcno5mo3lvm5p7uh27lde656pt5drfqzafsfsgles7pdztpa", + "bagmacgza2ved5k3y3gr3yqiixnhlzwelsmbxmyknsvg4ci4jiltww5alcxma", + "bagmacgzamq3lujnpelx5hm2l6heowtohkwhuliyq6r34yty4hrurctkscnla", + "bagmacgza45idxjlztz32umn34eyqymjmuf5syw6mr6ry6jtgoxupcvgckfvq", + "bagmacgzafi3v5u4p4fgckxsrbf4u3zz64gfszz7pyihxhqio7ztn77yjwcqq", + "bagmacgzatjwpysdg24pamvqso3g4tjchz72pdxsqweyuubc2jrdeusscvmra", + "bagmacgzasj4lqrtjnu3scovz2iff5nblapntc46ojefc545s6ozwablz7rrq", + "bagmacgzas7lcbavos6lvsurhbzlpekgh35dgarm7nye26e7wwrooolwfbpnq", + "bagmacgzasmhzm736xpvahwm6jogaqeuieqsteffkfxfsq4gm6eb4q35a5d5a", + "bagmacgzaw4bsyt4rnl5koaclh3bkzwk6ez72sj6j5ghsks5a2r675l3tyytq", + "bagmacgzacmg7rh342shchhjofzwlwxrej2psqkf43jurovkweqpniytdzvha", + "bagmacgzacy2ji662bc7ppplvkyxlvjxqiwyo4j2ie4xtck6l2zwtbf2w3i7a", + "bagmacgza5ecbawirj6ojccw6zijnxoq75543fywirgps24qtzurn7zbravqq", + "bagmacgza2vdmjsrcpith2klzmzbqgjbcg5dcj3iqtm6zjbemlxagxlhk5z3a", + "bagmacgzae7ci4iimzrxac2dl4lkkdgotl4hb5dpwesunhil4cy56rbq2zvta", + "bagmacgzai7cz3jllwk7tjde52kror5ktrkjlsbfwmhh6kssctc4fq2f34scq", + "bagmacgzabu4xfmjm7dg6rf2fjjn62f57ilrchh3v4gbf62erabtzu5wm2gxq", + "bagmacgzanjgius6avm37j2fq46oahss3cw4g5ntlfjzf5sbtguzppyai6pta", + "bafkrwibagt3z4drtwcxgx34uquzaeg5m5miwvxzgczdyoa56y2yxgkprzq", + "baglacgza5n2ivltmbqypzfjptsvbzvlvhpbcbzlr7xj6xb7zaallj3q3bu4a", + "baglacgzal5gkbdbs4srzs7iostmji3r5gypmlubclwonqxdn5dkxfoyktheq", + "baglacgzaeggi6pqszfefbd2or7verp6bbz6b7ctkszxi6yalsypnivkrc47a", + "baglacgzawxfq5gj2pt53idroosz6eahmfmrwxuz5fpciiwmiuts7l4a6k2eq", + "baglacgzaj46wxqbpstd5eicctecpdxhffmbuenzqmd3bt5jdjykdr7aeo3aa", + "baglacgza7lwpiwksommncl7ofw4nqxcu7qse2aqhxizwuapds5mtxaa24ypq", + "baglacgza7wkyigp25224rkrivwellawayv3y3r4mobbqc6xxmgscxgiq3gea", + "baglacgzazrwcvecxj5bq6pyshnxvp35apsxcdtfzacvfbvsrnaa2vag4wnza", + "baglacgzabchzwz3pjqtrnx35rjav3gmxeh6sbw3l7mjpwrb6gbiz5r4ltcgq", + "baglacgzaokokv2ioov6fjlkgkufj4yrplnxdw47r4rqhighqnb354ea4jaaq", + "baglacgza5gcozkl7fbpnys3d7uqzmawqsuvic5lrti4hznllfferepgxojja", + "baglacgza34suygwx22xxdd2fynck4x6fjrrhoaxloeni45znn5ewpk3g7lea", + "baglacgzasrizkrumchv6zypcuhr5fmtz66ej5cnup5sjbapxpj27ttj3u5xq", + "baglacgzad3w24kle2itl3jm2kxq6cysoj4xoflsrhrw55msc6meagt6laetq", + "baglacgzazixckhuckariike5abthcbdjgmgz5rcysbuaucijz5d7a3avqvpa", + "baglacgzapdoq2uowvqcis3dlzxug57bwzas2dyhefu3f4frrqdz3yknzdxtq", + "baglacgzabbcknaso72duwyoeqd4i2gyghf4avilk565nkzduap6h5jwcosza", + } +) diff --git a/fixture/service.go b/test/fixture_chain_B.go similarity index 54% rename from fixture/service.go rename to test/fixture_chain_B.go index 2c520af..f576a07 100644 --- a/fixture/service.go +++ b/test/fixture_chain_B.go @@ -1,18 +1,20 @@ -package fixture +package test import ( "math/big" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/statediff/indexer/ipld" - "github.com/ethereum/go-ethereum/statediff/indexer/models" - + "github.com/cerc-io/eth-testing/chaindata/small" + "github.com/cerc-io/plugeth-statediff/indexer/ipld" + "github.com/cerc-io/plugeth-statediff/indexer/models" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" ) -var Block1_Header = types.Header{ +var ChainB = small.ChainData + +var ChainB_block1_Header = types.Header{ ParentHash: common.HexToHash("0x6341fd3daf94b748c72ced5a5b26028f2474f5f00d824504e4fa37a75767e177"), UncleHash: common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"), Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"), @@ -31,53 +33,53 @@ var Block1_Header = types.Header{ BaseFee: nil, } -var block1_stateNodeRLP = []byte{248, 113, 160, 147, 141, 92, 6, 119, 63, 191, 125, 121, 193, 230, 153, 223, 49, 102, 109, 236, 50, 44, 161, 215, 28, 224, 171, 111, 118, 230, 79, 99, 18, 99, 4, 160, 117, 126, 95, 187, 60, 115, 90, 36, 51, 167, 59, 86, 20, 175, 63, 118, 94, 230, 107, 202, 41, 253, 234, 165, 214, 221, 181, 45, 9, 202, 244, 148, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 160, 247, 170, 155, 102, 71, 245, 140, 90, 255, 89, 193, 131, 99, 31, 85, 161, 78, 90, 0, 204, 46, 253, 15, 71, 120, 19, 109, 123, 255, 0, 188, 27, 128} -var block1_stateNodeCID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(block1_stateNodeRLP)) +var chainB_block1_stateNodeRLP = []byte{248, 113, 160, 147, 141, 92, 6, 119, 63, 191, 125, 121, 193, 230, 153, 223, 49, 102, 109, 236, 50, 44, 161, 215, 28, 224, 171, 111, 118, 230, 79, 99, 18, 99, 4, 160, 117, 126, 95, 187, 60, 115, 90, 36, 51, 167, 59, 86, 20, 175, 63, 118, 94, 230, 107, 202, 41, 253, 234, 165, 214, 221, 181, 45, 9, 202, 244, 148, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 160, 247, 170, 155, 102, 71, 245, 140, 90, 255, 89, 193, 131, 99, 31, 85, 161, 78, 90, 0, 204, 46, 253, 15, 71, 120, 19, 109, 123, 255, 0, 188, 27, 128} +var chainB_block1_stateNodeCID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(chainB_block1_stateNodeRLP)) var block_stateNodeLeafKey = "0x39fc293fc702e42b9c023f094826545db42fc0fdf2ba031bb522d5ef917a6edb" -var Block1_StateNodeIPLD = models.IPLDModel{ - BlockNumber: Block1_Header.Number.String(), - Key: block1_stateNodeCID.String(), - Data: block1_stateNodeRLP, +var ChainB_block1_StateNodeIPLD = models.IPLDModel{ + BlockNumber: ChainB_block1_Header.Number.String(), + Key: chainB_block1_stateNodeCID.String(), + Data: chainB_block1_stateNodeRLP, } -var Block1_EmptyRootNodeRLP, _ = rlp.EncodeToBytes([]byte{}) +var ChainB_block1_EmptyRootNodeRLP, _ = rlp.EncodeToBytes([]byte{}) -var Block1_StateNode0 = models.StateNodeModel{ - BlockNumber: Block1_Header.Number.String(), - HeaderID: Block1_Header.Hash().Hex(), - CID: block1_stateNodeCID.String(), +var ChainB_block1_StateNode0 = models.StateNodeModel{ + BlockNumber: ChainB_block1_Header.Number.String(), + HeaderID: ChainB_block1_Header.Hash().Hex(), + CID: chainB_block1_stateNodeCID.String(), Diff: false, Balance: "1000", Nonce: 1, CodeHash: crypto.Keccak256Hash([]byte{}).Hex(), - StorageRoot: crypto.Keccak256Hash(Block1_EmptyRootNodeRLP).Hex(), + StorageRoot: crypto.Keccak256Hash(ChainB_block1_EmptyRootNodeRLP).Hex(), Removed: false, StateKey: block_stateNodeLeafKey, } -var block1_storageNodeRLP = []byte{3, 111, 15, 5, 141, 92, 6, 120, 63, 191, 125, 121, 193, 230, 153, 7, 49, 102, 109, 236, 50, 44, 161, 215, 28, 224, 171, 111, 118, 230, 79, 99, 18, 99, 4, 160, 117, 126, 95, 187, 60, 115, 90, 36, 51, 167, 59, 86, 20, 175, 63, 118, 94, 2, 107, 202, 41, 253, 234, 165, 214, 221, 181, 45, 9, 202, 244, 148, 128, 128, 32, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 160, 247, 170, 155, 102, 245, 71, 140, 90, 255, 89, 131, 99, 99, 31, 85, 161, 78, 90, 0, 204, 46, 253, 15, 71, 120, 19, 109, 123, 255, 0, 188, 27, 128} -var block1_storageNodeCID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(block1_storageNodeRLP)) +var chainB_block1_storageNodeRLP = []byte{3, 111, 15, 5, 141, 92, 6, 120, 63, 191, 125, 121, 193, 230, 153, 7, 49, 102, 109, 236, 50, 44, 161, 215, 28, 224, 171, 111, 118, 230, 79, 99, 18, 99, 4, 160, 117, 126, 95, 187, 60, 115, 90, 36, 51, 167, 59, 86, 20, 175, 63, 118, 94, 2, 107, 202, 41, 253, 234, 165, 214, 221, 181, 45, 9, 202, 244, 148, 128, 128, 32, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 160, 247, 170, 155, 102, 245, 71, 140, 90, 255, 89, 131, 99, 99, 31, 85, 161, 78, 90, 0, 204, 46, 253, 15, 71, 120, 19, 109, 123, 255, 0, 188, 27, 128} +var chainB_block1_storageNodeCID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_block1_storageNodeRLP)) -var Block1_StorageNodeIPLD = models.IPLDModel{ - BlockNumber: Block1_Header.Number.String(), - Key: block1_storageNodeCID.String(), - Data: block1_storageNodeRLP, +var ChainB_block1_StorageNodeIPLD = models.IPLDModel{ + BlockNumber: ChainB_block1_Header.Number.String(), + Key: chainB_block1_storageNodeCID.String(), + Data: chainB_block1_storageNodeRLP, } -var Block1_StorageNode0 = models.StorageNodeModel{ - BlockNumber: Block1_Header.Number.String(), - HeaderID: Block1_Header.Hash().Hex(), +var ChainB_block1_StorageNode0 = models.StorageNodeModel{ + BlockNumber: ChainB_block1_Header.Number.String(), + HeaderID: ChainB_block1_Header.Hash().Hex(), StateKey: block_stateNodeLeafKey, StorageKey: "0x33153abc667e873b6036c8a46bdd847e2ade3f89b9331c78ef2553fea194c50d", Removed: false, - CID: block1_storageNodeCID.String(), + CID: chainB_block1_storageNodeCID.String(), Diff: false, Value: []byte{1}, } // Header for last block at height 32 -var Chain2_Block32_Header = types.Header{ +var ChainB_Block32_Header = types.Header{ ParentHash: common.HexToHash("0x6983c921c053d1f637449191379f61ba844013c71e5ebfacaff77f8a8bd97042"), UncleHash: common.HexToHash("0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"), Coinbase: common.HexToAddress("0x0000000000000000000000000000000000000000"), @@ -98,63 +100,64 @@ var Chain2_Block32_Header = types.Header{ // State nodes for all paths at height 32 // Total 7 -var Chain2_Block32_stateNode0RLP = []byte{248, 145, 128, 128, 128, 160, 151, 6, 152, 177, 246, 151, 39, 79, 71, 219, 192, 153, 253, 0, 46, 66, 56, 238, 116, 176, 237, 244, 79, 132, 49, 29, 30, 82, 108, 53, 191, 204, 128, 128, 160, 46, 224, 200, 157, 30, 24, 225, 92, 222, 131, 123, 169, 124, 86, 228, 124, 79, 136, 236, 83, 185, 22, 67, 136, 5, 73, 46, 110, 136, 138, 101, 63, 128, 128, 160, 104, 220, 31, 84, 240, 26, 100, 148, 110, 49, 52, 120, 81, 119, 30, 251, 196, 107, 11, 134, 124, 238, 93, 61, 109, 109, 181, 208, 10, 189, 17, 92, 128, 128, 160, 171, 149, 11, 254, 75, 39, 224, 164, 133, 151, 153, 47, 109, 134, 15, 169, 139, 206, 132, 93, 220, 210, 0, 225, 235, 118, 121, 247, 173, 12, 135, 133, 128, 128, 128, 128} -var Chain2_Block32_stateNode0CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(Chain2_Block32_stateNode0RLP)) -var Chain2_Block32_stateNode1RLP = []byte{248, 81, 128, 128, 128, 160, 209, 34, 171, 171, 30, 147, 168, 199, 137, 152, 249, 118, 14, 166, 1, 169, 116, 224, 82, 196, 237, 83, 255, 188, 228, 197, 7, 178, 144, 137, 77, 55, 128, 128, 128, 128, 128, 160, 135, 96, 108, 173, 177, 63, 201, 196, 26, 204, 72, 118, 17, 30, 76, 117, 155, 63, 68, 187, 4, 249, 78, 69, 161, 82, 178, 234, 164, 48, 158, 173, 128, 128, 128, 128, 128, 128, 128} -var Chain2_Block32_stateNode1CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(Chain2_Block32_stateNode1RLP)) -var Chain2_Block32_stateNode2RLP = []byte{248, 105, 160, 32, 21, 58, 188, 102, 126, 135, 59, 96, 54, 200, 164, 107, 221, 132, 126, 42, 222, 63, 137, 185, 51, 28, 120, 239, 37, 83, 254, 161, 148, 197, 13, 184, 70, 248, 68, 1, 128, 160, 168, 127, 48, 6, 204, 116, 51, 247, 216, 182, 191, 182, 185, 124, 223, 202, 239, 15, 67, 91, 253, 165, 42, 2, 54, 10, 211, 250, 242, 149, 205, 139, 160, 224, 22, 140, 8, 116, 27, 79, 113, 64, 185, 215, 180, 38, 38, 236, 164, 5, 87, 211, 15, 88, 153, 138, 185, 94, 186, 125, 137, 164, 198, 141, 192} -var Chain2_Block32_stateNode2CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(Chain2_Block32_stateNode2RLP)) -var Chain2_Block32_stateNode3RLP = []byte{248, 105, 160, 32, 252, 41, 63, 199, 2, 228, 43, 156, 2, 63, 9, 72, 38, 84, 93, 180, 47, 192, 253, 242, 186, 3, 27, 181, 34, 213, 239, 145, 122, 110, 219, 184, 70, 248, 68, 1, 128, 160, 25, 80, 158, 144, 166, 222, 32, 247, 189, 42, 34, 60, 40, 240, 56, 105, 251, 184, 132, 209, 219, 59, 60, 16, 221, 204, 228, 74, 76, 113, 37, 226, 160, 224, 22, 140, 8, 116, 27, 79, 113, 64, 185, 215, 180, 38, 38, 236, 164, 5, 87, 211, 15, 88, 153, 138, 185, 94, 186, 125, 137, 164, 198, 141, 192} -var Chain2_Block32_stateNode3CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(Chain2_Block32_stateNode3RLP)) -var Chain2_Block32_stateNode4RLP = []byte{248, 118, 160, 55, 171, 60, 13, 215, 117, 244, 72, 175, 127, 180, 18, 67, 65, 94, 214, 251, 151, 93, 21, 48, 162, 216, 40, 246, 155, 234, 115, 70, 35, 26, 215, 184, 83, 248, 81, 10, 141, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112} -var Chain2_Block32_stateNode4CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(Chain2_Block32_stateNode4RLP)) -var Chain2_Block32_stateNode5RLP = []byte{248, 105, 160, 51, 151, 227, 61, 237, 218, 71, 99, 174, 161, 67, 252, 97, 81, 235, 205, 154, 147, 246, 45, 183, 166, 165, 86, 212, 108, 88, 93, 130, 173, 42, 252, 184, 70, 248, 68, 1, 128, 160, 54, 174, 96, 33, 243, 186, 113, 120, 188, 222, 254, 210, 63, 40, 4, 130, 154, 156, 66, 247, 130, 93, 88, 113, 144, 78, 47, 252, 174, 140, 130, 45, 160, 29, 80, 58, 104, 206, 141, 36, 93, 124, 217, 67, 93, 183, 43, 71, 98, 114, 126, 124, 105, 229, 48, 218, 194, 109, 83, 20, 76, 13, 102, 156, 130} -var Chain2_Block32_stateNode5CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(Chain2_Block32_stateNode5RLP)) -var Chain2_Block32_stateNode6RLP = []byte{248, 105, 160, 58, 188, 94, 219, 48, 85, 131, 227, 63, 102, 50, 44, 238, 228, 48, 136, 170, 153, 39, 125, 167, 114, 254, 181, 5, 53, 18, 208, 58, 10, 112, 43, 184, 70, 248, 68, 1, 128, 160, 54, 174, 96, 33, 243, 186, 113, 120, 188, 222, 254, 210, 63, 40, 4, 130, 154, 156, 66, 247, 130, 93, 88, 113, 144, 78, 47, 252, 174, 140, 130, 45, 160, 29, 80, 58, 104, 206, 141, 36, 93, 124, 217, 67, 93, 183, 43, 71, 98, 114, 126, 124, 105, 229, 48, 218, 194, 109, 83, 20, 76, 13, 102, 156, 130} -var Chain2_Block32_stateNode6CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(Chain2_Block32_stateNode6RLP)) +var ChainB_Block32_stateNode0RLP = []byte{248, 145, 128, 128, 128, 160, 151, 6, 152, 177, 246, 151, 39, 79, 71, 219, 192, 153, 253, 0, 46, 66, 56, 238, 116, 176, 237, 244, 79, 132, 49, 29, 30, 82, 108, 53, 191, 204, 128, 128, 160, 46, 224, 200, 157, 30, 24, 225, 92, 222, 131, 123, 169, 124, 86, 228, 124, 79, 136, 236, 83, 185, 22, 67, 136, 5, 73, 46, 110, 136, 138, 101, 63, 128, 128, 160, 104, 220, 31, 84, 240, 26, 100, 148, 110, 49, 52, 120, 81, 119, 30, 251, 196, 107, 11, 134, 124, 238, 93, 61, 109, 109, 181, 208, 10, 189, 17, 92, 128, 128, 160, 171, 149, 11, 254, 75, 39, 224, 164, 133, 151, 153, 47, 109, 134, 15, 169, 139, 206, 132, 93, 220, 210, 0, 225, 235, 118, 121, 247, 173, 12, 135, 133, 128, 128, 128, 128} +var ChainB_Block32_stateNode0CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(ChainB_Block32_stateNode0RLP)) +var ChainB_Block32_stateNode1RLP = []byte{248, 81, 128, 128, 128, 160, 209, 34, 171, 171, 30, 147, 168, 199, 137, 152, 249, 118, 14, 166, 1, 169, 116, 224, 82, 196, 237, 83, 255, 188, 228, 197, 7, 178, 144, 137, 77, 55, 128, 128, 128, 128, 128, 160, 135, 96, 108, 173, 177, 63, 201, 196, 26, 204, 72, 118, 17, 30, 76, 117, 155, 63, 68, 187, 4, 249, 78, 69, 161, 82, 178, 234, 164, 48, 158, 173, 128, 128, 128, 128, 128, 128, 128} +var ChainB_Block32_stateNode1CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(ChainB_Block32_stateNode1RLP)) +var ChainB_Block32_stateNode2RLP = []byte{248, 105, 160, 32, 21, 58, 188, 102, 126, 135, 59, 96, 54, 200, 164, 107, 221, 132, 126, 42, 222, 63, 137, 185, 51, 28, 120, 239, 37, 83, 254, 161, 148, 197, 13, 184, 70, 248, 68, 1, 128, 160, 168, 127, 48, 6, 204, 116, 51, 247, 216, 182, 191, 182, 185, 124, 223, 202, 239, 15, 67, 91, 253, 165, 42, 2, 54, 10, 211, 250, 242, 149, 205, 139, 160, 224, 22, 140, 8, 116, 27, 79, 113, 64, 185, 215, 180, 38, 38, 236, 164, 5, 87, 211, 15, 88, 153, 138, 185, 94, 186, 125, 137, 164, 198, 141, 192} +var ChainB_Block32_stateNode2CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(ChainB_Block32_stateNode2RLP)) +var ChainB_Block32_stateNode3RLP = []byte{248, 105, 160, 32, 252, 41, 63, 199, 2, 228, 43, 156, 2, 63, 9, 72, 38, 84, 93, 180, 47, 192, 253, 242, 186, 3, 27, 181, 34, 213, 239, 145, 122, 110, 219, 184, 70, 248, 68, 1, 128, 160, 25, 80, 158, 144, 166, 222, 32, 247, 189, 42, 34, 60, 40, 240, 56, 105, 251, 184, 132, 209, 219, 59, 60, 16, 221, 204, 228, 74, 76, 113, 37, 226, 160, 224, 22, 140, 8, 116, 27, 79, 113, 64, 185, 215, 180, 38, 38, 236, 164, 5, 87, 211, 15, 88, 153, 138, 185, 94, 186, 125, 137, 164, 198, 141, 192} +var ChainB_Block32_stateNode3CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(ChainB_Block32_stateNode3RLP)) +var ChainB_Block32_stateNode4RLP = []byte{248, 118, 160, 55, 171, 60, 13, 215, 117, 244, 72, 175, 127, 180, 18, 67, 65, 94, 214, 251, 151, 93, 21, 48, 162, 216, 40, 246, 155, 234, 115, 70, 35, 26, 215, 184, 83, 248, 81, 10, 141, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 86, 232, 31, 23, 27, 204, 85, 166, 255, 131, 69, 230, 146, 192, 248, 110, 91, 72, 224, 27, 153, 108, 173, 192, 1, 98, 47, 181, 227, 99, 180, 33, 160, 197, 210, 70, 1, 134, 247, 35, 60, 146, 126, 125, 178, 220, 199, 3, 192, 229, 0, 182, 83, 202, 130, 39, 59, 123, 250, 216, 4, 93, 133, 164, 112} +var ChainB_Block32_stateNode4CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(ChainB_Block32_stateNode4RLP)) +var ChainB_Block32_stateNode5RLP = []byte{248, 105, 160, 51, 151, 227, 61, 237, 218, 71, 99, 174, 161, 67, 252, 97, 81, 235, 205, 154, 147, 246, 45, 183, 166, 165, 86, 212, 108, 88, 93, 130, 173, 42, 252, 184, 70, 248, 68, 1, 128, 160, 54, 174, 96, 33, 243, 186, 113, 120, 188, 222, 254, 210, 63, 40, 4, 130, 154, 156, 66, 247, 130, 93, 88, 113, 144, 78, 47, 252, 174, 140, 130, 45, 160, 29, 80, 58, 104, 206, 141, 36, 93, 124, 217, 67, 93, 183, 43, 71, 98, 114, 126, 124, 105, 229, 48, 218, 194, 109, 83, 20, 76, 13, 102, 156, 130} +var ChainB_Block32_stateNode5CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(ChainB_Block32_stateNode5RLP)) +var ChainB_Block32_stateNode6RLP = []byte{248, 105, 160, 58, 188, 94, 219, 48, 85, 131, 227, 63, 102, 50, 44, 238, 228, 48, 136, 170, 153, 39, 125, 167, 114, 254, 181, 5, 53, 18, 208, 58, 10, 112, 43, 184, 70, 248, 68, 1, 128, 160, 54, 174, 96, 33, 243, 186, 113, 120, 188, 222, 254, 210, 63, 40, 4, 130, 154, 156, 66, 247, 130, 93, 88, 113, 144, 78, 47, 252, 174, 140, 130, 45, 160, 29, 80, 58, 104, 206, 141, 36, 93, 124, 217, 67, 93, 183, 43, 71, 98, 114, 126, 124, 105, 229, 48, 218, 194, 109, 83, 20, 76, 13, 102, 156, 130} +var ChainB_Block32_stateNode6CID = ipld.Keccak256ToCid(ipld.MEthStateTrie, crypto.Keccak256(ChainB_Block32_stateNode6RLP)) -var Chain2_Block32_StateIPLDs = []models.IPLDModel{ +var ChainB_Block32_StateIPLDs = []models.IPLDModel{ { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: Chain2_Block32_stateNode0CID.String(), - Data: Chain2_Block32_stateNode0RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: ChainB_Block32_stateNode0CID.String(), + Data: ChainB_Block32_stateNode0RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: Chain2_Block32_stateNode1CID.String(), - Data: Chain2_Block32_stateNode1RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: ChainB_Block32_stateNode1CID.String(), + Data: ChainB_Block32_stateNode1RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: Chain2_Block32_stateNode2CID.String(), - Data: Chain2_Block32_stateNode2RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: ChainB_Block32_stateNode2CID.String(), + Data: ChainB_Block32_stateNode2RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: Chain2_Block32_stateNode3CID.String(), - Data: Chain2_Block32_stateNode3RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: ChainB_Block32_stateNode3CID.String(), + Data: ChainB_Block32_stateNode3RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: Chain2_Block32_stateNode4CID.String(), - Data: Chain2_Block32_stateNode4RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: ChainB_Block32_stateNode4CID.String(), + Data: ChainB_Block32_stateNode4RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: Chain2_Block32_stateNode5CID.String(), - Data: Chain2_Block32_stateNode5RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: ChainB_Block32_stateNode5CID.String(), + Data: ChainB_Block32_stateNode5RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: Chain2_Block32_stateNode6CID.String(), - Data: Chain2_Block32_stateNode6RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: ChainB_Block32_stateNode6CID.String(), + Data: ChainB_Block32_stateNode6RLP, }, } -var Chain2_Block32_StateNodes = []models.StateNodeModel{ + +var ChainB_Block32_StateNodes = []models.StateNodeModel{ { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), - CID: Chain2_Block32_stateNode2CID.String(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), + CID: ChainB_Block32_stateNode2CID.String(), Diff: false, Balance: "0", Nonce: 1, @@ -164,45 +167,45 @@ var Chain2_Block32_StateNodes = []models.StateNodeModel{ StateKey: "0x33153abc667e873b6036c8a46bdd847e2ade3f89b9331c78ef2553fea194c50d", }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), - CID: Chain2_Block32_stateNode3CID.String(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), + CID: ChainB_Block32_stateNode3CID.String(), Diff: false, Balance: "1000", Nonce: 1, CodeHash: crypto.Keccak256Hash([]byte{}).Hex(), - StorageRoot: crypto.Keccak256Hash(Block1_EmptyRootNodeRLP).Hex(), + StorageRoot: crypto.Keccak256Hash(ChainB_block1_EmptyRootNodeRLP).Hex(), Removed: false, StateKey: "0x39fc293fc702e42b9c023f094826545db42fc0fdf2ba031bb522d5ef917a6edb", }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), - CID: Chain2_Block32_stateNode4CID.String(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), + CID: ChainB_Block32_stateNode4CID.String(), Diff: false, Balance: "1000", Nonce: 1, CodeHash: crypto.Keccak256Hash([]byte{}).Hex(), - StorageRoot: crypto.Keccak256Hash(Block1_EmptyRootNodeRLP).Hex(), + StorageRoot: crypto.Keccak256Hash(ChainB_block1_EmptyRootNodeRLP).Hex(), Removed: false, StateKey: "0x67ab3c0dd775f448af7fb41243415ed6fb975d1530a2d828f69bea7346231ad7", }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), - CID: Chain2_Block32_stateNode5CID.String(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), + CID: ChainB_Block32_stateNode5CID.String(), Diff: false, Balance: "1000", Nonce: 1, CodeHash: crypto.Keccak256Hash([]byte{}).Hex(), - StorageRoot: crypto.Keccak256Hash(Block1_EmptyRootNodeRLP).Hex(), + StorageRoot: crypto.Keccak256Hash(ChainB_block1_EmptyRootNodeRLP).Hex(), Removed: false, StateKey: "0x9397e33dedda4763aea143fc6151ebcd9a93f62db7a6a556d46c585d82ad2afc", }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), - CID: Chain2_Block32_stateNode6CID.String(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), + CID: ChainB_Block32_stateNode6CID.String(), Diff: false, Balance: "0", Nonce: 1, @@ -215,269 +218,270 @@ var Chain2_Block32_StateNodes = []models.StateNodeModel{ // Storage nodes for all paths at height 32 // Total 18 -var chain2_Block32_storageNode0RLP = []byte{248, 145, 128, 128, 128, 128, 160, 46, 77, 227, 140, 57, 224, 108, 238, 40, 82, 145, 79, 210, 174, 54, 248, 0, 145, 137, 64, 229, 230, 148, 145, 250, 132, 89, 198, 8, 249, 245, 133, 128, 160, 146, 250, 117, 217, 106, 75, 51, 124, 196, 244, 29, 16, 47, 173, 5, 90, 86, 19, 15, 48, 179, 174, 60, 171, 112, 154, 92, 70, 232, 164, 141, 165, 128, 160, 107, 250, 27, 137, 190, 180, 7, 172, 62, 97, 13, 157, 215, 114, 55, 219, 14, 244, 163, 155, 192, 255, 34, 143, 154, 149, 33, 227, 166, 135, 164, 93, 128, 128, 128, 160, 173, 131, 221, 2, 30, 147, 11, 230, 58, 166, 18, 25, 90, 56, 198, 126, 196, 130, 131, 1, 213, 112, 129, 155, 96, 143, 121, 231, 218, 97, 216, 200, 128, 128, 128, 128} -var chain2_Block32_storageNode0CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode0RLP)) -var chain2_Block32_storageNode1RLP = []byte{248, 81, 160, 167, 145, 134, 15, 219, 140, 96, 62, 101, 242, 176, 129, 164, 160, 200, 221, 13, 1, 246, 167, 156, 45, 205, 192, 88, 236, 235, 80, 105, 178, 123, 2, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 160, 18, 136, 22, 150, 26, 170, 67, 152, 182, 246, 95, 49, 193, 199, 219, 163, 97, 25, 243, 70, 126, 235, 163, 59, 44, 16, 37, 37, 247, 50, 229, 70, 128, 128} -var chain2_Block32_storageNode1CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode1RLP)) -var chain2_Block32_storageNode2RLP = []byte{236, 160, 32, 87, 135, 250, 18, 168, 35, 224, 242, 183, 99, 28, 196, 27, 59, 168, 130, 139, 51, 33, 202, 129, 17, 17, 250, 117, 205, 58, 163, 187, 90, 206, 138, 137, 54, 53, 201, 173, 197, 222, 160, 0, 0} -var chain2_Block32_storageNode2CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode2RLP)) -var chain2_Block32_storageNode3RLP = []byte{226, 160, 32, 44, 236, 111, 71, 132, 84, 126, 80, 66, 161, 99, 128, 134, 227, 24, 137, 41, 243, 79, 60, 0, 5, 248, 222, 195, 102, 201, 110, 129, 149, 172, 100} -var chain2_Block32_storageNode3CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode3RLP)) -var chain2_Block32_storageNode4RLP = []byte{236, 160, 58, 160, 42, 17, 221, 77, 37, 151, 49, 139, 113, 212, 147, 177, 69, 221, 246, 174, 8, 23, 169, 211, 148, 127, 69, 213, 41, 166, 167, 95, 43, 239, 138, 137, 54, 53, 201, 173, 197, 222, 159, 255, 156} -var chain2_Block32_storageNode4CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode4RLP)) -var chain2_Block32_storageNode5RLP = []byte{248, 67, 160, 58, 53, 172, 251, 193, 95, 248, 26, 57, 174, 125, 52, 79, 215, 9, 242, 142, 134, 0, 180, 170, 140, 101, 198, 182, 75, 254, 127, 227, 107, 209, 155, 161, 160, 71, 76, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6} -var chain2_Block32_storageNode5CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode5RLP)) -var chain2_Block32_storageNode6RLP = []byte{248, 67, 160, 58, 53, 172, 251, 193, 95, 248, 26, 57, 174, 125, 52, 79, 215, 9, 242, 142, 134, 0, 180, 170, 140, 101, 198, 182, 75, 254, 127, 227, 107, 209, 155, 161, 160, 71, 76, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6} -var chain2_Block32_storageNode6CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode6RLP)) -var chain2_Block32_storageNode7RLP = []byte{248, 67, 160, 50, 87, 90, 14, 158, 89, 60, 0, 249, 89, 248, 201, 47, 18, 219, 40, 105, 195, 57, 90, 59, 5, 2, 208, 94, 37, 22, 68, 111, 113, 248, 91, 161, 160, 71, 111, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8} -var chain2_Block32_storageNode7CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode7RLP)) -var chain2_Block32_storageNode8RLP = []byte{248, 67, 160, 50, 87, 90, 14, 158, 89, 60, 0, 249, 89, 248, 201, 47, 18, 219, 40, 105, 195, 57, 90, 59, 5, 2, 208, 94, 37, 22, 68, 111, 113, 248, 91, 161, 160, 71, 111, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8} -var chain2_Block32_storageNode8CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode8RLP)) -var chain2_Block32_storageNode9RLP = []byte{248, 145, 128, 128, 128, 128, 160, 145, 86, 15, 219, 52, 36, 164, 68, 160, 227, 156, 111, 1, 245, 112, 184, 187, 242, 26, 138, 8, 98, 129, 35, 57, 212, 165, 21, 204, 151, 229, 43, 128, 160, 250, 205, 84, 126, 141, 108, 126, 228, 162, 8, 238, 234, 141, 159, 232, 175, 70, 112, 207, 55, 165, 209, 107, 153, 54, 183, 60, 172, 194, 251, 66, 61, 128, 160, 107, 250, 27, 137, 190, 180, 7, 172, 62, 97, 13, 157, 215, 114, 55, 219, 14, 244, 163, 155, 192, 255, 34, 143, 154, 149, 33, 227, 166, 135, 164, 93, 128, 128, 128, 160, 173, 131, 221, 2, 30, 147, 11, 230, 58, 166, 18, 25, 90, 56, 198, 126, 196, 130, 131, 1, 213, 112, 129, 155, 96, 143, 121, 231, 218, 97, 216, 200, 128, 128, 128, 128} -var chain2_Block32_storageNode9CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode9RLP)) -var chain2_Block32_storageNode10RLP = []byte{236, 160, 48, 87, 135, 250, 18, 168, 35, 224, 242, 183, 99, 28, 196, 27, 59, 168, 130, 139, 51, 33, 202, 129, 17, 17, 250, 117, 205, 58, 163, 187, 90, 206, 138, 137, 54, 53, 201, 173, 197, 222, 160, 0, 0} -var chain2_Block32_storageNode10CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode10RLP)) -var chain2_Block32_storageNode11RLP = []byte{236, 160, 58, 160, 42, 17, 221, 77, 37, 151, 49, 139, 113, 212, 147, 177, 69, 221, 246, 174, 8, 23, 169, 211, 148, 127, 69, 213, 41, 166, 167, 95, 43, 239, 138, 137, 54, 53, 201, 173, 197, 222, 160, 0, 0} -var chain2_Block32_storageNode11CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode11RLP)) -var chain2_Block32_storageNode12RLP = []byte{248, 81, 128, 128, 160, 79, 197, 241, 58, 178, 249, 186, 12, 45, 168, 139, 1, 81, 171, 14, 124, 244, 216, 93, 8, 204, 164, 92, 205, 146, 60, 106, 183, 99, 35, 235, 40, 128, 128, 128, 128, 128, 128, 128, 128, 160, 82, 154, 228, 80, 107, 126, 132, 72, 3, 170, 88, 197, 100, 216, 50, 21, 226, 183, 86, 42, 208, 239, 184, 183, 152, 93, 188, 113, 224, 234, 218, 43, 128, 128, 128, 128, 128} -var chain2_Block32_storageNode12CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode12RLP)) -var chain2_Block32_storageNode13RLP = []byte{248, 81, 128, 128, 160, 79, 197, 241, 58, 178, 249, 186, 12, 45, 168, 139, 1, 81, 171, 14, 124, 244, 216, 93, 8, 204, 164, 92, 205, 146, 60, 106, 183, 99, 35, 235, 40, 128, 128, 128, 128, 128, 128, 128, 128, 160, 82, 154, 228, 80, 107, 126, 132, 72, 3, 170, 88, 197, 100, 216, 50, 21, 226, 183, 86, 42, 208, 239, 184, 183, 152, 93, 188, 113, 224, 234, 218, 43, 128, 128, 128, 128, 128} -var chain2_Block32_storageNode13CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode13RLP)) -var chain2_Block32_storageNode14RLP = []byte{226, 160, 57, 13, 236, 217, 84, 139, 98, 168, 214, 3, 69, 169, 136, 56, 111, 200, 75, 166, 188, 149, 72, 64, 8, 246, 54, 47, 147, 22, 14, 243, 229, 99, 1} -var chain2_Block32_storageNode14CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode14RLP)) -var chain2_Block32_storageNode15RLP = []byte{226, 160, 57, 13, 236, 217, 84, 139, 98, 168, 214, 3, 69, 169, 136, 56, 111, 200, 75, 166, 188, 149, 72, 64, 8, 246, 54, 47, 147, 22, 14, 243, 229, 99, 1} -var chain2_Block32_storageNode15CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode15RLP)) -var chain2_Block32_storageNode16RLP = []byte{226, 160, 49, 14, 45, 82, 118, 18, 7, 59, 38, 238, 205, 253, 113, 126, 106, 50, 12, 244, 75, 74, 250, 194, 176, 115, 45, 159, 203, 226, 183, 250, 12, 246, 4} -var chain2_Block32_storageNode16CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode16RLP)) -var chain2_Block32_storageNode17RLP = []byte{226, 160, 49, 14, 45, 82, 118, 18, 7, 59, 38, 238, 205, 253, 113, 126, 106, 50, 12, 244, 75, 74, 250, 194, 176, 115, 45, 159, 203, 226, 183, 250, 12, 246, 4} -var chain2_Block32_storageNode17CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chain2_Block32_storageNode17RLP)) +var chainB_Block32_storageNode0RLP = []byte{248, 145, 128, 128, 128, 128, 160, 46, 77, 227, 140, 57, 224, 108, 238, 40, 82, 145, 79, 210, 174, 54, 248, 0, 145, 137, 64, 229, 230, 148, 145, 250, 132, 89, 198, 8, 249, 245, 133, 128, 160, 146, 250, 117, 217, 106, 75, 51, 124, 196, 244, 29, 16, 47, 173, 5, 90, 86, 19, 15, 48, 179, 174, 60, 171, 112, 154, 92, 70, 232, 164, 141, 165, 128, 160, 107, 250, 27, 137, 190, 180, 7, 172, 62, 97, 13, 157, 215, 114, 55, 219, 14, 244, 163, 155, 192, 255, 34, 143, 154, 149, 33, 227, 166, 135, 164, 93, 128, 128, 128, 160, 173, 131, 221, 2, 30, 147, 11, 230, 58, 166, 18, 25, 90, 56, 198, 126, 196, 130, 131, 1, 213, 112, 129, 155, 96, 143, 121, 231, 218, 97, 216, 200, 128, 128, 128, 128} +var chainB_Block32_storageNode0CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode0RLP)) +var chainB_Block32_storageNode1RLP = []byte{248, 81, 160, 167, 145, 134, 15, 219, 140, 96, 62, 101, 242, 176, 129, 164, 160, 200, 221, 13, 1, 246, 167, 156, 45, 205, 192, 88, 236, 235, 80, 105, 178, 123, 2, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 160, 18, 136, 22, 150, 26, 170, 67, 152, 182, 246, 95, 49, 193, 199, 219, 163, 97, 25, 243, 70, 126, 235, 163, 59, 44, 16, 37, 37, 247, 50, 229, 70, 128, 128} +var chainB_Block32_storageNode1CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode1RLP)) +var chainB_Block32_storageNode2RLP = []byte{236, 160, 32, 87, 135, 250, 18, 168, 35, 224, 242, 183, 99, 28, 196, 27, 59, 168, 130, 139, 51, 33, 202, 129, 17, 17, 250, 117, 205, 58, 163, 187, 90, 206, 138, 137, 54, 53, 201, 173, 197, 222, 160, 0, 0} +var chainB_Block32_storageNode2CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode2RLP)) +var chainB_Block32_storageNode3RLP = []byte{226, 160, 32, 44, 236, 111, 71, 132, 84, 126, 80, 66, 161, 99, 128, 134, 227, 24, 137, 41, 243, 79, 60, 0, 5, 248, 222, 195, 102, 201, 110, 129, 149, 172, 100} +var chainB_Block32_storageNode3CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode3RLP)) +var chainB_Block32_storageNode4RLP = []byte{236, 160, 58, 160, 42, 17, 221, 77, 37, 151, 49, 139, 113, 212, 147, 177, 69, 221, 246, 174, 8, 23, 169, 211, 148, 127, 69, 213, 41, 166, 167, 95, 43, 239, 138, 137, 54, 53, 201, 173, 197, 222, 159, 255, 156} +var chainB_Block32_storageNode4CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode4RLP)) +var chainB_Block32_storageNode5RLP = []byte{248, 67, 160, 58, 53, 172, 251, 193, 95, 248, 26, 57, 174, 125, 52, 79, 215, 9, 242, 142, 134, 0, 180, 170, 140, 101, 198, 182, 75, 254, 127, 227, 107, 209, 155, 161, 160, 71, 76, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6} +var chainB_Block32_storageNode5CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode5RLP)) +var chainB_Block32_storageNode6RLP = []byte{248, 67, 160, 58, 53, 172, 251, 193, 95, 248, 26, 57, 174, 125, 52, 79, 215, 9, 242, 142, 134, 0, 180, 170, 140, 101, 198, 182, 75, 254, 127, 227, 107, 209, 155, 161, 160, 71, 76, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6} +var chainB_Block32_storageNode6CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode6RLP)) +var chainB_Block32_storageNode7RLP = []byte{248, 67, 160, 50, 87, 90, 14, 158, 89, 60, 0, 249, 89, 248, 201, 47, 18, 219, 40, 105, 195, 57, 90, 59, 5, 2, 208, 94, 37, 22, 68, 111, 113, 248, 91, 161, 160, 71, 111, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8} +var chainB_Block32_storageNode7CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode7RLP)) +var chainB_Block32_storageNode8RLP = []byte{248, 67, 160, 50, 87, 90, 14, 158, 89, 60, 0, 249, 89, 248, 201, 47, 18, 219, 40, 105, 195, 57, 90, 59, 5, 2, 208, 94, 37, 22, 68, 111, 113, 248, 91, 161, 160, 71, 111, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8} +var chainB_Block32_storageNode8CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode8RLP)) +var chainB_Block32_storageNode9RLP = []byte{248, 145, 128, 128, 128, 128, 160, 145, 86, 15, 219, 52, 36, 164, 68, 160, 227, 156, 111, 1, 245, 112, 184, 187, 242, 26, 138, 8, 98, 129, 35, 57, 212, 165, 21, 204, 151, 229, 43, 128, 160, 250, 205, 84, 126, 141, 108, 126, 228, 162, 8, 238, 234, 141, 159, 232, 175, 70, 112, 207, 55, 165, 209, 107, 153, 54, 183, 60, 172, 194, 251, 66, 61, 128, 160, 107, 250, 27, 137, 190, 180, 7, 172, 62, 97, 13, 157, 215, 114, 55, 219, 14, 244, 163, 155, 192, 255, 34, 143, 154, 149, 33, 227, 166, 135, 164, 93, 128, 128, 128, 160, 173, 131, 221, 2, 30, 147, 11, 230, 58, 166, 18, 25, 90, 56, 198, 126, 196, 130, 131, 1, 213, 112, 129, 155, 96, 143, 121, 231, 218, 97, 216, 200, 128, 128, 128, 128} +var chainB_Block32_storageNode9CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode9RLP)) +var chainB_Block32_storageNode10RLP = []byte{236, 160, 48, 87, 135, 250, 18, 168, 35, 224, 242, 183, 99, 28, 196, 27, 59, 168, 130, 139, 51, 33, 202, 129, 17, 17, 250, 117, 205, 58, 163, 187, 90, 206, 138, 137, 54, 53, 201, 173, 197, 222, 160, 0, 0} +var chainB_Block32_storageNode10CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode10RLP)) +var chainB_Block32_storageNode11RLP = []byte{236, 160, 58, 160, 42, 17, 221, 77, 37, 151, 49, 139, 113, 212, 147, 177, 69, 221, 246, 174, 8, 23, 169, 211, 148, 127, 69, 213, 41, 166, 167, 95, 43, 239, 138, 137, 54, 53, 201, 173, 197, 222, 160, 0, 0} +var chainB_Block32_storageNode11CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode11RLP)) +var chainB_Block32_storageNode12RLP = []byte{248, 81, 128, 128, 160, 79, 197, 241, 58, 178, 249, 186, 12, 45, 168, 139, 1, 81, 171, 14, 124, 244, 216, 93, 8, 204, 164, 92, 205, 146, 60, 106, 183, 99, 35, 235, 40, 128, 128, 128, 128, 128, 128, 128, 128, 160, 82, 154, 228, 80, 107, 126, 132, 72, 3, 170, 88, 197, 100, 216, 50, 21, 226, 183, 86, 42, 208, 239, 184, 183, 152, 93, 188, 113, 224, 234, 218, 43, 128, 128, 128, 128, 128} +var chainB_Block32_storageNode12CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode12RLP)) +var chainB_Block32_storageNode13RLP = []byte{248, 81, 128, 128, 160, 79, 197, 241, 58, 178, 249, 186, 12, 45, 168, 139, 1, 81, 171, 14, 124, 244, 216, 93, 8, 204, 164, 92, 205, 146, 60, 106, 183, 99, 35, 235, 40, 128, 128, 128, 128, 128, 128, 128, 128, 160, 82, 154, 228, 80, 107, 126, 132, 72, 3, 170, 88, 197, 100, 216, 50, 21, 226, 183, 86, 42, 208, 239, 184, 183, 152, 93, 188, 113, 224, 234, 218, 43, 128, 128, 128, 128, 128} +var chainB_Block32_storageNode13CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode13RLP)) +var chainB_Block32_storageNode14RLP = []byte{226, 160, 57, 13, 236, 217, 84, 139, 98, 168, 214, 3, 69, 169, 136, 56, 111, 200, 75, 166, 188, 149, 72, 64, 8, 246, 54, 47, 147, 22, 14, 243, 229, 99, 1} +var chainB_Block32_storageNode14CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode14RLP)) +var chainB_Block32_storageNode15RLP = []byte{226, 160, 57, 13, 236, 217, 84, 139, 98, 168, 214, 3, 69, 169, 136, 56, 111, 200, 75, 166, 188, 149, 72, 64, 8, 246, 54, 47, 147, 22, 14, 243, 229, 99, 1} +var chainB_Block32_storageNode15CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode15RLP)) +var chainB_Block32_storageNode16RLP = []byte{226, 160, 49, 14, 45, 82, 118, 18, 7, 59, 38, 238, 205, 253, 113, 126, 106, 50, 12, 244, 75, 74, 250, 194, 176, 115, 45, 159, 203, 226, 183, 250, 12, 246, 4} +var chainB_Block32_storageNode16CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode16RLP)) +var chainB_Block32_storageNode17RLP = []byte{226, 160, 49, 14, 45, 82, 118, 18, 7, 59, 38, 238, 205, 253, 113, 126, 106, 50, 12, 244, 75, 74, 250, 194, 176, 115, 45, 159, 203, 226, 183, 250, 12, 246, 4} +var chainB_Block32_storageNode17CID = ipld.Keccak256ToCid(ipld.MEthStorageTrie, crypto.Keccak256(chainB_Block32_storageNode17RLP)) -var Chain2_Block32_StorageIPLDs = []models.IPLDModel{ +var ChainB_Block32_StorageIPLDs = []models.IPLDModel{ { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode0CID.String(), - Data: chain2_Block32_storageNode0RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode0CID.String(), + Data: chainB_Block32_storageNode0RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode1CID.String(), - Data: chain2_Block32_storageNode1RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode1CID.String(), + Data: chainB_Block32_storageNode1RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode2CID.String(), - Data: chain2_Block32_storageNode2RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode2CID.String(), + Data: chainB_Block32_storageNode2RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode3CID.String(), - Data: chain2_Block32_storageNode3RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode3CID.String(), + Data: chainB_Block32_storageNode3RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode4CID.String(), - Data: chain2_Block32_storageNode4RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode4CID.String(), + Data: chainB_Block32_storageNode4RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode5CID.String(), - Data: chain2_Block32_storageNode5RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode5CID.String(), + Data: chainB_Block32_storageNode5RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode6CID.String(), - Data: chain2_Block32_storageNode6RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode6CID.String(), + Data: chainB_Block32_storageNode6RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode7CID.String(), - Data: chain2_Block32_storageNode7RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode7CID.String(), + Data: chainB_Block32_storageNode7RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode8CID.String(), - Data: chain2_Block32_storageNode8RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode8CID.String(), + Data: chainB_Block32_storageNode8RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode9CID.String(), - Data: chain2_Block32_storageNode9RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode9CID.String(), + Data: chainB_Block32_storageNode9RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode10CID.String(), - Data: chain2_Block32_storageNode10RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode10CID.String(), + Data: chainB_Block32_storageNode10RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode11CID.String(), - Data: chain2_Block32_storageNode11RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode11CID.String(), + Data: chainB_Block32_storageNode11RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode12CID.String(), - Data: chain2_Block32_storageNode12RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode12CID.String(), + Data: chainB_Block32_storageNode12RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode13CID.String(), - Data: chain2_Block32_storageNode13RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode13CID.String(), + Data: chainB_Block32_storageNode13RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode14CID.String(), - Data: chain2_Block32_storageNode14RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode14CID.String(), + Data: chainB_Block32_storageNode14RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode15CID.String(), - Data: chain2_Block32_storageNode15RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode15CID.String(), + Data: chainB_Block32_storageNode15RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode16CID.String(), - Data: chain2_Block32_storageNode16RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode16CID.String(), + Data: chainB_Block32_storageNode16RLP, }, { - BlockNumber: Chain2_Block32_Header.Number.String(), - Key: chain2_Block32_storageNode17CID.String(), - Data: chain2_Block32_storageNode17RLP, + BlockNumber: ChainB_Block32_Header.Number.String(), + Key: chainB_Block32_storageNode17CID.String(), + Data: chainB_Block32_storageNode17RLP, }, } -var Chain2_Block32_StorageNodes = []models.StorageNodeModel{ + +var ChainB_Block32_StorageNodes = []models.StorageNodeModel{ { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace", - CID: chain2_Block32_storageNode2CID.String(), + CID: chainB_Block32_storageNode2CID.String(), Value: []byte{137, 54, 53, 201, 173, 197, 222, 160, 0, 0}, StateKey: "0x33153abc667e873b6036c8a46bdd847e2ade3f89b9331c78ef2553fea194c50d", }, // 0 { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0x4e2cec6f4784547e5042a1638086e3188929f34f3c0005f8dec366c96e8195ac", - CID: chain2_Block32_storageNode3CID.String(), + CID: chainB_Block32_storageNode3CID.String(), Value: []byte{100}, StateKey: "0x33153abc667e873b6036c8a46bdd847e2ade3f89b9331c78ef2553fea194c50d", }, // 1 { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0x6aa02a11dd4d2597318b71d493b145ddf6ae0817a9d3947f45d529a6a75f2bef", - CID: chain2_Block32_storageNode4CID.String(), + CID: chainB_Block32_storageNode4CID.String(), Value: []byte{137, 54, 53, 201, 173, 197, 222, 159, 255, 156}, StateKey: "0x33153abc667e873b6036c8a46bdd847e2ade3f89b9331c78ef2553fea194c50d", }, // 2 { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b", - CID: chain2_Block32_storageNode5CID.String(), + CID: chainB_Block32_storageNode5CID.String(), Value: []byte{}, StateKey: "0x39fc293fc702e42b9c023f094826545db42fc0fdf2ba031bb522d5ef917a6edb'", }, // 3 { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0x8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b", - CID: chain2_Block32_storageNode6CID.String(), + CID: chainB_Block32_storageNode6CID.String(), Value: []byte{160, 71, 76, 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6}, StateKey: "0x33153abc667e873b6036c8a46bdd847e2ade3f89b9331c78ef2553fea194c50d", }, // 4 { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b", - CID: chain2_Block32_storageNode7CID.String(), + CID: chainB_Block32_storageNode7CID.String(), Value: []byte{}, StateKey: "0x39fc293fc702e42b9c023f094826545db42fc0fdf2ba031bb522d5ef917a6edb'", }, // 5 { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0xc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b", - CID: chain2_Block32_storageNode8CID.String(), + CID: chainB_Block32_storageNode8CID.String(), Value: []byte{160, 71, 111, 108, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8}, StateKey: "0x33153abc667e873b6036c8a46bdd847e2ade3f89b9331c78ef2553fea194c50d", }, // 6 { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0x405787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace", - CID: chain2_Block32_storageNode10CID.String(), + CID: chainB_Block32_storageNode10CID.String(), Value: []byte{}, StateKey: "0x39fc293fc702e42b9c023f094826545db42fc0fdf2ba031bb522d5ef917a6edb'", }, // 7 { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0x6aa02a11dd4d2597318b71d493b145ddf6ae0817a9d3947f45d529a6a75f2bef", - CID: chain2_Block32_storageNode11CID.String(), + CID: chainB_Block32_storageNode11CID.String(), Value: []byte{}, StateKey: "0x39fc293fc702e42b9c023f094826545db42fc0fdf2ba031bb522d5ef917a6edb'", }, // 8 { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", - CID: chain2_Block32_storageNode14CID.String(), + CID: chainB_Block32_storageNode14CID.String(), Value: []byte{'\x01'}, StateKey: "0xcabc5edb305583e33f66322ceee43088aa99277da772feb5053512d03a0a702b", }, // 9 { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0x290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563", - CID: chain2_Block32_storageNode15CID.String(), + CID: chainB_Block32_storageNode15CID.String(), Value: []byte{}, StateKey: "0x9397e33dedda4763aea143fc6151ebcd9a93f62db7a6a556d46c585d82ad2afc", }, // 10 { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", - CID: chain2_Block32_storageNode16CID.String(), + CID: chainB_Block32_storageNode16CID.String(), Value: []byte{'\x04'}, StateKey: "0xcabc5edb305583e33f66322ceee43088aa99277da772feb5053512d03a0a702b", }, // 11 { - BlockNumber: Chain2_Block32_Header.Number.String(), - HeaderID: Chain2_Block32_Header.Hash().Hex(), + BlockNumber: ChainB_Block32_Header.Number.String(), + HeaderID: ChainB_Block32_Header.Hash().Hex(), Diff: false, Removed: false, StorageKey: "0xb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6", - CID: chain2_Block32_storageNode17CID.String(), + CID: chainB_Block32_storageNode17CID.String(), Value: []byte{}, StateKey: "0x9397e33dedda4763aea143fc6151ebcd9a93f62db7a6a556d46c585d82ad2afc", }, // 12 } -// Contracts used in chain2 +// Contracts used in chainB /* pragma solidity ^0.8.0; diff --git a/test/helper.go b/test/helper.go deleted file mode 100644 index 552c27c..0000000 --- a/test/helper.go +++ /dev/null @@ -1,59 +0,0 @@ -package test - -import ( - "bytes" - "os" - "reflect" - "testing" - - "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" - ethnode "github.com/ethereum/go-ethereum/statediff/indexer/node" -) - -var ( - DefaultNodeInfo = ethnode.Info{ - ID: "test_nodeid", - ClientName: "test_client", - GenesisBlock: "TEST_GENESIS", - NetworkID: "test_network", - ChainID: 0, - } - DefaultPgConfig = postgres.Config{ - Hostname: "localhost", - Port: 8077, - DatabaseName: "cerc_testing", - Username: "vdbm", - Password: "password", - - MaxIdle: 0, - MaxConnLifetime: 0, - MaxConns: 4, - } -) - -func NeedsDB(t *testing.T) { - t.Helper() - if os.Getenv("TEST_WITH_DB") == "" { - t.Skip("set TEST_WITH_DB to enable test") - } -} - -func NoError(t *testing.T, err error) { - t.Helper() - if err != nil { - t.Fatal(err) - } -} - -// ExpectEqual asserts the provided interfaces are deep equal -func ExpectEqual(t *testing.T, want, got interface{}) { - if !reflect.DeepEqual(want, got) { - t.Fatalf("Values not equal:\nExpected:\t%+v\nActual:\t\t%+v", want, got) - } -} - -func ExpectEqualBytes(t *testing.T, want, got []byte) { - if !bytes.Equal(want, got) { - t.Fatalf("Bytes not equal:\nExpected:\t%v\nActual:\t\t%v", want, got) - } -}