From 0575724195d0f192892ff02eaf158cf12041752c Mon Sep 17 00:00:00 2001 From: Artem Poltorzhitskiy Date: Mon, 16 Oct 2023 12:51:09 +0200 Subject: [PATCH] Refactoring: change ORM, testing and migrate to timescale (#995) * Change ORM to Bun * Add storage tests * Refactoring: rollback * Refactoring: saving block and migrations * Remove Save function from model interface * Refactoring: protocol migrations * Tests: protocol migration postgres functions * Fix: rollback * Fix: rollback protocol * Refactoring: saving accounts * Refactoring: Contract.tx_count -> Account.operations_count * Timescale * Feature: add stats model * Extend stats * Refactoring: remove unused functions * Refactoring: operations API * Account statistics * Feature: add ticket model * Feature: add ticket balances * Fix: create extension once * Fix: change varchar to text * Fix: register models * Fix: register m2m models * Fix: smart rollup count * Fix: save big map states * Feature: add ticket balance endpoint * Fix: content type for ticket balance * Fix: response in ticket balances * Fix: rollback test * Remove concurrent index creation * Fix: one ticket to all updates * Fix: ticket hash * Fix: tests * Fix: index creation * Fix and optimize babylon migration * Fix and optimize babylon migration * Remove bmd repo from babylon migration * Change test data for babylon migration test * Fix: tx_rollup_origination * Fix: recently called contracts endpoint * Fix: operations count for account * Fix: parsing node error * Fix: smart rollup accounts counting * Fix: failed originations * Fix: saving origination accounts * Fix: same API * Disable oxfordnet * Upgrade to go1.21 * Add fromatter tests for new primitives * Cache scripts * Create contract indexes * Add codeql * Add codeql * Remove codeql * Linter update and some API improvements * Fix: linter job * Refactoring: logger * Fix: recently called contracts * Fix: global constants per network API * Fix: add gin gonic timeout * Fix: post-creating index concurrently * Fix: increase timeout * Add log * Fix: gin timeout * Fix: add GetContractTickets endpoint * Optimization of GetLastAction query * Fix: global constants query * Fix: last action in same API * Optimize last query * Fix: sanbox tagging * Fix: errors scan * Fix: errors * Add filters to ticket updates endpoints * Add ticket_id to ticket updates response --- .github/workflows/release.yml | 2 +- .github/workflows/tests_master.yml | 4 +- .github/workflows/tests_pr.yml | 4 +- .golangci.yml | 6 +- Makefile | 6 +- build/api/Dockerfile | 4 +- build/indexer/Dockerfile | 2 +- cmd/api/handlers/account.go | 27 +- cmd/api/handlers/bigmap.go | 57 +- cmd/api/handlers/code.go | 11 +- cmd/api/handlers/contract.go | 34 +- cmd/api/handlers/entrypoints.go | 22 +- cmd/api/handlers/error.go | 4 +- cmd/api/handlers/events.go | 4 +- cmd/api/handlers/fork.go | 9 +- cmd/api/handlers/global_constants.go | 18 +- cmd/api/handlers/head.go | 8 +- cmd/api/handlers/helpers.go | 2 +- cmd/api/handlers/mempool.go | 52 +- cmd/api/handlers/migrations.go | 13 +- cmd/api/handlers/operations.go | 526 +- cmd/api/handlers/prepare.go | 375 + cmd/api/handlers/requests.go | 155 +- cmd/api/handlers/responses.go | 385 +- cmd/api/handlers/run_code.go | 44 +- cmd/api/handlers/script.go | 27 +- cmd/api/handlers/smart_rollup.go | 4 +- cmd/api/handlers/stats.go | 21 +- cmd/api/handlers/storage.go | 33 +- cmd/api/handlers/tickets.go | 158 +- cmd/api/handlers/views.go | 18 +- cmd/api/main.go | 48 +- cmd/indexer/indexer/indexer.go | 374 +- cmd/indexer/indexer/indices.go | 271 +- cmd/indexer/indexer/initializer.go | 26 +- cmd/indexer/indexer/periodic.go | 4 +- cmd/indexer/indexer/receiver.go | 4 +- cmd/indexer/main.go | 9 +- configs/development.yml | 15 +- configs/production.yml | 11 +- configs/sandbox.yml | 5 +- configs/testnets.yml | 11 +- docker-compose.flextesa.yml | 8 +- docker-compose.yml | 2 +- go.mod | 97 +- go.sum | 323 +- internal/bcd/ast/ast_test.go | 15 +- internal/bcd/base/node.go | 4 +- internal/bcd/encoding/base58_test.go | 9 + internal/bcd/formatter/formatter.go | 1 + internal/bcd/formatter/formatter_test.go | 3 + .../code_KT1BcT.json | 1 + .../code_KT1BcT.tz | 18 + .../code_KT1Lfm.json | 1 + .../code_KT1Lfm.tz | 175 + .../code_KT1U4G.json | 1 + .../code_KT1U4G.tz | 55 + internal/bcd/raw_script.go | 8 +- internal/bcd/tezerrors/error.go | 13 +- internal/bcd/tezerrors/error_test.go | 20 + internal/bcd/translator/converter.go | 6 +- internal/cache/cache.go | 52 +- internal/config/config.go | 30 +- internal/config/context.go | 10 +- internal/config/options.go | 12 +- internal/helpers/sentry.go | 6 +- internal/logger/logger.go | 134 +- internal/models/account/model.go | 32 +- internal/models/account/repository.go | 7 +- internal/models/bigmapaction/model.go | 31 +- internal/models/bigmapaction/repository.go | 4 +- internal/models/bigmapdiff/bigmapstate.go | 46 +- internal/models/bigmapdiff/model.go | 43 +- internal/models/bigmapdiff/repository.go | 27 +- internal/models/block/model.go | 26 +- internal/models/block/repository.go | 6 +- internal/models/consts.go | 10 + internal/models/contract/constant.go | 26 +- internal/models/contract/model.go | 45 +- internal/models/contract/repository.go | 47 +- internal/models/contract/script.go | 42 +- internal/models/contract/script_constants.go | 16 +- internal/models/domains/data.go | 11 - internal/models/domains/repository.go | 8 +- internal/models/interface.go | 58 +- internal/models/migration/model.go | 25 +- internal/models/migration/repository.go | 4 +- internal/models/mock/account/mock.go | 52 +- internal/models/mock/bigmapaction/mock.go | 13 +- internal/models/mock/bigmapdiff/mock.go | 320 +- internal/models/mock/block/mock.go | 25 +- internal/models/mock/contract/mock.go | 430 +- internal/models/mock/domains/mock.go | 64 +- internal/models/mock/general.go | 1190 ++- internal/models/mock/migration/mock.go | 13 +- internal/models/mock/model.go | 114 + internal/models/mock/operation/mock.go | 324 +- internal/models/mock/protocol/mock.go | 103 +- internal/models/mock/rollback.go | 865 +++ internal/models/mock/saver.go | 432 ++ internal/models/mock/smart_rollup/mock.go | 25 +- internal/models/mock/stats/mock.go | 79 + internal/models/mock/ticket/mock.go | 116 +- internal/models/model.go | 30 +- internal/models/operation/model.go | 92 +- internal/models/operation/repository.go | 28 +- internal/models/protocol/model.go | 39 +- internal/models/protocol/repository.go | 8 +- internal/models/rollback.go | 45 + internal/models/smart_rollup/model.go | 28 +- internal/models/smart_rollup/repository.go | 6 +- internal/models/stats/model.go | 32 + internal/models/stats/repository.go | 8 + internal/models/ticket/balance.go | 41 + internal/models/ticket/model.go | 52 - internal/models/ticket/repository.go | 23 +- internal/models/ticket/ticket.go | 49 + internal/models/ticket/ticket_test.go | 46 + internal/models/ticket/update.go | 43 + internal/models/types/null.go | 10 +- internal/noderpc/rpc.go | 14 +- internal/noderpc/rpc_test.go | 66 + internal/parsers/contract/alpha.go | 23 +- internal/parsers/contract/babylon.go | 23 +- internal/parsers/contract/hangzhou.go | 25 +- internal/parsers/contract/jakarta.go | 29 +- internal/parsers/contract/parser.go | 4 +- internal/parsers/migrations/alpha.go | 13 +- internal/parsers/migrations/babylon.go | 49 +- internal/parsers/migrations/carthage.go | 13 +- internal/parsers/migrations/implicit.go | 32 +- internal/parsers/migrations/jakarta.go | 12 +- internal/parsers/migrations/parser.go | 5 +- internal/parsers/migrations/vesting.go | 39 +- .../KT19nHqEWZxFFbbDL1b7Y86escgEN7qUShGo.json | 3 +- .../KT1Ap287P1NzsnToSJdA4aqSNjPomRaHBZSr.json | 3 +- .../KT1KemKUx79keZgFW756jQrqKcZJ21y4SPdS.json | 3 +- .../KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn.json | 3 +- .../KT1QcxwB4QyPKfmSwjH1VRxa6kquUjeDWeEy.json | 3 +- .../KT1S5iPRQ612wcNm6mXDqDhTNegGFcvTV7vM.json | 3 +- ...rMcT6wwPbUD62mF7ddenwXSyJKJAAiSRxq4JQ.json | 120 + internal/parsers/operations/event.go | 15 +- internal/parsers/operations/migration.go | 29 +- internal/parsers/operations/migration_test.go | 6 +- .../parsers/operations/operation_group.go | 18 +- .../operations/operation_group_test.go | 769 +- internal/parsers/operations/origination.go | 30 +- internal/parsers/operations/params.go | 12 +- .../operations/register_global_constant.go | 14 +- internal/parsers/operations/result.go | 19 +- internal/parsers/operations/result_test.go | 16 +- internal/parsers/operations/smart_rollup.go | 7 +- .../operations/sr_execute_outbox_message.go | 21 +- internal/parsers/operations/sr_originate.go | 16 +- internal/parsers/operations/tag.go | 8 +- ...YhGoyCRf9y2JqfWoLKPJ3zMiDmMhE_babylon.json | 1 + internal/parsers/operations/test_common.go | 45 +- internal/parsers/operations/ticket_updates.go | 54 +- internal/parsers/operations/transaction.go | 47 +- .../parsers/operations/transfer_ticket.go | 22 +- .../operations/tx_rollup_origination.go | 18 +- .../parsers/protocols/functions.go | 15 +- internal/parsers/protocols/migration.go | 202 + internal/parsers/protocols/protocol.go | 2 +- internal/parsers/stacktrace/stacktrace.go | 18 +- internal/parsers/storage/alpha.go | 6 +- internal/parsers/storage/alpha_test.go | 3 +- internal/parsers/storage/babylon.go | 40 +- internal/parsers/storage/babylon_test.go | 5 +- internal/parsers/storage/big_map.go | 6 +- internal/parsers/storage/lazy_babylon.go | 42 +- internal/parsers/storage/parser.go | 6 +- internal/parsers/store.go | 57 + internal/periodic/general_worker.go | 16 +- internal/periodic/worker.go | 20 +- internal/postgres/account/storage.go | 27 +- internal/postgres/bigmapaction/storage.go | 15 +- internal/postgres/bigmapdiff/context.go | 12 +- internal/postgres/bigmapdiff/storage.go | 153 +- internal/postgres/block/storage.go | 16 +- internal/postgres/contract/storage.go | 252 +- internal/postgres/core/bulk.go | 42 - internal/postgres/core/config.go | 21 + internal/postgres/core/delete.go | 13 - internal/postgres/core/get.go | 21 +- internal/postgres/core/histogram.go | 45 - internal/postgres/core/index.go | 170 +- internal/postgres/core/logger.go | 22 +- internal/postgres/core/options.go | 28 - internal/postgres/core/postgres.go | 138 +- internal/postgres/core/postgres_test.go | 46 - internal/postgres/core/scopes.go | 29 +- internal/postgres/core/table.go | 129 + internal/postgres/core/transaction.go | 291 + internal/postgres/core/update.go | 8 - internal/postgres/domains/storage.go | 61 +- internal/postgres/global_constant/storage.go | 94 +- internal/postgres/migration/storage.go | 11 +- internal/postgres/operation/storage.go | 355 +- internal/postgres/partition_manager.go | 67 - internal/postgres/protocol/storage.go | 25 +- internal/postgres/rollback.go | 253 + internal/postgres/smart_rollup/storage.go | 26 +- internal/postgres/stats/storage.go | 28 + internal/postgres/store.go | 377 - internal/postgres/store/operations.go | 29 + internal/postgres/store/save.go | 381 + internal/postgres/store/store.go | 166 + internal/postgres/tests/accounts_test.go | 27 + .../postgres/tests/big_map_actions_test.go | 25 + internal/postgres/tests/big_map_diffs_test.go | 140 + internal/postgres/tests/blocks_test.go | 36 + internal/postgres/tests/contracts_test.go | 106 + internal/postgres/tests/domains_test.go | 42 + internal/postgres/tests/fixtures/accounts.yml | 1071 +++ .../tests/fixtures/big_map_actions.yml | 832 ++ .../postgres/tests/fixtures/big_map_diffs.yml | 1420 ++++ .../tests/fixtures/big_map_states.yml | 1420 ++++ internal/postgres/tests/fixtures/blocks.yml | 235 + .../postgres/tests/fixtures/contracts.yml | 1210 +++ .../tests/fixtures/global_constants.yml | 15 + .../postgres/tests/fixtures/migrations.yml | 48 + .../postgres/tests/fixtures/operations.yml | 6720 +++++++++++++++++ .../postgres/tests/fixtures/protocols.yml | 22 + .../tests/fixtures/script_constants.yml | 6 + internal/postgres/tests/fixtures/scripts.yml | 267 + .../postgres/tests/fixtures/smart_rollup.yml | 90 + internal/postgres/tests/fixtures/stats.yml | 7 + .../tests/fixtures/ticket_balances.yml | 9 + .../tests/fixtures/ticket_updates.yml | 21 + internal/postgres/tests/fixtures/tickets.yml | 12 + .../postgres/tests/global_constants_test.go | 60 + internal/postgres/tests/migrations_test.go | 25 + internal/postgres/tests/operations_test.go | 211 + internal/postgres/tests/protocols_test.go | 45 + internal/postgres/tests/rollback_test.go | 377 + internal/postgres/tests/smart_rollup_test.go | 38 + internal/postgres/tests/stats_test.go | 21 + internal/postgres/tests/suite_test.go | 119 + internal/postgres/tests/ticket_test.go | 143 + internal/postgres/tests/transaction_test.go | 446 ++ internal/postgres/ticket/storage.go | 143 +- internal/rollback/big_map_states.go | 52 + internal/rollback/context.go | 110 + internal/rollback/operations.go | 69 + internal/rollback/rollback.go | 234 +- internal/rollback/rollback_test.go | 420 ++ internal/rollback/scripts.go | 46 + internal/rollback/tickets.go | 60 + internal/services/mempool/mempool.go | 8 +- internal/testsuite/functions.go | 10 + scripts/bcdctl/main.go | 8 +- scripts/bcdctl/rollback.go | 27 +- scripts/migration/main.go | 14 +- scripts/newman/tests.json | 4 - scripts/nginx/main.go | 12 +- scripts/nginx/nginx.go | 4 +- scripts/nginx/sitemap.go | 4 +- 258 files changed, 25349 insertions(+), 5659 deletions(-) create mode 100644 cmd/api/handlers/prepare.go create mode 100644 internal/bcd/formatter/formatter_tests/KT1BcTXqU4TW1tPuujvyWYvnUJ2VrpY3WnzY/code_KT1BcT.json create mode 100644 internal/bcd/formatter/formatter_tests/KT1BcTXqU4TW1tPuujvyWYvnUJ2VrpY3WnzY/code_KT1BcT.tz create mode 100644 internal/bcd/formatter/formatter_tests/KT1LfmcX6usZoHYNf9LPrBL1sYCGDDeuApJq/code_KT1Lfm.json create mode 100644 internal/bcd/formatter/formatter_tests/KT1LfmcX6usZoHYNf9LPrBL1sYCGDDeuApJq/code_KT1Lfm.tz create mode 100644 internal/bcd/formatter/formatter_tests/KT1U4Gb8FjnmyyiUxu4Uy5iFuBRzp4ezbYa7/code_KT1U4G.json create mode 100644 internal/bcd/formatter/formatter_tests/KT1U4Gb8FjnmyyiUxu4Uy5iFuBRzp4ezbYa7/code_KT1U4G.tz create mode 100644 internal/models/mock/model.go create mode 100644 internal/models/mock/rollback.go create mode 100644 internal/models/mock/saver.go create mode 100644 internal/models/mock/stats/mock.go create mode 100644 internal/models/rollback.go create mode 100644 internal/models/stats/model.go create mode 100644 internal/models/stats/repository.go create mode 100644 internal/models/ticket/balance.go delete mode 100644 internal/models/ticket/model.go create mode 100644 internal/models/ticket/ticket.go create mode 100644 internal/models/ticket/ticket_test.go create mode 100644 internal/models/ticket/update.go create mode 100644 internal/noderpc/rpc_test.go create mode 100644 internal/parsers/operations/data/rpc/opg/oozKKBjBK44uGCrMcT6wwPbUD62mF7ddenwXSyJKJAAiSRxq4JQ.json create mode 100644 internal/parsers/operations/test/contracts/KT1MYutYhGoyCRf9y2JqfWoLKPJ3zMiDmMhE_babylon.json rename cmd/indexer/indexer/protocol.go => internal/parsers/protocols/functions.go (71%) create mode 100644 internal/parsers/protocols/migration.go delete mode 100644 internal/postgres/core/bulk.go create mode 100644 internal/postgres/core/config.go delete mode 100644 internal/postgres/core/delete.go delete mode 100644 internal/postgres/core/histogram.go delete mode 100644 internal/postgres/core/postgres_test.go create mode 100644 internal/postgres/core/table.go create mode 100644 internal/postgres/core/transaction.go delete mode 100644 internal/postgres/partition_manager.go create mode 100644 internal/postgres/rollback.go create mode 100644 internal/postgres/stats/storage.go delete mode 100644 internal/postgres/store.go create mode 100644 internal/postgres/store/operations.go create mode 100644 internal/postgres/store/save.go create mode 100644 internal/postgres/store/store.go create mode 100644 internal/postgres/tests/accounts_test.go create mode 100644 internal/postgres/tests/big_map_actions_test.go create mode 100644 internal/postgres/tests/big_map_diffs_test.go create mode 100644 internal/postgres/tests/blocks_test.go create mode 100644 internal/postgres/tests/contracts_test.go create mode 100644 internal/postgres/tests/domains_test.go create mode 100644 internal/postgres/tests/fixtures/accounts.yml create mode 100644 internal/postgres/tests/fixtures/big_map_actions.yml create mode 100644 internal/postgres/tests/fixtures/big_map_diffs.yml create mode 100644 internal/postgres/tests/fixtures/big_map_states.yml create mode 100644 internal/postgres/tests/fixtures/blocks.yml create mode 100644 internal/postgres/tests/fixtures/contracts.yml create mode 100644 internal/postgres/tests/fixtures/global_constants.yml create mode 100644 internal/postgres/tests/fixtures/migrations.yml create mode 100644 internal/postgres/tests/fixtures/operations.yml create mode 100644 internal/postgres/tests/fixtures/protocols.yml create mode 100644 internal/postgres/tests/fixtures/script_constants.yml create mode 100644 internal/postgres/tests/fixtures/scripts.yml create mode 100644 internal/postgres/tests/fixtures/smart_rollup.yml create mode 100644 internal/postgres/tests/fixtures/stats.yml create mode 100644 internal/postgres/tests/fixtures/ticket_balances.yml create mode 100644 internal/postgres/tests/fixtures/ticket_updates.yml create mode 100644 internal/postgres/tests/fixtures/tickets.yml create mode 100644 internal/postgres/tests/global_constants_test.go create mode 100644 internal/postgres/tests/migrations_test.go create mode 100644 internal/postgres/tests/operations_test.go create mode 100644 internal/postgres/tests/protocols_test.go create mode 100644 internal/postgres/tests/rollback_test.go create mode 100644 internal/postgres/tests/smart_rollup_test.go create mode 100644 internal/postgres/tests/stats_test.go create mode 100644 internal/postgres/tests/suite_test.go create mode 100644 internal/postgres/tests/ticket_test.go create mode 100644 internal/postgres/tests/transaction_test.go create mode 100644 internal/rollback/big_map_states.go create mode 100644 internal/rollback/context.go create mode 100644 internal/rollback/operations.go create mode 100644 internal/rollback/rollback_test.go create mode 100644 internal/rollback/scripts.go create mode 100644 internal/rollback/tickets.go diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 85f8a306d..33787132f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,7 +46,7 @@ jobs: context: . file: build/sandbox/Dockerfile build-args: | - TAG=4.6.2 + TAG=4.6.3 push: true cache-from: type=gha cache-to: type=gha,mode=max diff --git a/.github/workflows/tests_master.yml b/.github/workflows/tests_master.yml index 7b220ef05..cce8a5430 100644 --- a/.github/workflows/tests_master.yml +++ b/.github/workflows/tests_master.yml @@ -11,12 +11,12 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: '1.20' + go-version: '1.21' - uses: actions/checkout@v3 - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: - version: v1.51.2 + version: v1.54.2 args: --timeout=3m test: name: Run tests diff --git a/.github/workflows/tests_pr.yml b/.github/workflows/tests_pr.yml index aa203426b..a80e40eb3 100644 --- a/.github/workflows/tests_pr.yml +++ b/.github/workflows/tests_pr.yml @@ -11,12 +11,12 @@ jobs: steps: - uses: actions/setup-go@v3 with: - go-version: '1.20' + go-version: '1.21' - uses: actions/checkout@v3 - name: golangci-lint uses: golangci/golangci-lint-action@v3 with: - version: v1.51.2 + version: v1.54.2 args: --timeout=3m test: name: Run tests diff --git a/.golangci.yml b/.golangci.yml index 9a0745881..b4cc9f7b1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -11,7 +11,11 @@ linters: - ineffassign - containedctx - tenv + - musttag + - mirror + - tagalign + - zerologlint run: - go: '1.19' + go: '1.21' timeout: 3m diff --git a/Makefile b/Makefile index 3bea78aa4..d9d3f9dea 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ BACKUP?=dump_latest.gz api: docker-compose up -d db - cd cmd/api && go run . + cd cmd/api && go run -tags=jsoniter . indexer: docker-compose up -d db @@ -79,10 +79,10 @@ ps: docker ps --format "table {{.Names}}\t{{.RunningFor}}\t{{.Status}}\t{{.Ports}}" sandbox-pull: - TAG=4.4.0 docker-compose -f docker-compose.flextesa.yml pull + TAG_FRONT=4.6.2 TAG_BACK=4.7.2 docker-compose -f docker-compose.flextesa.yml pull flextesa-sandbox: - COMPOSE_PROJECT_NAME=bcdbox TAG=4.6.2 docker-compose -f docker-compose.flextesa.yml up -d + COMPOSE_PROJECT_NAME=bcdbox TAG_FRONT=4.6.2 TAG_BACK=4.7.2 docker-compose -f docker-compose.flextesa.yml up -d sandbox-down: COMPOSE_PROJECT_NAME=bcdbox docker-compose -f docker-compose.flextesa.yml down diff --git a/build/api/Dockerfile b/build/api/Dockerfile index 996cadf97..c2da5f0e5 100644 --- a/build/api/Dockerfile +++ b/build/api/Dockerfile @@ -1,7 +1,7 @@ # --------------------------------------------------------------------- # The first stage container, for building the application # --------------------------------------------------------------------- -FROM golang:1.20-alpine as builder +FROM golang:1.21-alpine as builder ENV CGO_ENABLED=0 ENV GO111MODULE=on @@ -20,7 +20,7 @@ COPY cmd/api cmd/api COPY internal internal WORKDIR $GOPATH/src/github.com/baking-bad/bcdhub/cmd/api/ -RUN go build -a -installsuffix cgo -o /go/bin/api . +RUN go build -tags=jsoniter -a -installsuffix cgo -o /go/bin/api . WORKDIR $GOPATH/src/github.com/baking-bad/bcdhub COPY scripts scripts diff --git a/build/indexer/Dockerfile b/build/indexer/Dockerfile index e0570d8a5..6209d9b66 100644 --- a/build/indexer/Dockerfile +++ b/build/indexer/Dockerfile @@ -1,7 +1,7 @@ # --------------------------------------------------------------------- # The first stage container, for building the application # --------------------------------------------------------------------- -FROM golang:1.20-alpine as builder +FROM golang:1.21-alpine as builder ENV CGO_ENABLED=0 ENV GO111MODULE=on diff --git a/cmd/api/handlers/account.go b/cmd/api/handlers/account.go index 6f3378b82..ae42b96e0 100644 --- a/cmd/api/handlers/account.go +++ b/cmd/api/handlers/account.go @@ -5,8 +5,8 @@ import ( "github.com/baking-bad/bcdhub/internal/bcd" "github.com/baking-bad/bcdhub/internal/config" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/gin-gonic/gin" + "github.com/rs/zerolog/log" ) // GetInfo godoc @@ -33,32 +33,31 @@ func GetInfo() gin.HandlerFunc { return } - acc, err := ctx.Accounts.Get(req.Address) - if handleError(c, ctx.Storage, err, 0) { - return - } - stats, err := ctx.Operations.ContractStats(acc.Address) + acc, err := ctx.Accounts.Get(c.Request.Context(), req.Address) if handleError(c, ctx.Storage, err, 0) { return } + var balance int64 if !(bcd.IsRollupAddressLazy(acc.Address) || bcd.IsSmartRollupAddressLazy(acc.Address)) { - block, err := ctx.Blocks.Last() + block, err := ctx.Blocks.Last(c.Request.Context()) if handleError(c, ctx.Storage, err, 0) { return } balance, err = ctx.Cache.TezosBalance(c, acc.Address, block.Level) if err != nil { - logger.Err(err) + log.Err(err).Msg("receiving tezos balance") } } c.SecureJSON(http.StatusOK, AccountInfo{ - Address: acc.Address, - Alias: acc.Alias, - TxCount: stats.Count, - Balance: balance, - LastAction: stats.LastAction.UTC(), - AccountType: acc.Type.String(), + Address: acc.Address, + OperationsCount: acc.OperationsCount, + EventsCount: acc.EventsCount, + MigrationsCount: acc.MigrationsCount, + TicketUpdatesCount: acc.TicketUpdatesCount, + Balance: balance, + LastAction: acc.LastAction.UTC(), + AccountType: acc.Type.String(), }) } diff --git a/cmd/api/handlers/bigmap.go b/cmd/api/handlers/bigmap.go index ca742f2be..63a7815b3 100644 --- a/cmd/api/handlers/bigmap.go +++ b/cmd/api/handlers/bigmap.go @@ -1,6 +1,7 @@ package handlers import ( + "context" "fmt" "net/http" @@ -38,7 +39,7 @@ func GetBigMap() gin.HandlerFunc { return } - stats, err := ctx.BigMapDiffs.GetStats(req.Ptr) + stats, err := ctx.BigMapDiffs.GetStats(c.Request.Context(), req.Ptr) if handleError(c, ctx.Storage, err, 0) { return } @@ -52,7 +53,7 @@ func GetBigMap() gin.HandlerFunc { } if stats.Total == 0 { - actions, err := ctx.BigMapActions.Get(req.Ptr, 1, 0) + actions, err := ctx.BigMapActions.Get(c.Request.Context(), req.Ptr, 1, 0) if handleError(c, ctx.Storage, err, 0) { return } @@ -60,13 +61,13 @@ func GetBigMap() gin.HandlerFunc { res.Address = actions[0].Address } } else { - destination, err := ctx.Accounts.Get(res.Address) + destination, err := ctx.Accounts.Get(c.Request.Context(), res.Address) if handleError(c, ctx.Storage, err, 0) { return } - res.ContractAlias = destination.Alias operation, err := ctx.Operations.Last( + c.Request.Context(), map[string]interface{}{ "status": types.OperationStatusApplied, "destination_id": destination.ID, @@ -74,7 +75,7 @@ func GetBigMap() gin.HandlerFunc { if handleError(c, ctx.Storage, err, 0) { return } - proto, err := ctx.Cache.ProtocolByID(operation.ProtocolID) + proto, err := ctx.Cache.ProtocolByID(c.Request.Context(), operation.ProtocolID) if handleError(c, ctx.Storage, err, 0) { return } @@ -94,7 +95,7 @@ func GetBigMap() gin.HandlerFunc { return } - script, err := ctx.Contracts.ScriptPart(res.Address, proto.SymLink, consts.STORAGE) + script, err := ctx.Contracts.ScriptPart(c.Request.Context(), res.Address, proto.SymLink, consts.STORAGE) if handleError(c, ctx.Storage, err, 0) { return } @@ -146,7 +147,7 @@ func GetBigMapHistory() gin.HandlerFunc { return } - bm, err := ctx.BigMapActions.Get(req.Ptr, 0, 0) + bm, err := ctx.BigMapActions.Get(c.Request.Context(), req.Ptr, 0, 0) if handleError(c, ctx.Storage, err, 0) { return } @@ -189,7 +190,7 @@ func GetBigMapKeys() gin.HandlerFunc { return } - keys, err := ctx.BigMapDiffs.Keys(bigmapdiff.GetContext{ + keys, err := ctx.BigMapDiffs.Keys(c.Request.Context(), bigmapdiff.GetContext{ Ptr: &req.Ptr, Size: pageReq.Size, Offset: pageReq.Offset, @@ -201,12 +202,12 @@ func GetBigMapKeys() gin.HandlerFunc { return } - symLink, err := getCurrentSymLink(ctx.Blocks) + symLink, err := getCurrentSymLink(c.Request.Context(), ctx.Blocks) if handleError(c, ctx.Storage, err, 0) { return } - response, err := prepareBigMapKeys(ctx, keys, symLink) + response, err := prepareBigMapKeys(c.Request.Context(), ctx, keys, symLink) if handleError(c, ctx.Storage, err, 0) { return } @@ -246,7 +247,7 @@ func GetBigMapByKeyHash() gin.HandlerFunc { return } - bm, total, err := ctx.BigMapDiffs.GetByPtrAndKeyHash(req.Ptr, req.KeyHash, pageReq.Size, pageReq.Offset) + bm, total, err := ctx.BigMapDiffs.GetByPtrAndKeyHash(c.Request.Context(), req.Ptr, req.KeyHash, pageReq.Size, pageReq.Offset) if handleError(c, ctx.Storage, err, 0) { return } @@ -255,12 +256,12 @@ func GetBigMapByKeyHash() gin.HandlerFunc { c.SecureJSON(http.StatusNoContent, gin.H{}) return } - symLink, err := getCurrentSymLink(ctx.Blocks) + symLink, err := getCurrentSymLink(c.Request.Context(), ctx.Blocks) if handleError(c, ctx.Storage, err, 0) { return } - response, err := prepareBigMapItem(ctx, bm, req.KeyHash, symLink) + response, err := prepareBigMapItem(c.Request.Context(), ctx, bm, req.KeyHash, symLink) if handleError(c, ctx.Storage, err, 0) { return } @@ -294,17 +295,17 @@ func GetCurrentBigMapKeyHash() gin.HandlerFunc { return } - state, err := ctx.BigMapDiffs.Current(req.KeyHash, req.Ptr) + state, err := ctx.BigMapDiffs.Current(c.Request.Context(), req.KeyHash, req.Ptr) if handleError(c, ctx.Storage, err, 0) { return } - symLink, err := getCurrentSymLink(ctx.Blocks) + symLink, err := getCurrentSymLink(c.Request.Context(), ctx.Blocks) if handleError(c, ctx.Storage, err, 0) { return } - bigMapType, err := getBigMapType(ctx, state.Contract, state.Ptr, symLink) + bigMapType, err := getBigMapType(c.Request.Context(), ctx, state.Contract, state.Ptr, symLink) if handleError(c, ctx.Storage, err, 0) { return } @@ -348,7 +349,7 @@ func GetBigMapDiffCount() gin.HandlerFunc { return } - count, err := ctx.BigMapDiffs.Count(req.Ptr) + count, err := ctx.BigMapDiffs.Count(c.Request.Context(), req.Ptr) if err != nil { if ctx.Storage.IsRecordNotFound(err) { c.SecureJSON(http.StatusOK, CountResponse{}) @@ -357,16 +358,16 @@ func GetBigMapDiffCount() gin.HandlerFunc { handleError(c, ctx.Storage, err, 0) return } - c.SecureJSON(http.StatusOK, CountResponse{count}) + c.SecureJSON(http.StatusOK, CountResponse{int64(count)}) } } -func prepareBigMapKeys(ctx *config.Context, data []bigmapdiff.BigMapState, symLink string) ([]BigMapResponseItem, error) { +func prepareBigMapKeys(c context.Context, ctx *config.Context, data []bigmapdiff.BigMapState, symLink string) ([]BigMapResponseItem, error) { if len(data) == 0 { return []BigMapResponseItem{}, nil } - bigMapType, err := getBigMapType(ctx, data[0].Contract, data[0].Ptr, symLink) + bigMapType, err := getBigMapType(c, ctx, data[0].Contract, data[0].Ptr, symLink) if err != nil { return nil, err } @@ -393,12 +394,12 @@ func prepareBigMapKeys(ctx *config.Context, data []bigmapdiff.BigMapState, symLi return res, nil } -func prepareBigMapItem(ctx *config.Context, data []bigmapdiff.BigMapDiff, keyHash, symLink string) (res BigMapDiffByKeyResponse, err error) { +func prepareBigMapItem(c context.Context, ctx *config.Context, data []bigmapdiff.BigMapDiff, keyHash, symLink string) (res BigMapDiffByKeyResponse, err error) { if len(data) == 0 { return } - bigMapType, err := getBigMapType(ctx, data[0].Contract, data[0].Ptr, symLink) + bigMapType, err := getBigMapType(c, ctx, data[0].Contract, data[0].Ptr, symLink) if err != nil { return } @@ -424,13 +425,13 @@ func prepareBigMapItem(ctx *config.Context, data []bigmapdiff.BigMapDiff, keyHas return } -func getBigMapType(ctx *config.Context, contract string, ptr int64, symLink string) (*ast.BigMap, error) { - storageType, err := getStorageType(ctx.Contracts, contract, symLink) +func getBigMapType(c context.Context, ctx *config.Context, contract string, ptr int64, symLink string) (*ast.BigMap, error) { + storageType, err := getStorageType(c, ctx.Contracts, contract, symLink) if err != nil { return nil, err } - actions, err := ctx.BigMapActions.Get(ptr, 2, 0) + actions, err := ctx.BigMapActions.Get(c, ptr, 2, 0) if err != nil { return nil, err } @@ -443,18 +444,18 @@ func getBigMapType(ctx *config.Context, contract string, ptr int64, symLink stri operationID = actions[1].OperationID } } - operation, err := ctx.Operations.GetByID(operationID) + operation, err := ctx.Operations.GetByID(c, operationID) if err != nil { return nil, err } deffatedStorage = operation.DeffatedStorage } else { - contract, err := ctx.Accounts.Get(contract) + contract, err := ctx.Accounts.Get(c, contract) if err != nil { return nil, err } - operation, err := ctx.Operations.Last(map[string]interface{}{ + operation, err := ctx.Operations.Last(c, map[string]interface{}{ "destination_id": contract.ID, "status": types.OperationStatusApplied, }, 0) diff --git a/cmd/api/handlers/code.go b/cmd/api/handlers/code.go index ef251d1fe..cacd3111f 100644 --- a/cmd/api/handlers/code.go +++ b/cmd/api/handlers/code.go @@ -1,6 +1,7 @@ package handlers import ( + "context" "net/http" "github.com/baking-bad/bcdhub/internal/bcd" @@ -40,18 +41,18 @@ func GetContractCode() gin.HandlerFunc { } if req.Protocol == "" { - state, err := ctx.Blocks.Last() + state, err := ctx.Blocks.Last(c.Request.Context()) if handleError(c, ctx.Storage, err, 0) { return } - proto, err := ctx.Cache.ProtocolByID(state.ProtocolID) + proto, err := ctx.Cache.ProtocolByID(c.Request.Context(), state.ProtocolID) if handleError(c, ctx.Storage, err, 0) { return } req.Protocol = proto.Hash } - code, err := getContractCodeJSON(ctx, req.Address, req.Protocol) + code, err := getContractCodeJSON(c.Request.Context(), ctx, req.Address, req.Protocol) if handleError(c, ctx.Storage, err, 0) { return } @@ -65,12 +66,12 @@ func GetContractCode() gin.HandlerFunc { } } -func getContractCodeJSON(ctx *config.Context, address string, protocol string) (res gjson.Result, err error) { +func getContractCodeJSON(c context.Context, ctx *config.Context, address string, protocol string) (res gjson.Result, err error) { symLink, err := bcd.GetProtoSymLink(protocol) if err != nil { return res, err } - script, err := ctx.Contracts.Script(address, symLink) + script, err := ctx.Cache.Script(c, address, symLink) if err != nil { return res, err } diff --git a/cmd/api/handlers/contract.go b/cmd/api/handlers/contract.go index f598b7f52..8bc201499 100644 --- a/cmd/api/handlers/contract.go +++ b/cmd/api/handlers/contract.go @@ -1,6 +1,7 @@ package handlers import ( + "context" "net/http" "github.com/baking-bad/bcdhub/internal/config" @@ -37,7 +38,7 @@ func GetContract() gin.HandlerFunc { return } - contract, err := ctx.Contracts.Get(req.Address) + contract, err := ctx.Contracts.Get(c.Request.Context(), req.Address) if err != nil { if ctx.Storage.IsRecordNotFound(err) { c.SecureJSON(http.StatusNoContent, gin.H{}) @@ -47,10 +48,8 @@ func GetContract() gin.HandlerFunc { return } - ctxs := c.MustGet("contexts").(config.Contexts) - if args.HasStats() { - res, err := contractWithStatsPostprocessing(ctxs, ctx, contract) + res, err := contractWithStatsPostprocessing(c.Request.Context(), ctx, contract) if handleError(c, ctx.Storage, err, 0) { return } @@ -95,12 +94,12 @@ func GetSameContracts() gin.HandlerFunc { return } - contract, err := ctx.Contracts.Get(req.Address) + contract, err := ctx.Contracts.Get(c.Request.Context(), req.Address) if handleError(c, ctx.Storage, err, 0) { return } - count, err := ctx.Domains.SameCount(contract, ctx.Config.API.Networks...) + count, err := ctx.Domains.SameCount(c.Request.Context(), contract, ctx.Config.API.Networks...) if handleError(c, ctx.Storage, err, 0) { return } @@ -110,7 +109,7 @@ func GetSameContracts() gin.HandlerFunc { Contracts: make([]ContractWithStats, 0), } - same, err := ctx.Domains.Same(req.Network, contract, int(page.Size), int(page.Offset), ctx.Config.API.Networks...) + same, err := ctx.Domains.Same(c.Request.Context(), req.Network, contract, int(page.Size), int(page.Offset), ctx.Config.API.Networks...) if handleError(c, ctx.Storage, err, 0) { return } @@ -120,6 +119,7 @@ func GetSameContracts() gin.HandlerFunc { if handleError(c, ctx.Storage, err, 0) { return } + result.LastAction = same[i].Account.LastAction result.Network = same[i].Network response.Contracts = append(response.Contracts, ContractWithStats{ Contract: result, @@ -139,30 +139,18 @@ func contractPostprocessing(ctx *config.Context, contract contract.Contract) (Co return res, nil } -func contractWithStatsPostprocessing(ctxs config.Contexts, ctx *config.Context, contractModel contract.Contract) (ContractWithStats, error) { - c, err := contractPostprocessing(ctx, contractModel) +func contractWithStatsPostprocessing(c context.Context, ctx *config.Context, contractModel contract.Contract) (ContractWithStats, error) { + contract, err := contractPostprocessing(ctx, contractModel) if err != nil { return ContractWithStats{}, err } - res := ContractWithStats{c, 0, 0, false} - - eventsCount, err := ctx.Operations.EventsCount(contractModel.AccountID) - if err != nil { - return res, err - } - res.EventsCount = eventsCount + res := ContractWithStats{contract, 0} - stats, err := ctx.Domains.SameCount(contractModel, ctx.Config.API.Networks...) + stats, err := ctx.Domains.SameCount(c, contractModel, ctx.Config.API.Networks...) if err != nil { return res, err } res.SameCount += int64(stats) - hasTicketUpdates, err := ctx.TicketUpdates.Has(contractModel.AccountID) - if err != nil { - return res, err - } - res.HasTicketUpdates = hasTicketUpdates - return res, nil } diff --git a/cmd/api/handlers/entrypoints.go b/cmd/api/handlers/entrypoints.go index 136f2d83d..850487773 100644 --- a/cmd/api/handlers/entrypoints.go +++ b/cmd/api/handlers/entrypoints.go @@ -1,6 +1,7 @@ package handlers import ( + "context" "net/http" "github.com/baking-bad/bcdhub/internal/bcd" @@ -38,12 +39,12 @@ func GetEntrypoints() gin.HandlerFunc { return } - symLink, err := getCurrentSymLink(ctx.Blocks) + symLink, err := getCurrentSymLink(c.Request.Context(), ctx.Blocks) if handleError(c, ctx.Storage, err, 0) { return } - parameter, err := getParameterType(ctx.Contracts, req.Address, symLink) + parameter, err := getParameterType(c.Request.Context(), ctx.Contracts, req.Address, symLink) if handleError(c, ctx.Storage, err, 0) { return } @@ -99,12 +100,12 @@ func GetEntrypointData() gin.HandlerFunc { return } - symLink, err := getCurrentSymLink(ctx.Blocks) + symLink, err := getCurrentSymLink(c.Request.Context(), ctx.Blocks) if handleError(c, ctx.Storage, err, 0) { return } - result, err := buildParametersForExecution(ctx, req.Address, symLink, reqData.Name, reqData.Data) + result, err := buildParametersForExecution(c.Request.Context(), ctx, req.Address, symLink, reqData.Name, reqData.Data) if handleError(c, ctx.Storage, err, 0) { return } @@ -164,12 +165,12 @@ func GetEntrypointSchema() gin.HandlerFunc { } } - symLink, err := getCurrentSymLink(ctx.Blocks) + symLink, err := getCurrentSymLink(c.Request.Context(), ctx.Blocks) if handleError(c, ctx.Storage, err, 0) { return } - parameter, err := getParameterType(ctx.Contracts, req.Address, symLink) + parameter, err := getParameterType(c.Request.Context(), ctx.Contracts, req.Address, symLink) if handleError(c, ctx.Storage, err, 0) { return } @@ -198,12 +199,13 @@ func GetEntrypointSchema() gin.HandlerFunc { var usingOperation operation.Operation switch esReq.FillType { case "latest": - account, err := ctx.Accounts.Get(req.Address) + account, err := ctx.Accounts.Get(c.Request.Context(), req.Address) if handleError(c, ctx.Storage, err, 0) { return } op, err := ctx.Operations.Last( + c.Request.Context(), map[string]interface{}{ "destination_id": account.ID, "kind": modelTypes.OperationKindTransaction, @@ -220,7 +222,7 @@ func GetEntrypointSchema() gin.HandlerFunc { return } - opg, err := ctx.Operations.GetByHashAndCounter(hash, int64(*esReq.Counter)) + opg, err := ctx.Operations.GetByHashAndCounter(c.Request.Context(), hash, int64(*esReq.Counter)) if handleError(c, ctx.Storage, err, 0) { return } @@ -250,8 +252,8 @@ func GetEntrypointSchema() gin.HandlerFunc { } } -func buildParametersForExecution(ctx *config.Context, address, symLink, entrypoint string, data map[string]interface{}) (*types.Parameters, error) { - parameterType, err := getParameterType(ctx.Contracts, address, symLink) +func buildParametersForExecution(c context.Context, ctx *config.Context, address, symLink, entrypoint string, data map[string]interface{}) (*types.Parameters, error) { + parameterType, err := getParameterType(c, ctx.Contracts, address, symLink) if err != nil { return nil, err } diff --git a/cmd/api/handlers/error.go b/cmd/api/handlers/error.go index 3e4882624..89447c08c 100644 --- a/cmd/api/handlers/error.go +++ b/cmd/api/handlers/error.go @@ -5,12 +5,12 @@ import ( "net/http" "github.com/baking-bad/bcdhub/internal/bcd/ast" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models" "github.com/baking-bad/bcdhub/internal/noderpc" sentrygin "github.com/getsentry/sentry-go/gin" "github.com/gin-gonic/gin" jsoniter "github.com/json-iterator/go" + "github.com/rs/zerolog/log" ) var json = jsoniter.ConfigCompatibleWithStandardLibrary @@ -35,7 +35,7 @@ func handleError(c *gin.Context, repo models.GeneralRepository, err error, code } } - logger.Err(err) + log.Err(err).Msg("unexpected error") } c.AbortWithStatusJSON(code, getErrorMessage(err, repo)) diff --git a/cmd/api/handlers/events.go b/cmd/api/handlers/events.go index 9ecd60fc8..1fb726087 100644 --- a/cmd/api/handlers/events.go +++ b/cmd/api/handlers/events.go @@ -37,12 +37,12 @@ func ListEvents() gin.HandlerFunc { return } - account, err := ctx.Accounts.Get(req.Address) + account, err := ctx.Accounts.Get(c.Request.Context(), req.Address) if handleError(c, ctx.Storage, err, http.StatusNotFound) { return } - operations, err := ctx.Operations.ListEvents(account.ID, page.Size, page.Offset) + operations, err := ctx.Operations.ListEvents(c.Request.Context(), account.ID, page.Size, page.Offset) if handleError(c, ctx.Storage, err, http.StatusNotFound) { return } diff --git a/cmd/api/handlers/fork.go b/cmd/api/handlers/fork.go index acb7de925..bf83b7b24 100644 --- a/cmd/api/handlers/fork.go +++ b/cmd/api/handlers/fork.go @@ -1,6 +1,7 @@ package handlers import ( + "context" stdJSON "encoding/json" "io" "net/http" @@ -20,7 +21,7 @@ func ForkContract(ctxs config.Contexts) gin.HandlerFunc { return } - response, err := buildStorageDataFromForkRequest(ctxs, req) + response, err := buildStorageDataFromForkRequest(c.Request.Context(), ctxs, req) if err != nil { handleError(c, ctxs.Any().Storage, err, 0) return @@ -29,7 +30,7 @@ func ForkContract(ctxs config.Contexts) gin.HandlerFunc { } } -func buildStorageDataFromForkRequest(ctxs config.Contexts, req forkRequest) (*ForkResponse, error) { +func buildStorageDataFromForkRequest(c context.Context, ctxs config.Contexts, req forkRequest) (*ForkResponse, error) { var err error var scriptData []byte @@ -40,11 +41,11 @@ func buildStorageDataFromForkRequest(ctxs config.Contexts, req forkRequest) (*Fo if err != nil { return nil, err } - symLink, err := getCurrentSymLink(ctx.Blocks) + symLink, err := getCurrentSymLink(c, ctx.Blocks) if err != nil { return nil, err } - scriptData, err = getScriptBytes(ctx.Contracts, req.Address, symLink) + scriptData, err = getScriptBytes(c, ctx.Cache, req.Address, symLink) if err != nil { return nil, err } diff --git a/cmd/api/handlers/global_constants.go b/cmd/api/handlers/global_constants.go index f6385f7bc..fe5efa46b 100644 --- a/cmd/api/handlers/global_constants.go +++ b/cmd/api/handlers/global_constants.go @@ -32,7 +32,7 @@ func GetGlobalConstant() gin.HandlerFunc { return } - constant, err := ctx.GlobalConstants.Get(req.Address) + constant, err := ctx.GlobalConstants.Get(c.Request.Context(), req.Address) if handleError(c, ctx.Storage, err, 0) { return } @@ -61,7 +61,7 @@ func GetGlobalConstant() gin.HandlerFunc { // @Param sort query string false "Sort order" Enums(asc, desc) // @Accept json // @Produce json -// @Success 200 {array} contract.ListGlobalConstantItem +// @Success 200 {array} GlobalConstantItem // @Failure 400 {object} Error // @Failure 404 {object} Error // @Failure 500 {object} Error @@ -75,11 +75,17 @@ func ListGlobalConstants() gin.HandlerFunc { return } - constants, err := ctx.GlobalConstants.List(args.Size, args.Offset, args.OrderBy, args.Sort) + constants, err := ctx.GlobalConstants.List(c.Request.Context(), args.Size, args.Offset, args.OrderBy, args.Sort) if handleError(c, ctx.Storage, err, 0) { return } - c.SecureJSON(http.StatusOK, constants) + + response := make([]GlobalConstantItem, len(constants)) + for i := range constants { + response[i] = NewGlobalConstantItem(constants[i]) + } + + c.SecureJSON(http.StatusOK, response) } } @@ -113,7 +119,7 @@ func GetContractGlobalConstants() gin.HandlerFunc { return } - constants, err := ctx.GlobalConstants.ForContract(req.Address, args.Size, args.Offset) + constants, err := ctx.GlobalConstants.ForContract(c.Request.Context(), req.Address, args.Size, args.Offset) if handleError(c, ctx.Storage, err, 0) { return } @@ -156,7 +162,7 @@ func GetGlobalConstantContracts() gin.HandlerFunc { return } - contracts, err := ctx.GlobalConstants.ContractList(args.Address, args.Size, args.Offset) + contracts, err := ctx.GlobalConstants.ContractList(c.Request.Context(), args.Address, args.Size, args.Offset) if handleError(c, ctx.Storage, err, 0) { return } diff --git a/cmd/api/handlers/head.go b/cmd/api/handlers/head.go index 9c0d10c22..0ffa579cf 100644 --- a/cmd/api/handlers/head.go +++ b/cmd/api/handlers/head.go @@ -6,11 +6,11 @@ import ( "time" "github.com/baking-bad/bcdhub/internal/config" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models/block" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/gin-gonic/gin" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) // GetHead godoc @@ -29,7 +29,7 @@ func GetHead() gin.HandlerFunc { body := make([]Head, 0) for network, ctx := range ctxs { - block, err := ctx.Blocks.Last() + block, err := ctx.Blocks.Last(c.Request.Context()) if err != nil { if ctx.Storage.IsRecordNotFound(err) { continue @@ -40,7 +40,7 @@ func GetHead() gin.HandlerFunc { head, err := getHead(ctx, network, block) if err != nil { - logger.Warning().Str("network", network.String()).Err(err).Msg("head API") + log.Warn().Str("network", network.String()).Err(err).Msg("head api") continue } @@ -68,7 +68,7 @@ func GetHeadByNetwork() gin.HandlerFunc { return func(c *gin.Context) { ctx := c.MustGet("context").(*config.Context) - block, err := ctx.Blocks.Last() + block, err := ctx.Blocks.Last(c.Request.Context()) if handleError(c, ctx.Storage, err, 0) { return } diff --git a/cmd/api/handlers/helpers.go b/cmd/api/handlers/helpers.go index ce8fa1414..bdb3be2ba 100644 --- a/cmd/api/handlers/helpers.go +++ b/cmd/api/handlers/helpers.go @@ -26,7 +26,7 @@ func ContractsHelpers() gin.HandlerFunc { splitted := strings.Split(args.Tags, ",") tags := types.NewTags(splitted) - contract, err := ctx.Contracts.FindOne(tags) + contract, err := ctx.Contracts.FindOne(c.Request.Context(), tags) if handleError(c, ctx.Storage, err, http.StatusNotFound) { return } diff --git a/cmd/api/handlers/mempool.go b/cmd/api/handlers/mempool.go index 5f5927a69..b1e5dd4b6 100644 --- a/cmd/api/handlers/mempool.go +++ b/cmd/api/handlers/mempool.go @@ -1,6 +1,7 @@ package handlers import ( + "context" "net/http" "time" @@ -37,16 +38,16 @@ func GetMempool() gin.HandlerFunc { return } - res, err := ctx.Mempool.Get(req.Address) + res, err := ctx.Mempool.Get(c.Request.Context(), req.Address) if handleError(c, ctx.Storage, err, 0) { return } - c.SecureJSON(http.StatusOK, mempoolPostprocessing(ctx, res)) + c.SecureJSON(http.StatusOK, mempoolPostprocessing(c.Request.Context(), ctx, res)) } } -func mempoolPostprocessing(ctx *config.Context, res mempool.PendingOperations) []Operation { +func mempoolPostprocessing(c context.Context, ctx *config.Context, res mempool.PendingOperations) []Operation { ret := make([]Operation, 0) if len(res.Originations)+len(res.Transactions) == 0 { return ret @@ -60,7 +61,7 @@ func mempoolPostprocessing(ctx *config.Context, res mempool.PendingOperations) [ } for _, tx := range res.Transactions { - op := prepareMempoolTransaction(ctx, tx) + op := prepareMempoolTransaction(c, ctx, tx) if op != nil { ret = append(ret, *op) } @@ -69,7 +70,7 @@ func mempoolPostprocessing(ctx *config.Context, res mempool.PendingOperations) [ return ret } -func prepareMempoolTransaction(ctx *config.Context, tx mempool.PendingTransaction) *Operation { +func prepareMempoolTransaction(c context.Context, ctx *config.Context, tx mempool.PendingTransaction) *Operation { status := tx.Status if status == consts.Applied { status = consts.Pending @@ -84,23 +85,21 @@ func prepareMempoolTransaction(ctx *config.Context, tx mempool.PendingTransactio } op := Operation{ - Hash: tx.Hash, - Network: ctx.Network.String(), - Timestamp: time.Unix(tx.UpdatedAt, 0).UTC(), - SourceAlias: ctx.Cache.Alias(tx.Source), - DestinationAlias: ctx.Cache.Alias(tx.Destination), - Kind: tx.Kind, - Source: tx.Source, - Fee: tx.Fee, - Counter: tx.Counter, - GasLimit: tx.GasLimit, - StorageLimit: tx.StorageLimit, - Amount: amount, - Destination: tx.Destination, - Mempool: true, - Status: status, - RawMempool: tx.Raw, - Protocol: tx.Protocol, + Hash: tx.Hash, + Network: ctx.Network.String(), + Timestamp: time.Unix(tx.UpdatedAt, 0).UTC(), + Kind: tx.Kind, + Source: tx.Source, + Fee: tx.Fee, + Counter: tx.Counter, + GasLimit: tx.GasLimit, + StorageLimit: tx.StorageLimit, + Amount: amount, + Destination: tx.Destination, + Mempool: true, + Status: status, + RawMempool: tx.Raw, + Protocol: tx.Protocol, } errs, err := tezerrors.ParseArray(tx.Errors) @@ -111,7 +110,7 @@ func prepareMempoolTransaction(ctx *config.Context, tx mempool.PendingTransactio if bcd.IsContract(op.Destination) && op.Protocol != "" && op.Status == consts.Pending { if len(tx.Parameters) > 0 { - _ = buildMempoolOperationParameters(ctx, tx.Parameters, &op) + _ = buildMempoolOperationParameters(c, ctx, tx.Parameters, &op) } else { op.Entrypoint = consts.DefaultEntrypoint } @@ -133,7 +132,6 @@ func prepareMempoolOrigination(ctx *config.Context, origination mempool.PendingO Hash: origination.Hash, Network: ctx.Network.String(), Timestamp: time.Unix(origination.UpdatedAt, 0).UTC(), - SourceAlias: ctx.Cache.Alias(origination.Source), Kind: origination.Kind, Source: origination.Source, Fee: origination.Fee, @@ -154,12 +152,12 @@ func prepareMempoolOrigination(ctx *config.Context, origination mempool.PendingO return &op } -func buildMempoolOperationParameters(ctx *config.Context, data []byte, op *Operation) error { - proto, err := ctx.Protocols.Get(op.Protocol, -1) +func buildMempoolOperationParameters(c context.Context, ctx *config.Context, data []byte, op *Operation) error { + proto, err := ctx.Protocols.Get(c, op.Protocol, -1) if err != nil { return err } - parameter, err := getParameterType(ctx.Contracts, op.Destination, proto.SymLink) + parameter, err := getParameterType(c, ctx.Contracts, op.Destination, proto.SymLink) if err != nil { return err } diff --git a/cmd/api/handlers/migrations.go b/cmd/api/handlers/migrations.go index 68bfd8555..4814fc181 100644 --- a/cmd/api/handlers/migrations.go +++ b/cmd/api/handlers/migrations.go @@ -1,6 +1,7 @@ package handlers import ( + "context" "net/http" "github.com/baking-bad/bcdhub/internal/bcd/encoding" @@ -32,17 +33,17 @@ func GetContractMigrations() gin.HandlerFunc { return } - contract, err := ctx.Contracts.Get(req.Address) + contract, err := ctx.Contracts.Get(c.Request.Context(), req.Address) if handleError(c, ctx.Storage, err, 0) { return } - migrations, err := ctx.Migrations.Get(contract.ID) + migrations, err := ctx.Migrations.Get(c.Request.Context(), contract.ID) if handleError(c, ctx.Storage, err, 0) { return } - result, err := prepareMigrations(ctx, migrations) + result, err := prepareMigrations(c.Request.Context(), ctx, migrations) if handleError(c, ctx.Storage, err, 0) { return } @@ -51,14 +52,14 @@ func GetContractMigrations() gin.HandlerFunc { } } -func prepareMigrations(ctx *config.Context, data []migration.Migration) ([]Migration, error) { +func prepareMigrations(c context.Context, ctx *config.Context, data []migration.Migration) ([]Migration, error) { result := make([]Migration, len(data)) for i := range data { - proto, err := ctx.Cache.ProtocolByID(data[i].ProtocolID) + proto, err := ctx.Cache.ProtocolByID(c, data[i].ProtocolID) if err != nil && !ctx.Storage.IsRecordNotFound(err) { return nil, err } - prevProto, err := ctx.Cache.ProtocolByID(data[i].PrevProtocolID) + prevProto, err := ctx.Cache.ProtocolByID(c, data[i].PrevProtocolID) if err != nil && !ctx.Storage.IsRecordNotFound(err) { return nil, err } diff --git a/cmd/api/handlers/operations.go b/cmd/api/handlers/operations.go index 11657d137..ece60333c 100644 --- a/cmd/api/handlers/operations.go +++ b/cmd/api/handlers/operations.go @@ -1,103 +1,33 @@ package handlers import ( - "encoding/hex" + "context" "net/http" - "strings" - "github.com/baking-bad/bcdhub/internal/bcd" - "github.com/baking-bad/bcdhub/internal/bcd/ast" - "github.com/baking-bad/bcdhub/internal/bcd/consts" "github.com/baking-bad/bcdhub/internal/bcd/encoding" - "github.com/baking-bad/bcdhub/internal/bcd/formatter" - formattererror "github.com/baking-bad/bcdhub/internal/bcd/formatter/error" "github.com/baking-bad/bcdhub/internal/bcd/tezerrors" - "github.com/baking-bad/bcdhub/internal/bcd/types" "github.com/baking-bad/bcdhub/internal/config" - "github.com/baking-bad/bcdhub/internal/helpers" - "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" "github.com/baking-bad/bcdhub/internal/models/operation" - modelTypes "github.com/baking-bad/bcdhub/internal/models/types" - "github.com/baking-bad/bcdhub/internal/parsers/storage" - "github.com/baking-bad/bcdhub/internal/postgres/core" "github.com/gin-gonic/gin" "github.com/pkg/errors" - "github.com/tidwall/gjson" ) -// GetContractOperations godoc -// @Summary Get contract operations -// @Description Get contract operations -// @Tags contract -// @ID get-contract-operations -// @Param network path string true "Network" -// @Param address path string true "KT address" minlength(36) maxlength(36) -// @Param last_id query string false "Last operation ID" -// @Param from query integer false "Timestamp" -// @Param to query integer false "Timestamp" -// @Param size query integer false "Expected OPG count" mininum(1) -// @Param status query string false "Comma-separated operations statuses" -// @Param entrypoints query string false "Comma-separated called entrypoints list" -// @Param with_storage_diff query bool false "Include storage diff to operations or not" -// @Accept json -// @Produce json -// @Success 200 {object} OperationResponse -// @Failure 400 {object} Error -// @Failure 404 {object} Error -// @Failure 500 {object} Error -// @Router /v1/contract/{network}/{address}/operations [get] -func GetContractOperations() gin.HandlerFunc { - return func(c *gin.Context) { - ctx := c.MustGet("context").(*config.Context) - - var req getAccountRequest - if err := c.BindUri(&req); handleError(c, ctx.Storage, err, http.StatusNotFound) { - return - } - - var filtersReq operationsRequest - if err := c.BindQuery(&filtersReq); handleError(c, ctx.Storage, err, http.StatusBadRequest) { - return - } - - account, err := ctx.Accounts.Get(req.Address) - if handleError(c, ctx.Storage, err, http.StatusNotFound) { - return - } - - filters := prepareFilters(filtersReq) - ops, err := ctx.Operations.GetByAccount(account, filtersReq.Size, filters) - if handleError(c, ctx.Storage, err, 0) { - return - } - - resp, err := PrepareOperations(ctx, ops.Operations, filtersReq.WithStorageDiff) - if handleError(c, ctx.Storage, err, 0) { - return - } - c.SecureJSON(http.StatusOK, OperationResponse{ - Operations: resp, - LastID: ops.LastID, - }) - } -} - // GetOperation godoc // @Summary Get operation group // @Description Get operation group by hash // @Tags operations // @ID get-opg +// @Param network path string true "Network" // @Param hash path string true "Operation group hash" minlength(51) maxlength(51) // @Param with_mempool query bool false "Search operation in mempool or not" // @Param with_storage_diff query bool false "Include storage diff to operations or not" -// @Param network query string false "Network" // @Accept json // @Produce json // @Success 200 {array} Operation // @Success 204 {object} gin.H // @Failure 400 {object} Error // @Failure 500 {object} Error -// @Router /v1/opg/{hash} [get] +// @Router /v1/opg/{network}/{hash} [get] func GetOperation() gin.HandlerFunc { return func(c *gin.Context) { ctxs := c.MustGet("contexts").(config.Contexts) @@ -113,73 +43,60 @@ func GetOperation() gin.HandlerFunc { return } - operations := make([]operation.Operation, 0) - var foundContext *config.Context - hash, err := encoding.DecodeBase58(req.Hash) if handleError(c, any.Storage, err, http.StatusBadRequest) { return } - network := modelTypes.NewNetwork(queryReq.Network) + network := req.NetworkID() if ctx, ok := ctxs[network]; ok { - op, err := ctx.Operations.GetByHash(hash) + operations, err := ctx.Operations.GetByHash(c.Request.Context(), hash) if err != nil { - if !ctx.Storage.IsRecordNotFound(err) { - handleError(c, ctx.Storage, err, 0) - return - } - } else { - foundContext = ctx - operations = append(operations, op...) + handleError(c, ctx.Storage, err, 0) + return } - } else { - for _, ctx := range ctxs { - op, err := ctx.Operations.GetByHash(hash) - if err != nil { - if !ctx.Storage.IsRecordNotFound(err) { - handleError(c, ctx.Storage, err, 0) - return - } - continue - } - operations = append(operations, op...) - if len(operations) > 0 { - foundContext = ctx - break - } + + resp, err := PrepareOperations(c.Request.Context(), ctx, operations, queryReq.WithStorageDiff) + if handleError(c, ctx.Storage, err, 0) { + return } + + c.SecureJSON(http.StatusOK, resp) + return } - if foundContext == nil { - opg := make([]Operation, 0) + for _, ctx := range ctxs { + operations, err := ctx.Operations.GetByHash(c.Request.Context(), hash) + if err != nil { + handleError(c, ctx.Storage, err, 0) + return + } - if queryReq.WithMempool { - ctx := ctxs.Any() - operation, err := getOperationFromMempool(ctx, req.Hash) + if len(operations) > 0 { + resp, err := PrepareOperations(c.Request.Context(), ctx, operations, queryReq.WithStorageDiff) if handleError(c, ctx.Storage, err, 0) { return } - if operation != nil { - opg = append(opg, *operation) - } - } - if len(opg) == 0 { - c.SecureJSON(http.StatusNoContent, []gin.H{}) + c.SecureJSON(http.StatusOK, resp) return } + } - c.SecureJSON(http.StatusOK, opg) + if !queryReq.WithMempool { + c.SecureJSON(http.StatusNoContent, []gin.H{}) return } - resp, err := PrepareOperations(foundContext, operations, queryReq.WithStorageDiff) - if handleError(c, foundContext.Storage, err, 0) { + operation, err := getOperationFromMempool(c, ctxs.Any(), req.Hash) + if handleError(c, ctxs.Any().Storage, err, 0) { return } - - c.SecureJSON(http.StatusOK, resp) + if operation != nil { + c.SecureJSON(http.StatusOK, []Operation{*operation}) + } else { + c.SecureJSON(http.StatusNoContent, []gin.H{}) + } } } @@ -206,12 +123,12 @@ func GetImplicitOperation() gin.HandlerFunc { return } - op, err := ctx.Operations.GetImplicitOperation(req.Counter) + operations, err := ctx.Operations.GetByHashAndCounter(c.Request.Context(), nil, req.Counter) if handleError(c, ctx.Storage, err, 0) { return } - resp, err := PrepareOperations(ctx, []operation.Operation{op}, false) + resp, err := PrepareOperations(c.Request.Context(), ctx, operations, false) if handleError(c, ctx.Storage, err, 0) { return } @@ -242,7 +159,7 @@ func GetOperationErrorLocation() gin.HandlerFunc { return } - operation, err := ctx.Operations.GetByID(req.ID) + operation, err := ctx.Operations.GetByID(c.Request.Context(), req.ID) if handleError(c, ctx.Storage, err, 0) { return } @@ -252,7 +169,7 @@ func GetOperationErrorLocation() gin.HandlerFunc { return } - response, err := getErrorLocation(ctx, operation, 2) + response, err := getErrorLocation(c.Request.Context(), ctx, operation, 2) if handleError(c, ctx.Storage, err, 0) { return } @@ -281,7 +198,7 @@ func GetOperationDiff() gin.HandlerFunc { if err := c.BindUri(&req); handleError(c, ctx.Storage, err, http.StatusBadRequest) { return } - operation, err := ctx.Operations.GetByID(req.ID) + operation, err := ctx.Operations.GetByID(c.Request.Context(), req.ID) if handleError(c, ctx.Storage, err, 0) { return } @@ -289,31 +206,13 @@ func GetOperationDiff() gin.HandlerFunc { var result Operation result.FromModel(operation) - if len(operation.DeffatedStorage) > 0 && (operation.IsCall() || operation.IsOrigination() || operation.IsImplicit()) && operation.IsApplied() { - proto, err := ctx.Cache.ProtocolByID(operation.ProtocolID) + if operation.CanHasStorageDiff() { + proto, err := ctx.Cache.ProtocolByID(c.Request.Context(), operation.ProtocolID) if handleError(c, ctx.Storage, err, 0) { return } - result.Protocol = proto.Hash - storageBytes, err := ctx.Contracts.ScriptPart(operation.Destination.Address, proto.SymLink, consts.STORAGE) - if handleError(c, ctx.Storage, err, 0) { - return - } - - storageType, err := ast.NewTypedAstFromBytes(storageBytes) - if handleError(c, ctx.Storage, err, 0) { - return - } - - var bmd []bigmapdiff.BigMapDiff - if operation.BigMapDiffsCount > 0 { - bmd, err = ctx.BigMapDiffs.GetForOperation(operation.ID) - if handleError(c, ctx.Storage, err, 0) { - return - } - } - if err := setStorageDiff(ctx, operation.DestinationID, operation.DeffatedStorage, &result, bmd, storageType); handleError(c, ctx.Storage, err, 0) { + if err := setFullStorage(c.Request.Context(), ctx, proto.SymLink, operation, &result); handleError(c, ctx.Storage, err, 0) { return } } @@ -351,7 +250,7 @@ func GetOperationGroups() gin.HandlerFunc { return } - opg, err := ctx.Operations.OPG(req.Address, int64(args.Size), args.LastID) + opg, err := ctx.Operations.OPG(c.Request.Context(), req.Address, int64(args.Size), args.LastID) if handleError(c, ctx.Storage, err, 0) { return } @@ -369,16 +268,16 @@ func GetOperationGroups() gin.HandlerFunc { // @Description Get operations by hash and counter // @Tags operations // @ID get-operations-by-hash-and-counter +// @Param network path string true "You can set network field for better performance" // @Param hash path string true "Operation group hash" minlength(51) maxlength(51) // @Param counter path integer true "Counter of main operation" -// @Param network query string false "You can set network field for better performance" // @Accept json // @Produce json // @Success 200 {array} Operation // @Failure 400 {object} Error // @Failure 404 {object} Error // @Failure 500 {object} Error -// @Router /v1/opg/{hash}/{counter} [get] +// @Router /v1/opg/{network}/{hash}/{counter} [get] func GetByHashAndCounter() gin.HandlerFunc { return func(c *gin.Context) { ctxs := c.MustGet("contexts").(config.Contexts) @@ -388,11 +287,6 @@ func GetByHashAndCounter() gin.HandlerFunc { return } - var args networkQueryRequest - if err := c.BindQuery(&args); handleError(c, ctxs.Any().Storage, err, http.StatusBadRequest) { - return - } - hash, err := encoding.DecodeBase58(req.Hash) if handleError(c, ctxs.Any().Storage, err, http.StatusBadRequest) { return @@ -401,16 +295,16 @@ func GetByHashAndCounter() gin.HandlerFunc { var opg []operation.Operation var foundContext *config.Context - ctx, err := ctxs.Get(modelTypes.NewNetwork(args.Network)) - if err == nil { - opg, err = ctx.Operations.GetByHashAndCounter(hash, req.Counter) + network := req.NetworkID() + if ctx, ok := ctxs[network]; ok { + opg, err = ctx.Operations.GetByHashAndCounter(c.Request.Context(), hash, req.Counter) if handleError(c, ctx.Storage, err, 0) { return } foundContext = ctx } else { for _, ctx := range ctxs { - opg, err = ctx.Operations.GetByHashAndCounter(hash, req.Counter) + opg, err = ctx.Operations.GetByHashAndCounter(c.Request.Context(), hash, req.Counter) if handleError(c, ctx.Storage, err, 0) { return } @@ -421,7 +315,7 @@ func GetByHashAndCounter() gin.HandlerFunc { } } - resp, err := PrepareOperations(foundContext, opg, false) + resp, err := PrepareOperations(c.Request.Context(), foundContext, opg, false) if handleError(c, foundContext.Storage, err, 0) { return } @@ -430,8 +324,8 @@ func GetByHashAndCounter() gin.HandlerFunc { } } -func getOperationFromMempool(ctx *config.Context, hash string) (*Operation, error) { - res, err := ctx.Mempool.GetByHash(hash) +func getOperationFromMempool(c context.Context, ctx *config.Context, hash string) (*Operation, error) { + res, err := ctx.Mempool.GetByHash(c, hash) if err != nil { return nil, err } @@ -440,324 +334,8 @@ func getOperationFromMempool(ctx *config.Context, hash string) (*Operation, erro case len(res.Originations) > 0: return prepareMempoolOrigination(ctx, res.Originations[0]), nil case len(res.Transactions) > 0: - return prepareMempoolTransaction(ctx, res.Transactions[0]), nil + return prepareMempoolTransaction(c, ctx, res.Transactions[0]), nil default: return nil, nil } } - -func prepareFilters(req operationsRequest) map[string]interface{} { - filters := map[string]interface{}{} - - if req.LastID != "" { - filters["last_id"] = req.LastID - } - - if req.From > 0 { - filters["from"] = req.From / 1000 - } - - if req.To > 0 { - filters["to"] = req.To / 1000 - } - - if req.Status != "" { - statusList := make([]modelTypes.OperationStatus, 0) - for _, item := range strings.Split(req.Status, ",") { - status := modelTypes.NewOperationStatus(item) - statusList = append(statusList, status) - } - filters["status"] = statusList - } - - if req.Entrypoints != "" { - filters["entrypoints"] = strings.Split(req.Entrypoints, ",") - } - return filters -} - -func formatErrors(errs []*tezerrors.Error, op *Operation) error { - for i := range errs { - if err := errs[i].Format(); err != nil { - return err - } - } - op.Errors = errs - return nil -} - -func prepareOperation(ctx *config.Context, operation operation.Operation, bmd []bigmapdiff.BigMapDiff, withStorageDiff bool) (Operation, error) { - var op Operation - op.FromModel(operation) - - op.SourceAlias = operation.Source.Alias - op.DestinationAlias = operation.Destination.Alias - - proto, err := ctx.Cache.ProtocolByID(operation.ProtocolID) - if err != nil { - return op, err - } - op.Protocol = proto.Hash - - if err := formatErrors(operation.Errors, &op); err != nil { - return op, err - } - - switch operation.Kind { - case modelTypes.OperationKindEvent, modelTypes.OperationKindTransferTicket: - payloadType, err := ast.NewTypedAstFromBytes(operation.PayloadType) - if err != nil { - return op, err - } - if err := payloadType.SettleFromBytes(operation.Payload); err != nil { - return op, err - } - payloadMiguel, err := payloadType.ToMiguel() - if err != nil { - return op, err - } - op.Payload = payloadMiguel - return op, err - case modelTypes.OperationKindSrExecuteOutboxMessage: - if len(operation.Payload) >= 32 { - commitment, err := encoding.EncodeBase58(operation.Payload[:32], []byte(encoding.PrefixSmartRollupCommitment)) - if err != nil { - return op, err - } - op.Payload = []*ast.MiguelNode{ - { - Prim: "pair", - Type: "namedtuple", - Children: []*ast.MiguelNode{ - { - Prim: "string", - Type: "string", - Name: getStringPointer("cemented_commitment"), - Value: commitment, - }, { - Prim: "bytes", - Type: "bytes", - Name: getStringPointer("output_proof"), - Value: hex.EncodeToString(operation.Payload[32:]), - }, - }, - }, - } - } - - } - - if bcd.IsContract(op.Destination) { - if withStorageDiff { - storageType, err := getStorageType(ctx.Contracts, op.Destination, proto.SymLink) - if err != nil { - return op, err - } - if len(operation.DeffatedStorage) > 0 && (operation.IsCall() || operation.IsOrigination() || operation.IsImplicit()) && operation.IsApplied() { - if err := setStorageDiff(ctx, operation.DestinationID, operation.DeffatedStorage, &op, bmd, storageType); err != nil { - return op, err - } - } - } - - if !operation.IsTransaction() { - return op, nil - } - - if operation.IsCall() && !tezerrors.HasParametersError(op.Errors) { - parameterType, err := getParameterType(ctx.Contracts, op.Destination, proto.SymLink) - if err != nil { - return op, err - } - if err := setParameters(operation.Parameters, parameterType, &op); err != nil { - return op, err - } - } - } - - if bcd.IsSmartRollupHash(op.Destination) && operation.IsTransaction() && operation.IsCall() && !tezerrors.HasParametersError(op.Errors) { - rollup, err := ctx.SmartRollups.Get(op.Destination) - if err != nil { - return op, err - } - tree, err := ast.NewTypedAstFromBytes(rollup.Type) - if err != nil { - return op, err - } - if err := setParameters(operation.Parameters, tree, &op); err != nil { - return op, err - } - } - - return op, nil -} - -// PrepareOperations - -func PrepareOperations(ctx *config.Context, ops []operation.Operation, withStorageDiff bool) ([]Operation, error) { - resp := make([]Operation, len(ops)) - for i := 0; i < len(ops); i++ { - var diffs []bigmapdiff.BigMapDiff - var err error - - if withStorageDiff && ops[i].BigMapDiffsCount > 0 { - diffs, err = ctx.BigMapDiffs.GetForOperation(ops[i].ID) - if err != nil { - return nil, err - } - } - - op, err := prepareOperation(ctx, ops[i], diffs, withStorageDiff) - if err != nil { - return nil, err - } - op.Network = ctx.Network.String() - resp[i] = op - } - return resp, nil -} - -func setParameters(data []byte, parameter *ast.TypedAst, op *Operation) error { - if len(data) == 0 { - return nil - } - params := types.NewParameters(data) - return setParatemetersWithType(params, parameter, op) -} - -func setParatemetersWithType(params *types.Parameters, parameter *ast.TypedAst, op *Operation) error { - if params == nil { - return errors.New("Empty parameters") - } - tree, err := parameter.FromParameters(params) - if err != nil { - if tezerrors.HasGasExhaustedError(op.Errors) { - return nil - } - return err - } - - op.Parameters, err = tree.ToMiguel() - if err != nil { - if !tezerrors.HasGasExhaustedError(op.Errors) { - helpers.CatchErrorSentry(err) - return err - } - } - return nil -} - -func setStorageDiff(ctx *config.Context, destinationID int64, storage []byte, op *Operation, bmd []bigmapdiff.BigMapDiff, storageType *ast.TypedAst) error { - storageDiff, err := getStorageDiff(ctx, destinationID, bmd, storage, storageType, op) - if err != nil { - return err - } - op.StorageDiff = storageDiff - return nil -} - -func getStorageDiff(ctx *config.Context, destinationID int64, bmd []bigmapdiff.BigMapDiff, storage []byte, storageType *ast.TypedAst, op *Operation) (*ast.MiguelNode, error) { - currentStorage := &ast.TypedAst{ - Nodes: []ast.Node{ast.Copy(storageType.Nodes[0])}, - } - var prevStorage *ast.TypedAst - - prev, err := ctx.Operations.Last( - map[string]interface{}{ - "destination_id": destinationID, - "status": modelTypes.OperationStatusApplied, - "timestamp": core.TimestampFilter{ - Lt: op.Timestamp, - }, - }, op.ID) - if err == nil { - prevStorage = &ast.TypedAst{ - Nodes: []ast.Node{ast.Copy(storageType.Nodes[0])}, - } - - prevBmd, err := ctx.BigMapDiffs.Previous(bmd) - if err != nil { - return nil, err - } - - if len(prev.DeffatedStorage) > 0 { - if len(prevBmd) > 0 { - if err := prepareStorage(prevStorage, prev.DeffatedStorage, prevBmd); err != nil { - return nil, err - } - } else { - if err := prepareStorage(prevStorage, prev.DeffatedStorage, nil); err != nil { - return nil, err - } - } - } - } else if !ctx.Storage.IsRecordNotFound(err) { - return nil, err - } - - if err := prepareStorage(currentStorage, storage, bmd); err != nil { - return nil, err - } - if !currentStorage.IsSettled() { - return nil, nil - } - return currentStorage.Diff(prevStorage) -} - -func prepareStorage(storageType *ast.TypedAst, deffatedStorage []byte, bmd []bigmapdiff.BigMapDiff) error { - if err := storageType.SettleFromBytes(deffatedStorage); err != nil { - return err - } - - return getEnrichStorage(storageType, bmd) -} - -func getEnrichStorage(storageType *ast.TypedAst, bmd []bigmapdiff.BigMapDiff) error { - if len(bmd) == 0 { - return nil - } - - return storage.Enrich(storageType, bmd, false, true) -} - -func getErrorLocation(ctx *config.Context, operation operation.Operation, window int) (GetErrorLocationResponse, error) { - proto, err := ctx.Cache.ProtocolByID(operation.ProtocolID) - if err != nil { - return GetErrorLocationResponse{}, err - } - code, err := getScriptBytes(ctx.Contracts, operation.Destination.Address, proto.SymLink) - if err != nil { - return GetErrorLocationResponse{}, err - } - opErr := tezerrors.First(operation.Errors, consts.ScriptRejectedError) - if opErr == nil { - return GetErrorLocationResponse{}, errors.Errorf("Can't find script rejected error") - } - defaultError, ok := opErr.IError.(*tezerrors.DefaultError) - if !ok { - return GetErrorLocationResponse{}, errors.Errorf("Invalid error type: %T", opErr) - } - - location := int(defaultError.Location) - sections := gjson.ParseBytes(code) - row, sCol, eCol, err := formattererror.LocateContractError(sections, location) - if err != nil { - return GetErrorLocationResponse{}, err - } - - michelson, err := formatter.MichelineToMichelson(sections, false, formatter.DefLineSize) - if err != nil { - return GetErrorLocationResponse{}, err - } - rows := strings.Split(michelson, "\n") - start := helpers.Max(0, row-window) - end := helpers.Min(len(rows), row+window+1) - - rows = rows[start:end] - return GetErrorLocationResponse{ - Text: strings.Join(rows, "\n"), - FailedRow: row + 1, - StartColumn: sCol, - EndColumn: eCol, - FirstRow: start + 1, - }, nil -} diff --git a/cmd/api/handlers/prepare.go b/cmd/api/handlers/prepare.go new file mode 100644 index 000000000..d9e6cffe7 --- /dev/null +++ b/cmd/api/handlers/prepare.go @@ -0,0 +1,375 @@ +package handlers + +import ( + "context" + "encoding/hex" + "strings" + + "github.com/baking-bad/bcdhub/internal/bcd" + "github.com/baking-bad/bcdhub/internal/bcd/ast" + "github.com/baking-bad/bcdhub/internal/bcd/consts" + "github.com/baking-bad/bcdhub/internal/bcd/encoding" + "github.com/baking-bad/bcdhub/internal/bcd/formatter" + formattererror "github.com/baking-bad/bcdhub/internal/bcd/formatter/error" + "github.com/baking-bad/bcdhub/internal/bcd/tezerrors" + "github.com/baking-bad/bcdhub/internal/bcd/types" + "github.com/baking-bad/bcdhub/internal/config" + "github.com/baking-bad/bcdhub/internal/helpers" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/protocol" + modelTypes "github.com/baking-bad/bcdhub/internal/models/types" + "github.com/baking-bad/bcdhub/internal/parsers/storage" + "github.com/baking-bad/bcdhub/internal/postgres/core" + "github.com/pkg/errors" + "github.com/tidwall/gjson" +) + +func newOperationResponse(ctx context.Context, cfgCtx *config.Context, operation operation.Operation) (Operation, protocol.Protocol, error) { + var response Operation + response.FromModel(operation) + response.Network = cfgCtx.Network.String() + + proto, err := cfgCtx.Cache.ProtocolByID(ctx, operation.ProtocolID) + if err != nil { + return response, proto, err + } + response.Protocol = proto.Hash + + err = formatErrors(operation.Errors, &response) + return response, proto, err +} + +func preparePayloadOperation(ctx context.Context, cfgCtx *config.Context, operation operation.Operation) (Operation, error) { + response, _, err := newOperationResponse(ctx, cfgCtx, operation) + if err != nil { + return response, err + } + payloadType, err := ast.NewTypedAstFromBytes(operation.PayloadType) + if err != nil { + return response, err + } + if err := payloadType.SettleFromBytes(operation.Payload); err != nil { + return response, err + } + payloadMiguel, err := payloadType.ToMiguel() + if err != nil { + return response, err + } + response.Payload = payloadMiguel + return response, err +} + +func prepareSrExecute(ctx context.Context, cfgCtx *config.Context, operation operation.Operation) (Operation, error) { + response, _, err := newOperationResponse(ctx, cfgCtx, operation) + if err != nil { + return response, err + } + + if len(operation.Payload) < 32 { + return response, nil + } + + commitment, err := encoding.EncodeBase58(operation.Payload[:32], []byte(encoding.PrefixSmartRollupCommitment)) + if err != nil { + return response, err + } + response.Payload = []*ast.MiguelNode{ + { + Prim: "pair", + Type: "namedtuple", + Children: []*ast.MiguelNode{ + { + Prim: "string", + Type: "string", + Name: getStringPointer("cemented_commitment"), + Value: commitment, + }, { + Prim: "bytes", + Type: "bytes", + Name: getStringPointer("output_proof"), + Value: hex.EncodeToString(operation.Payload[32:]), + }, + }, + }, + } + + return response, nil +} + +func prepareTransaction(ctx context.Context, cfgCtx *config.Context, operation operation.Operation, withStorageDiff bool) (Operation, error) { + response, proto, err := newOperationResponse(ctx, cfgCtx, operation) + if err != nil { + return response, err + } + + if withStorageDiff && operation.CanHasStorageDiff() { + if err := setFullStorage(ctx, cfgCtx, proto.SymLink, operation, &response); err != nil { + return response, err + } + } + + if operation.IsCall() && !tezerrors.HasParametersError(response.Errors) { + switch { + case bcd.IsContract(response.Destination): + parameterType, err := getParameterType(ctx, cfgCtx.Contracts, response.Destination, proto.SymLink) + if err != nil { + return response, err + } + if err := setParameters(operation.Parameters, parameterType, &response); err != nil { + return response, err + } + case bcd.IsSmartRollupHash(response.Destination): + rollup, err := cfgCtx.SmartRollups.Get(ctx, response.Destination) + if err != nil { + return response, err + } + tree, err := ast.NewTypedAstFromBytes(rollup.Type) + if err != nil { + return response, err + } + if err := setParameters(operation.Parameters, tree, &response); err != nil { + return response, err + } + } + } + + return response, nil +} + +func prepareOrigination(ctx context.Context, cfgCtx *config.Context, operation operation.Operation, withStorageDiff bool) (Operation, error) { + response, proto, err := newOperationResponse(ctx, cfgCtx, operation) + if err != nil { + return response, err + } + + if !withStorageDiff { + return response, nil + } + if !operation.CanHasStorageDiff() { + return response, nil + } + + err = setFullStorage(ctx, cfgCtx, proto.SymLink, operation, &response) + return response, err +} + +func setFullStorage(ctx context.Context, cfgCtx *config.Context, symLink string, operation operation.Operation, response *Operation) error { + storageType, err := getStorageType(ctx, cfgCtx.Contracts, response.Destination, symLink) + if err != nil { + return err + } + + var diffs []bigmapdiff.BigMapDiff + + if operation.BigMapDiffsCount > 0 { + if len(operation.BigMapDiffs) == 0 { + diffs, err = cfgCtx.BigMapDiffs.GetForOperation(ctx, operation.ID) + if err != nil { + return err + } + } else { + diffs = make([]bigmapdiff.BigMapDiff, len(operation.BigMapDiffs)) + for i := range operation.BigMapDiffs { + diffs[i] = *operation.BigMapDiffs[i] + } + } + } + + return setStorageDiff(ctx, cfgCtx, operation.DestinationID, operation.DeffatedStorage, response, diffs, storageType) +} + +func prepareOperation(ctx context.Context, cfgCtx *config.Context, operation operation.Operation, withStorageDiff bool) (Operation, error) { + switch operation.Kind { + case modelTypes.OperationKindEvent: + return preparePayloadOperation(ctx, cfgCtx, operation) + case modelTypes.OperationKindTransferTicket: + return preparePayloadOperation(ctx, cfgCtx, operation) + case modelTypes.OperationKindTransaction: + return prepareTransaction(ctx, cfgCtx, operation, withStorageDiff) + case modelTypes.OperationKindOrigination: + return prepareOrigination(ctx, cfgCtx, operation, withStorageDiff) + case modelTypes.OperationKindOriginationNew: + return prepareOrigination(ctx, cfgCtx, operation, withStorageDiff) + case modelTypes.OperationKindSrExecuteOutboxMessage: + return prepareSrExecute(ctx, cfgCtx, operation) + case modelTypes.OperationKindRegisterGlobalConstant: + response, _, err := newOperationResponse(ctx, cfgCtx, operation) + return response, err + case modelTypes.OperationKindSrOrigination: + response, _, err := newOperationResponse(ctx, cfgCtx, operation) + return response, err + default: + return Operation{}, errors.Errorf("unknown operation kind: %s", operation.Kind.String()) + } +} + +// PrepareOperations - +func PrepareOperations(c context.Context, ctx *config.Context, ops []operation.Operation, withStorageDiff bool) ([]Operation, error) { + resp := make([]Operation, len(ops)) + for i := 0; i < len(ops); i++ { + op, err := prepareOperation(c, ctx, ops[i], withStorageDiff) + if err != nil { + return nil, err + } + resp[i] = op + } + return resp, nil +} + +func setParameters(data []byte, parameter *ast.TypedAst, op *Operation) error { + if len(data) == 0 { + return nil + } + params := types.NewParameters(data) + return setParatemetersWithType(params, parameter, op) +} + +func setParatemetersWithType(params *types.Parameters, parameter *ast.TypedAst, op *Operation) error { + if params == nil { + return errors.New("Empty parameters") + } + tree, err := parameter.FromParameters(params) + if err != nil { + if tezerrors.HasGasExhaustedError(op.Errors) { + return nil + } + return err + } + + op.Parameters, err = tree.ToMiguel() + if err != nil { + if !tezerrors.HasGasExhaustedError(op.Errors) { + helpers.CatchErrorSentry(err) + return err + } + } + return nil +} + +func setStorageDiff(c context.Context, ctx *config.Context, destinationID int64, storage []byte, op *Operation, bmd []bigmapdiff.BigMapDiff, storageType *ast.TypedAst) error { + storageDiff, err := getStorageDiff(c, ctx, destinationID, bmd, storage, storageType, op) + if err != nil { + return err + } + op.StorageDiff = storageDiff + return nil +} + +func getStorageDiff(c context.Context, ctx *config.Context, destinationID int64, bmd []bigmapdiff.BigMapDiff, storage []byte, storageType *ast.TypedAst, op *Operation) (*ast.MiguelNode, error) { + currentStorage := &ast.TypedAst{ + Nodes: []ast.Node{ast.Copy(storageType.Nodes[0])}, + } + var prevStorage *ast.TypedAst + + prev, err := ctx.Operations.Last( + c, + map[string]interface{}{ + "destination_id": destinationID, + "status": modelTypes.OperationStatusApplied, + "timestamp": core.TimestampFilter{ + Lt: op.Timestamp, + }, + }, op.ID) + if err == nil { + prevStorage = &ast.TypedAst{ + Nodes: []ast.Node{ast.Copy(storageType.Nodes[0])}, + } + + prevBmd, err := ctx.BigMapDiffs.Previous(c, bmd) + if err != nil { + return nil, err + } + + if len(prev.DeffatedStorage) > 0 { + if len(prevBmd) > 0 { + if err := prepareStorage(prevStorage, prev.DeffatedStorage, prevBmd); err != nil { + return nil, err + } + } else { + if err := prepareStorage(prevStorage, prev.DeffatedStorage, nil); err != nil { + return nil, err + } + } + } + } else if !ctx.Storage.IsRecordNotFound(err) { + return nil, err + } + + if err := prepareStorage(currentStorage, storage, bmd); err != nil { + return nil, err + } + if !currentStorage.IsSettled() { + return nil, nil + } + return currentStorage.Diff(prevStorage) +} + +func prepareStorage(storageType *ast.TypedAst, deffatedStorage []byte, bmd []bigmapdiff.BigMapDiff) error { + if err := storageType.SettleFromBytes(deffatedStorage); err != nil { + return err + } + + return getEnrichStorage(storageType, bmd) +} + +func getEnrichStorage(storageType *ast.TypedAst, bmd []bigmapdiff.BigMapDiff) error { + if len(bmd) == 0 { + return nil + } + + return storage.Enrich(storageType, bmd, false, true) +} + +func getErrorLocation(c context.Context, ctx *config.Context, operation operation.Operation, window int) (GetErrorLocationResponse, error) { + proto, err := ctx.Cache.ProtocolByID(c, operation.ProtocolID) + if err != nil { + return GetErrorLocationResponse{}, err + } + code, err := getScriptBytes(c, ctx.Cache, operation.Destination.Address, proto.SymLink) + if err != nil { + return GetErrorLocationResponse{}, err + } + opErr := tezerrors.First(operation.Errors, consts.ScriptRejectedError) + if opErr == nil { + return GetErrorLocationResponse{}, errors.Errorf("Can't find script rejected error") + } + defaultError, ok := opErr.IError.(*tezerrors.DefaultError) + if !ok { + return GetErrorLocationResponse{}, errors.Errorf("Invalid error type: %T", opErr) + } + + location := int(defaultError.Location) + sections := gjson.ParseBytes(code) + row, sCol, eCol, err := formattererror.LocateContractError(sections, location) + if err != nil { + return GetErrorLocationResponse{}, err + } + + michelson, err := formatter.MichelineToMichelson(sections, false, formatter.DefLineSize) + if err != nil { + return GetErrorLocationResponse{}, err + } + rows := strings.Split(michelson, "\n") + start := helpers.Max(0, row-window) + end := helpers.Min(len(rows), row+window+1) + + rows = rows[start:end] + return GetErrorLocationResponse{ + Text: strings.Join(rows, "\n"), + FailedRow: row + 1, + StartColumn: sCol, + EndColumn: eCol, + FirstRow: start + 1, + }, nil +} + +func formatErrors(errs []*tezerrors.Error, op *Operation) error { + for i := range errs { + if err := errs[i].Format(); err != nil { + return err + } + } + op.Errors = errs + return nil +} diff --git a/cmd/api/handlers/requests.go b/cmd/api/handlers/requests.go index 346a98f81..53d250b45 100644 --- a/cmd/api/handlers/requests.go +++ b/cmd/api/handlers/requests.go @@ -8,8 +8,8 @@ import ( ) type getAccountRequest struct { - Address string `uri:"address" binding:"required,address"` - Network string `uri:"network" binding:"required,network"` + Address string `binding:"required,address" uri:"address"` + Network string `binding:"required,network" uri:"network"` } // NetworkID - @@ -18,8 +18,8 @@ func (req getAccountRequest) NetworkID() types.Network { } type getContractRequest struct { - Address string `uri:"address" binding:"required,contract"` - Network string `uri:"network" binding:"required,network"` + Address string `binding:"required,contract" uri:"address"` + Network string `binding:"required,network" uri:"network"` } // NetworkID - @@ -34,7 +34,7 @@ type getContractCodeRequest struct { } type withStatsRequest struct { - Stats *bool `form:"stats,omitempty" binding:"omitempty"` + Stats *bool `binding:"omitempty" form:"stats,omitempty"` } // HasStats - @@ -42,32 +42,23 @@ func (req withStatsRequest) HasStats() bool { return req.Stats == nil || *req.Stats } -type networkQueryRequest struct { - Network string `form:"network,omitempty" binding:"omitempty,network"` -} - -// NetworkID - -func (req networkQueryRequest) NetworkID() types.Network { - return types.NewNetwork(req.Network) -} - // CodeDiffLeg - type CodeDiffLeg struct { - Address string `json:"address" binding:"required,address"` - Network types.Network `json:"network" binding:"required,network"` + Address string `binding:"required,address" json:"address"` + Network types.Network `binding:"required,network" json:"network"` Protocol string `json:"protocol,omitempty"` Level int64 `json:"level,omitempty"` } // CodeDiffRequest - type CodeDiffRequest struct { - Left CodeDiffLeg `json:"left" binding:"required"` - Right CodeDiffLeg `json:"right" binding:"required"` + Left CodeDiffLeg `binding:"required" json:"left"` + Right CodeDiffLeg `binding:"required" json:"right"` } type getBigMapRequest struct { - Network string `uri:"network" binding:"required,network"` - Ptr int64 `uri:"ptr" binding:"min=0"` + Network string `binding:"required,network" uri:"network"` + Ptr int64 `binding:"min=0" uri:"ptr"` } // NetworkID - @@ -76,9 +67,9 @@ func (req getBigMapRequest) NetworkID() types.Network { } type getBigMapByKeyHashRequest struct { - Network string `uri:"network" binding:"required,network"` - Ptr int64 `uri:"ptr" binding:"min=0"` - KeyHash string `uri:"key_hash" binding:"required"` + Network string `binding:"required,network" uri:"network"` + Ptr int64 `binding:"min=0" uri:"ptr"` + KeyHash string `binding:"required" uri:"key_hash"` } // OauthRequest - @@ -92,43 +83,34 @@ type OauthParams struct { Provider string `uri:"provider"` } -type operationsRequest struct { - LastID string `form:"last_id" binding:"omitempty,numeric"` - From uint `form:"from" binding:"omitempty"` - To uint `form:"to" binding:"omitempty,gtfield=From"` - Size uint64 `form:"size" binding:"min=0"` - Status string `form:"status" binding:"omitempty,status"` - Entrypoints string `form:"entrypoints" binding:"omitempty,excludesall=\"'"` - WithStorageDiff bool `form:"with_storage_diff"` -} - type opgForAddressRequest struct { - LastID int64 `form:"last_id" binding:"omitempty"` - Size uint64 `form:"size" binding:"min=0"` + LastID int64 `binding:"omitempty" form:"last_id"` + Size uint64 `binding:"min=0" form:"size"` } type pageableRequest struct { - Offset int64 `form:"offset" binding:"min=0"` - Size int64 `form:"size" binding:"min=0,bcd_max_size=10"` + Offset int64 `binding:"min=0" form:"offset"` + Size int64 `binding:"min=0,bcd_max_size=10" form:"size"` } // OPGRequest - type OPGRequest struct { - Hash string `uri:"hash" binding:"required,opg" example:"ooy4c6G2BZzybYEY3vRQ7WXGL63tFmamTeGTHdjUxhd6ckbSNnb"` + getByNetwork + Hash string `binding:"required,opg" example:"ooy4c6G2BZzybYEY3vRQ7WXGL63tFmamTeGTHdjUxhd6ckbSNnb" uri:"hash"` } // OperationGroupContentRequest - type OperationGroupContentRequest struct { OPGRequest - Counter int64 `uri:"counter" binding:"required" example:"123456"` + Counter int64 `binding:"required" example:"123456" uri:"counter"` } // ImplicitOperationRequest - type ImplicitOperationRequest struct { getByNetwork - Counter int64 `uri:"counter" binding:"required" example:"123456"` + Counter int64 `binding:"required" example:"123456" uri:"counter"` } // FormatterRequest - @@ -139,7 +121,7 @@ type FormatterRequest struct { } type getByNetwork struct { - Network string `uri:"network" binding:"required,network" example:"mainnet"` + Network string `binding:"required,network" example:"mainnet" uri:"network"` } // NetworkID - @@ -149,59 +131,58 @@ func (req getByNetwork) NetworkID() types.Network { type bigMapSearchRequest struct { pageableRequest - MaxLevel *int64 `form:"max_level,omitempty" binding:"omitempty,gt_int64_ptr=MinLevel"` - MinLevel *int64 `form:"min_level,omitempty" binding:"omitempty"` + MaxLevel *int64 `binding:"omitempty,gt_int64_ptr=MinLevel" form:"max_level,omitempty"` + MinLevel *int64 `binding:"omitempty" form:"min_level,omitempty"` } type opgRequest struct { - WithMempool bool `form:"with_mempool" binding:"omitempty"` - WithStorageDiff bool `form:"with_storage_diff" binding:"omitempty"` - Network string `form:"network" binding:"omitempty,network" example:"mainnet"` + WithMempool bool `binding:"omitempty" form:"with_mempool"` + WithStorageDiff bool `binding:"omitempty" form:"with_storage_diff"` } type getEntrypointDataRequest struct { - Name string `json:"name" binding:"required"` - Data map[string]interface{} `json:"data" binding:"required"` + Name string `binding:"required" json:"name"` + Data map[string]interface{} `binding:"required" json:"data"` Format string `json:"format"` } type getOperationByIDRequest struct { - ID int64 `uri:"id" binding:"required"` + ID int64 `binding:"required" uri:"id"` } type runOperationRequest struct { - Data map[string]interface{} `json:"data" binding:"required"` - Name string `json:"name" binding:"required"` + Data map[string]interface{} `binding:"required" json:"data"` + Name string `binding:"required" json:"name"` Amount int64 `json:"amount,omitempty"` - Source string `json:"source,omitempty" binding:"omitempty,address"` + Source string `binding:"omitempty,address" json:"source,omitempty"` } type runCodeRequest struct { - Data map[string]interface{} `json:"data" binding:"required"` - Name string `json:"name" binding:"required"` + Data map[string]interface{} `binding:"required" json:"data"` + Name string `binding:"required" json:"name"` Amount int64 `json:"amount,omitempty"` GasLimit int64 `json:"gas_limit,omitempty"` - Source string `json:"source,omitempty" binding:"omitempty,address"` - Sender string `json:"sender,omitempty" binding:"omitempty,address"` + Source string `binding:"omitempty,address" json:"source,omitempty"` + Sender string `binding:"omitempty,address" json:"sender,omitempty"` } type storageSchemaRequest struct { - FillType string `form:"fill_type,omitempty" binding:"omitempty,fill_type"` + FillType string `binding:"omitempty,fill_type" form:"fill_type,omitempty"` } type entrypointSchemaRequest struct { - FillType string `form:"fill_type,omitempty" binding:"omitempty"` - EntrypointName string `form:"entrypoint" binding:"required"` - Hash string `form:"hash,omitempty" binding:"omitempty"` - Counter *uint64 `form:"counter,omitempty" binding:"omitempty"` + FillType string `binding:"omitempty" form:"fill_type,omitempty"` + EntrypointName string `binding:"required" form:"entrypoint"` + Hash string `binding:"omitempty" form:"hash,omitempty"` + Counter *uint64 `binding:"omitempty" form:"counter,omitempty"` } type forkRequest struct { - Address string `json:"address,omitempty" binding:"omitempty,address,required_with=Network"` - Network string `json:"network,omitempty" binding:"omitempty,network,required_with=Address"` - Script string `json:"script,omitempty" binding:"omitempty"` + Address string `binding:"omitempty,address,required_with=Network" json:"address,omitempty"` + Network string `binding:"omitempty,network,required_with=Address" json:"network,omitempty"` + Script string `binding:"omitempty" json:"script,omitempty"` - Storage map[string]interface{} `json:"storage" binding:"required"` + Storage map[string]interface{} `binding:"required" json:"storage"` } // NetworkID - @@ -210,12 +191,12 @@ func (req forkRequest) NetworkID() types.Network { } type storageRequest struct { - Level int `form:"level" binding:"omitempty,gte=1"` + Level int `binding:"omitempty,gte=1" form:"level"` } // GetTokenStatsRequest - type GetTokenStatsRequest struct { - Period string `form:"period" binding:"oneof=all year month week day hour" example:"year"` + Period string `binding:"oneof=all year month week day hour" example:"year" form:"period"` Contracts string `form:"contracts"` } @@ -228,26 +209,26 @@ func (req GetTokenStatsRequest) Addresses() []string { } type executeViewRequest struct { - Data map[string]interface{} `json:"data" binding:"required"` - Name string `json:"name" binding:"required_if=Kind on-chain"` - Implementation *int `json:"implementation" binding:"required_if=Kind on-chain"` - Kind ViewSchemaKind `json:"kind" binding:"required"` + Data map[string]interface{} `binding:"required" json:"data"` + Name string `binding:"required_if=Kind on-chain" json:"name"` + Implementation *int `binding:"required_if=Kind on-chain" json:"implementation"` + Kind ViewSchemaKind `binding:"required" json:"kind"` Amount int64 `json:"amount,omitempty"` GasLimit int64 `json:"gas_limit,omitempty"` - Source string `json:"source,omitempty" binding:"omitempty,address"` - Sender string `json:"sender,omitempty" binding:"omitempty,address"` - View *contract.ViewImplementation `json:"view,omitempty" binding:"required_if=Kind off-chain"` + Source string `binding:"omitempty,address" json:"source,omitempty"` + Sender string `binding:"omitempty,address" json:"sender,omitempty"` + View *contract.ViewImplementation `binding:"required_if=Kind off-chain" json:"view,omitempty"` } type getGlobalConstantRequest struct { - Address string `uri:"address" binding:"required,global_constant"` + Address string `binding:"required,global_constant" uri:"address"` } type globalConstantsListRequest struct { pageableRequest - OrderBy string `form:"order_by" binding:"omitempty,oneof=level timestamp links_count address"` - Sort string `form:"sort" binding:"omitempty,oneof=asc desc"` + OrderBy string `binding:"omitempty,oneof=level timestamp links_count address" form:"order_by"` + Sort string `binding:"omitempty,oneof=asc desc" form:"sort"` } type globalConstantsContractsRequest struct { @@ -256,19 +237,31 @@ type globalConstantsContractsRequest struct { } type getViewsArgs struct { - Kind ViewSchemaKind `form:"kind" binding:"omitempty,oneof=off-chain on-chain"` + Kind ViewSchemaKind `binding:"omitempty,oneof=off-chain on-chain" form:"kind"` } type findContract struct { - Tags string `form:"tags" binding:"omitempty"` + Tags string `binding:"omitempty" form:"tags"` } type smartRollupListRequest struct { pageableRequest - Sort string `form:"sort" binding:"omitempty,oneof=asc desc"` + Sort string `binding:"omitempty,oneof=asc desc" form:"sort"` } type getSmartRollupRequest struct { - Address string `uri:"address" binding:"required,smart_rollup"` + Address string `binding:"required,smart_rollup" uri:"address"` +} + +type ticketBalancesRequest struct { + pageableRequest + WithoutZeroBalances bool `binding:"omitempty" form:"skip_empty"` +} + +type ticketUpdatesRequest struct { + pageableRequest + + Account string `binding:"omitempty,address" form:"account"` + TicketId *uint64 `binding:"omitempty" form:"ticket_id"` } diff --git a/cmd/api/handlers/responses.go b/cmd/api/handlers/responses.go index 466e3e8a9..83c437c30 100644 --- a/cmd/api/handlers/responses.go +++ b/cmd/api/handlers/responses.go @@ -15,55 +15,54 @@ import ( "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/protocol" smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" + "github.com/baking-bad/bcdhub/internal/models/stats" "github.com/baking-bad/bcdhub/internal/models/ticket" "github.com/baking-bad/bcdhub/internal/models/types" ) // Error - type Error struct { - Message string `json:"message" example:"text"` + Message string `example:"text" json:"message"` } // Operation - type Operation struct { - ID int64 `json:"id,omitempty" extensions:"x-nullable"` - Level int64 `json:"level,omitempty" extensions:"x-nullable"` - Fee int64 `json:"fee,omitempty" extensions:"x-nullable"` - Counter int64 `json:"counter,omitempty" extensions:"x-nullable"` - GasLimit int64 `json:"gas_limit,omitempty" extensions:"x-nullable"` - StorageLimit int64 `json:"storage_limit,omitempty" extensions:"x-nullable"` - Amount int64 `json:"amount,omitempty" extensions:"x-nullable"` - Balance int64 `json:"balance,omitempty" extensions:"x-nullable"` - Burned int64 `json:"burned,omitempty" extensions:"x-nullable"` - AllocatedDestinationContractBurned int64 `json:"allocated_destination_contract_burned,omitempty" extensions:"x-nullable"` + ID int64 `extensions:"x-nullable" json:"id,omitempty"` + Level int64 `extensions:"x-nullable" json:"level,omitempty"` + Fee int64 `extensions:"x-nullable" json:"fee,omitempty"` + Counter int64 `extensions:"x-nullable" json:"counter,omitempty"` + GasLimit int64 `extensions:"x-nullable" json:"gas_limit,omitempty"` + StorageLimit int64 `extensions:"x-nullable" json:"storage_limit,omitempty"` + Amount int64 `extensions:"x-nullable" json:"amount,omitempty"` + Balance int64 `extensions:"x-nullable" json:"balance,omitempty"` + Burned int64 `extensions:"x-nullable" json:"burned,omitempty"` + AllocatedDestinationContractBurned int64 `extensions:"x-nullable" json:"allocated_destination_contract_burned,omitempty"` IndexedTime int64 `json:"-"` ContentIndex int64 `json:"content_index"` - ConsumedGas int64 `json:"consumed_gas,omitempty" extensions:"x-nullable" example:"100"` - StorageSize int64 `json:"storage_size,omitempty" extensions:"x-nullable" example:"200"` - PaidStorageSizeDiff int64 `json:"paid_storage_size_diff,omitempty" extensions:"x-nullable" example:"300"` + ConsumedGas int64 `example:"100" extensions:"x-nullable" json:"consumed_gas,omitempty"` + StorageSize int64 `example:"200" extensions:"x-nullable" json:"storage_size,omitempty"` + PaidStorageSizeDiff int64 `example:"300" extensions:"x-nullable" json:"paid_storage_size_diff,omitempty"` TicketUpdatesCount int `json:"ticket_updates_count"` BigMapDiffsCount int `json:"big_map_diffs_count"` - Errors []*tezerrors.Error `json:"errors,omitempty" extensions:"x-nullable"` - Parameters interface{} `json:"parameters,omitempty" extensions:"x-nullable"` - StorageDiff *ast.MiguelNode `json:"storage_diff,omitempty" extensions:"x-nullable"` - Payload []*ast.MiguelNode `json:"payload,omitempty" extensions:"x-nullable"` - RawMempool interface{} `json:"rawMempool,omitempty" extensions:"x-nullable"` + Errors []*tezerrors.Error `extensions:"x-nullable" json:"errors,omitempty"` + Parameters interface{} `extensions:"x-nullable" json:"parameters,omitempty"` + StorageDiff *ast.MiguelNode `extensions:"x-nullable" json:"storage_diff,omitempty"` + Payload []*ast.MiguelNode `extensions:"x-nullable" json:"payload,omitempty"` + RawMempool interface{} `extensions:"x-nullable" json:"rawMempool,omitempty"` Timestamp time.Time `json:"timestamp"` Protocol string `json:"protocol"` - Hash string `json:"hash,omitempty" extensions:"x-nullable"` + Hash string `extensions:"x-nullable" json:"hash,omitempty"` Network string `json:"network"` Kind string `json:"kind"` - Source string `json:"source,omitempty" extensions:"x-nullable"` - SourceAlias string `json:"source_alias,omitempty" extensions:"x-nullable"` - Destination string `json:"destination,omitempty" extensions:"x-nullable"` - DestinationAlias string `json:"destination_alias,omitempty" extensions:"x-nullable"` - PublicKey string `json:"public_key,omitempty" extensions:"x-nullable"` - ManagerPubKey string `json:"manager_pubkey,omitempty" extensions:"x-nullable"` - Delegate string `json:"delegate,omitempty" extensions:"x-nullable"` + Source string `extensions:"x-nullable" json:"source,omitempty"` + Destination string `extensions:"x-nullable" json:"destination,omitempty"` + PublicKey string `extensions:"x-nullable" json:"public_key,omitempty"` + ManagerPubKey string `extensions:"x-nullable" json:"manager_pubkey,omitempty"` + Delegate string `extensions:"x-nullable" json:"delegate,omitempty"` Status string `json:"status"` - Entrypoint string `json:"entrypoint,omitempty" extensions:"x-nullable"` - Tag string `json:"tag,omitempty" extensions:"x-nullable"` - AllocatedDestinationContract bool `json:"allocated_destination_contract,omitempty" extensions:"x-nullable" example:"true"` + Entrypoint string `extensions:"x-nullable" json:"entrypoint,omitempty"` + Tag string `extensions:"x-nullable" json:"tag,omitempty"` + AllocatedDestinationContract bool `example:"true" extensions:"x-nullable" json:"allocated_destination_contract,omitempty"` Internal bool `json:"internal"` Mempool bool `json:"mempool"` Storage stdJSON.RawMessage `json:"-"` @@ -155,37 +154,29 @@ type Contract struct { Timestamp time.Time `json:"timestamp"` Hash string `json:"hash,omitempty"` - Tags []string `json:"tags,omitempty" extensions:"x-nullable"` - Hardcoded []string `json:"hardcoded,omitempty" extensions:"x-nullable"` - FailStrings []string `json:"fail_strings,omitempty" extensions:"x-nullable"` - Annotations []string `json:"annotations,omitempty" extensions:"x-nullable"` - Entrypoints []string `json:"entrypoints,omitempty" extensions:"x-nullable"` + Tags []string `extensions:"x-nullable" json:"tags,omitempty"` + Hardcoded []string `extensions:"x-nullable" json:"hardcoded,omitempty"` + FailStrings []string `extensions:"x-nullable" json:"fail_strings,omitempty"` + Annotations []string `extensions:"x-nullable" json:"annotations,omitempty"` + Entrypoints []string `extensions:"x-nullable" json:"entrypoints,omitempty"` Address string `json:"address"` - Manager string `json:"manager,omitempty" extensions:"x-nullable"` - Delegate string `json:"delegate,omitempty" extensions:"x-nullable"` + Manager string `extensions:"x-nullable" json:"manager,omitempty"` + Delegate string `extensions:"x-nullable" json:"delegate,omitempty"` - FoundBy string `json:"found_by,omitempty" extensions:"x-nullable"` - LastAction time.Time `json:"last_action,omitempty" extensions:"x-nullable"` - TxCount int64 `json:"tx_count,omitempty" extensions:"x-nullable"` - MigrationsCount int64 `json:"migrations_count,omitempty" extensions:"x-nullable"` - Alias string `json:"alias,omitempty" extensions:"x-nullable"` - DelegateAlias string `json:"delegate_alias,omitempty" extensions:"x-nullable"` - Slug string `json:"slug,omitempty" extensions:"x-nullable"` + FoundBy string `extensions:"x-nullable" json:"found_by,omitempty"` + LastAction time.Time `extensions:"x-nullable" json:"last_action,omitempty"` + TxCount int64 `extensions:"x-nullable" json:"tx_count,omitempty"` + MigrationsCount int64 `extensions:"x-nullable" json:"migrations_count,omitempty"` + Slug string `extensions:"x-nullable" json:"slug,omitempty"` } // FromModel - func (c *Contract) FromModel(contract contract.Contract) { c.Address = contract.Account.Address - c.Alias = contract.Account.Alias c.Delegate = contract.Delegate.Address - c.DelegateAlias = contract.Delegate.Alias - c.TxCount = contract.TxCount - c.LastAction = contract.LastAction - c.Level = contract.Level c.Manager = contract.Manager.Address - c.MigrationsCount = contract.MigrationsCount c.Tags = contract.Tags.ToArray() c.Timestamp = contract.Timestamp @@ -208,33 +199,29 @@ func (c *Contract) FromModel(contract contract.Contract) { type ContractWithStats struct { Contract - SameCount int64 `json:"same_count"` - EventsCount int `json:"events_count"` - HasTicketUpdates bool `json:"has_ticket_updates"` + SameCount int64 `json:"same_count"` } // RecentlyCalledContract - type RecentlyCalledContract struct { - ID int64 `json:"id"` - Address string `json:"address"` - Alias string `json:"alias,omitempty" extensions:"x-nullable"` - LastAction time.Time `json:"last_action,omitempty" extensions:"x-nullable"` - TxCount int64 `json:"tx_count,omitempty" extensions:"x-nullable"` + ID int64 `json:"id"` + Address string `json:"address"` + LastAction time.Time `json:"last_action"` + OperationsCount int64 `json:"operations_count"` } // FromModel - -func (c *RecentlyCalledContract) FromModel(contract contract.Contract) { - c.Address = contract.Account.Address - c.Alias = contract.Account.Alias - c.TxCount = contract.TxCount - c.LastAction = contract.LastAction - c.ID = contract.ID +func (c *RecentlyCalledContract) FromModel(account account.Account) { + c.Address = account.Address + c.ID = account.ID + c.LastAction = account.LastAction + c.OperationsCount = account.OperationsCount } // OperationResponse - type OperationResponse struct { Operations []Operation `json:"operations"` - LastID string `json:"last_id,omitempty" extensions:"x-nullable" example:"1588640276994159"` + LastID string `example:"1588640276994159" extensions:"x-nullable" json:"last_id,omitempty"` } // BigMapItem - @@ -255,77 +242,24 @@ type BigMapResponseItem struct { // GetBigMapResponse - type GetBigMapResponse struct { - Address string `json:"address"` - Network string `json:"network"` - Ptr int64 `json:"ptr"` - ActiveKeys uint `json:"active_keys"` - TotalKeys uint `json:"total_keys"` - ContractAlias string `json:"contract_alias,omitempty" extensions:"x-nullable"` - Typedef []ast.Typedef `json:"typedef,omitempty" extensions:"x-nullable"` + Address string `json:"address"` + Network string `json:"network"` + Ptr int64 `json:"ptr"` + ActiveKeys uint `json:"active_keys"` + TotalKeys uint `json:"total_keys"` + Typedef []ast.Typedef `extensions:"x-nullable" json:"typedef,omitempty"` } // Migration - type Migration struct { Level int64 `json:"level"` Timestamp time.Time `json:"timestamp"` - Hash string `json:"hash,omitempty" extensions:"x-nullable"` + Hash string `extensions:"x-nullable" json:"hash,omitempty"` Protocol string `json:"protocol"` PrevProtocol string `json:"prev_protocol"` Kind string `json:"kind"` } -// TokenContract - -type TokenContract struct { - Network string `json:"network"` - Level int64 `json:"level"` - Timestamp time.Time `json:"timestamp"` - LastAction time.Time `json:"last_action"` - Address string `json:"address"` - Manager string `json:"manager,omitempty" extensions:"x-nullable"` - Delegate string `json:"delegate,omitempty" extensions:"x-nullable"` - Alias string `json:"alias,omitempty" extensions:"x-nullable"` - DelegateAlias string `json:"delegate_alias,omitempty" extensions:"x-nullable"` - Type string `json:"type"` - Balance int64 `json:"balance"` - TxCount int64 `json:"tx_count"` - Methods map[string]TokenMethodStats `json:"methods,omitempty" extensions:"x-nullable"` -} - -// TokenMethodStats - -type TokenMethodStats struct { - CallCount int64 `json:"call_count"` - AverageConsumedGas int64 `json:"average_consumed_gas"` -} - -// PageableTokenContracts - -type PageableTokenContracts struct { - Total int64 `json:"total"` - Tokens []TokenContract `json:"tokens"` -} - -// TokenTransfer - -type TokenTransfer struct { - Contract string `json:"contract"` - Network string `json:"network"` - Protocol string `json:"protocol"` - Hash string `json:"hash"` - Counter int64 `json:"counter,omitempty" extensions:"x-nullable"` - Status string `json:"status"` - Timestamp time.Time `json:"timestamp"` - Level int64 `json:"level"` - From string `json:"from,omitempty" extensions:"x-nullable"` - To string `json:"to"` - Amount int64 `json:"amount"` - Source string `json:"source"` - Nonce *int64 `json:"nonce,omitempty" extensions:"x-nullable"` -} - -// PageableTokenTransfers - -type PageableTokenTransfers struct { - Transfers []TokenTransfer `json:"transfers"` - LastID string `json:"last_id,omitempty" extensions:"x-nullable"` -} - // BigMapDiffItem - type BigMapDiffItem struct { Value interface{} `json:"value"` @@ -335,15 +269,15 @@ type BigMapDiffItem struct { // BigMapDiffByKeyResponse - type BigMapDiffByKeyResponse struct { - Key interface{} `json:"key,omitempty" extensions:"x-nullable"` + Key interface{} `extensions:"x-nullable" json:"key,omitempty"` KeyHash string `json:"key_hash"` - Values []BigMapDiffItem `json:"values,omitempty" extensions:"x-nullable"` + Values []BigMapDiffItem `extensions:"x-nullable" json:"values,omitempty"` Total int64 `json:"total"` } // BigMapKeyStateResponse - type BigMapKeyStateResponse struct { - Key interface{} `json:"key,omitempty" extensions:"x-nullable"` + Key interface{} `extensions:"x-nullable" json:"key,omitempty"` KeyHash string `json:"key_hash"` KeyString string `json:"key_string"` Value interface{} `json:"value"` @@ -362,11 +296,11 @@ type CodeDiffResponse struct { // NetworkStats - type NetworkStats struct { - ContractsCount int64 `json:"contracts_count" example:"10"` - OperationsCount int64 `json:"operations_count" example:"100"` - ContractCalls uint64 `json:"contract_calls" example:"100"` - UniqueContracts uint64 `json:"unique_contracts" example:"100"` - FACount uint64 `json:"fa_count" example:"100"` + ContractsCount int64 `example:"10" json:"contracts_count"` + OperationsCount int64 `example:"100" json:"operations_count"` + ContractCalls uint64 `example:"100" json:"contract_calls"` + UniqueContracts uint64 `example:"100" json:"unique_contracts"` + FACount uint64 `example:"100" json:"fa_count"` Protocols []Protocol `json:"protocols"` } @@ -387,7 +321,7 @@ type SearchBigMapDiff struct { type EntrypointSchema struct { ast.EntrypointType Schema *ast.JSONSchema `json:"schema"` - DefaultModel ast.JSONModel `json:"default_model,omitempty" extensions:"x-nullable"` + DefaultModel ast.JSONModel `extensions:"x-nullable" json:"default_model,omitempty"` } // GetErrorLocationResponse - @@ -399,20 +333,12 @@ type GetErrorLocationResponse struct { EndColumn int `json:"end_col"` } -// Alias - -type Alias struct { - Alias string `json:"alias" example:"Contract alias"` - Network string `json:"network" example:"babylonnet"` - Address string `json:"address" example:"KT1CeekjGVRc5ASmgWDc658NBExetoKNuiqz"` - Slug string `json:"slug" example:"contract_slug"` -} - // Protocol - type Protocol struct { - Hash string `json:"hash" example:"PsCARTHAGazKbHtnKfLzQg3kms52kSRpgnDY982a9oYsSXRLQEb"` - StartLevel int64 `json:"start_level" example:"851969"` - EndLevel int64 `json:"end_level,omitempty" example:"0" extensions:"x-nullable"` - Alias string `json:"alias" example:"Carthage"` + Hash string `example:"PsCARTHAGazKbHtnKfLzQg3kms52kSRpgnDY982a9oYsSXRLQEb" json:"hash"` + StartLevel int64 `example:"851969" json:"start_level"` + EndLevel int64 `example:"0" extensions:"x-nullable" json:"end_level,omitempty"` + Alias string `example:"Carthage" json:"alias"` } // FromModel - @@ -425,17 +351,19 @@ func (p *Protocol) FromModel(protocol protocol.Protocol) { // Block - type Block struct { - Network string `json:"network" example:"mainnet"` - Hash string `json:"hash" example:"BLyAEwaXShJuZasvUezHUfLqzZ48V8XrPvXF2wRaH15tmzEpsHT"` - Level int64 `json:"level" example:"100"` - Predecessor string `json:"predecessor" example:"BMWVEwEYw9m5iaHzqxDfkPzZTV4rhkSouRh3DkVMVGkxZ3EVaNs"` - ChainID string `json:"chain_id" example:"NetXdQprcVkpaWU"` - Timestamp time.Time `json:"timestamp" example:"2018-06-30T18:05:27Z"` - Protocol string `json:"protocol" example:"PtCJ7pwoxe8JasnHY8YonnLYjcVHmhiARPJvqcC6VfHT5s8k8sY"` - CostPerByte int64 `json:"cost_per_byte" example:"250"` - HardGasLimitPerOperation int64 `json:"hard_gas_limit_per_operation" example:"1040000"` - HardStorageLimitPerOperation int64 `json:"hard_storage_limit_per_operation" example:"60000"` - TimeBetweenBlocks int64 `json:"time_between_blocks" example:"30"` + Network string `example:"mainnet" json:"network"` + Hash string `example:"BLyAEwaXShJuZasvUezHUfLqzZ48V8XrPvXF2wRaH15tmzEpsHT" json:"hash"` + Level int64 `example:"100" json:"level"` + Predecessor string `example:"BMWVEwEYw9m5iaHzqxDfkPzZTV4rhkSouRh3DkVMVGkxZ3EVaNs" json:"predecessor"` + ChainID string `example:"NetXdQprcVkpaWU" json:"chain_id"` + Timestamp time.Time `example:"2018-06-30T18:05:27Z" json:"timestamp"` + Protocol string `example:"PtCJ7pwoxe8JasnHY8YonnLYjcVHmhiARPJvqcC6VfHT5s8k8sY" json:"protocol"` + CostPerByte int64 `example:"250" json:"cost_per_byte"` + HardGasLimitPerOperation int64 `example:"1040000" json:"hard_gas_limit_per_operation"` + HardStorageLimitPerOperation int64 `example:"60000" json:"hard_storage_limit_per_operation"` + TimeBetweenBlocks int64 `example:"30" json:"time_between_blocks"` + + Stats *Stats `json:"stats,omitempty"` } // FromModel - @@ -445,10 +373,42 @@ func (b *Block) FromModel(block block.Block) { b.Protocol = block.Protocol.Hash b.ChainID = block.Protocol.ChainID b.Timestamp = block.Timestamp - b.CostPerByte = block.Protocol.CostPerByte - b.HardGasLimitPerOperation = block.Protocol.HardGasLimitPerOperation - b.HardStorageLimitPerOperation = block.Protocol.HardStorageLimitPerOperation - b.TimeBetweenBlocks = block.Protocol.TimeBetweenBlocks + if block.Protocol.Constants != nil { + b.CostPerByte = block.Protocol.CostPerByte + b.HardGasLimitPerOperation = block.Protocol.HardGasLimitPerOperation + b.HardStorageLimitPerOperation = block.Protocol.HardStorageLimitPerOperation + b.TimeBetweenBlocks = block.Protocol.TimeBetweenBlocks + } +} + +type Stats struct { + ContractsCount int `json:"contracts_count"` + SmartRollupsCount int `json:"smart_rollups_count"` + GlobalConstantsCount int `json:"global_constants_count"` + OperationsCount int `json:"operations_count"` + EventsCount int `json:"events_count"` + TransactionsCount int `json:"tx_count"` + OriginationsCount int `json:"originations_count"` + SrOriginationsCount int `json:"sr_originations_count"` + SrExecutesCount int `json:"sr_executes_count"` + RegisterGlobalConstantCount int `json:"register_global_constants_count"` + TransferTicketsCount int `json:"transfer_tickets_count"` +} + +func NewStats(s stats.Stats) *Stats { + return &Stats{ + ContractsCount: s.ContractsCount, + SmartRollupsCount: s.SmartRollupsCount, + GlobalConstantsCount: s.GlobalConstantsCount, + OperationsCount: s.OperationsCount, + EventsCount: s.EventsCount, + TransactionsCount: s.TransactionsCount, + OriginationsCount: s.OriginationsCount, + SrOriginationsCount: s.SrOriginationsCount, + SrExecutesCount: s.SrExecutesCount, + RegisterGlobalConstantCount: s.RegisterGlobalConstantCount, + TransferTicketsCount: s.TransferTicketsCount, + } } // SameContractsResponse - @@ -467,14 +427,14 @@ type SeriesFloat [][]float64 type BigMapHistoryResponse struct { Address string `json:"address"` Ptr int64 `json:"ptr"` - Items []BigMapHistoryItem `json:"items,omitempty" extensions:"x-nullable"` + Items []BigMapHistoryItem `extensions:"x-nullable" json:"items,omitempty"` } // BigMapHistoryItem - type BigMapHistoryItem struct { Action string `json:"action"` - SourcePtr *int64 `json:"source_ptr,omitempty" extensions:"x-nullable"` - DestinationPtr *int64 `json:"destination_ptr,omitempty" extensions:"x-nullable"` + SourcePtr *int64 `extensions:"x-nullable" json:"source_ptr,omitempty"` + DestinationPtr *int64 `extensions:"x-nullable" json:"destination_ptr,omitempty"` Timestamp time.Time `json:"timestamp"` Level int64 `json:"level"` } @@ -498,12 +458,14 @@ type Screenshot struct { // AccountInfo - type AccountInfo struct { - Address string `json:"address"` - Alias string `json:"alias,omitempty" extensions:"x-nullable"` - Balance int64 `json:"balance"` - TxCount int64 `json:"tx_count"` - LastAction time.Time `json:"last_action"` - AccountType string `json:"account_type"` + Address string `json:"address"` + Balance int64 `json:"balance"` + OperationsCount int64 `json:"operations_count"` + MigrationsCount int64 `json:"migrations_count"` + EventsCount int64 `json:"events_count"` + TicketUpdatesCount int64 `json:"ticket_updates_count"` + LastAction time.Time `json:"last_action"` + AccountType string `json:"account_type"` } // CountResponse - @@ -523,7 +485,7 @@ type ViewSchema struct { Implementation int `json:"implementation"` Description string `json:"description,omitempty"` Schema *ast.JSONSchema `json:"schema"` - DefaultModel interface{} `json:"default_model,omitempty" extensions:"x-nullable"` + DefaultModel interface{} `extensions:"x-nullable" json:"default_model,omitempty"` Error string `json:"error,omitempty"` Kind ViewSchemaKind `json:"kind"` } @@ -594,9 +556,9 @@ type CodeFromMichelsonResponse struct { // CodeFromMichelsonStorage - type CodeFromMichelsonStorage struct { - Type []ast.Typedef `json:"type,omitempty" extensions:"x-nullable"` + Type []ast.Typedef `extensions:"x-nullable" json:"type,omitempty"` Schema *ast.JSONSchema `json:"schema"` - DefaultModel ast.JSONModel `json:"default_model,omitempty" extensions:"x-nullable"` + DefaultModel ast.JSONModel `extensions:"x-nullable" json:"default_model,omitempty"` } // OPGResponse - @@ -644,7 +606,7 @@ type Event struct { Timestamp time.Time `json:"timestamp"` Level int64 `json:"level"` Tag string `json:"tag"` - Payload []*ast.MiguelNode `json:"payload,omitempty" extensions:"x-nullable"` + Payload []*ast.MiguelNode `extensions:"x-nullable" json:"payload,omitempty"` } // NewEvent - @@ -686,6 +648,7 @@ type TicketUpdate struct { ID int64 `json:"id"` Level int64 `json:"level"` Timestamp time.Time `json:"timestamp"` + TicketId int64 `json:"ticket_id"` Ticketer string `json:"ticketer"` Address string `json:"address"` Amount string `json:"amount"` @@ -700,7 +663,8 @@ func NewTicketUpdateFromModel(update ticket.TicketUpdate) TicketUpdate { ID: update.ID, Timestamp: update.Timestamp.UTC(), Level: update.Level, - Ticketer: update.Ticketer.Address, + TicketId: update.TicketId, + Ticketer: update.Ticket.Ticketer.Address, Address: update.Account.Address, Amount: update.Amount.String(), } @@ -733,3 +697,74 @@ func NewSmartRollup(rollup smartrollup.SmartRollup) SmartRollup { Kernel: kernel, } } + +type TicketBalance struct { + Ticketer string `json:"ticketer"` + Amount string `json:"amount"` + ContentType []ast.Typedef `json:"content_type"` + Content *ast.MiguelNode `json:"content,omitempty"` + TicketId int64 `json:"ticket_id"` +} + +func NewTicketBalance(balance ticket.Balance) TicketBalance { + return TicketBalance{ + Ticketer: balance.Ticket.Ticketer.Address, + Amount: balance.Amount.String(), + TicketId: balance.TicketId, + } +} + +type Ticket struct { + Ticketer string `json:"ticketer"` + ContentType []ast.Typedef `json:"content_type"` + Content *ast.MiguelNode `json:"content,omitempty"` + UpdatesCount int `json:"updates_count"` + Level int64 `json:"first_level"` +} + +func NewTicket(t ticket.Ticket) (Ticket, error) { + result := Ticket{ + Ticketer: t.Ticketer.Address, + UpdatesCount: t.UpdatesCount, + Level: t.Level, + } + + content, err := ast.NewTypedAstFromBytes(t.ContentType) + if err != nil { + return result, err + } + docs, err := content.Docs("") + if err != nil { + return result, err + } + result.ContentType = docs + + if err := content.SettleFromBytes(t.Content); err != nil { + return result, err + } + contentMiguel, err := content.ToMiguel() + if err != nil { + return result, err + } + if len(contentMiguel) > 0 { + result.Content = contentMiguel[0] + } + + return result, nil +} + +type GlobalConstantItem struct { + Timestamp time.Time `json:"timestamp"` + Level int64 `json:"level"` + Address string `json:"address"` + LinksCount uint64 `json:"links_count"` +} + +func NewGlobalConstantItem(item contract.ListGlobalConstantItem) GlobalConstantItem { + return GlobalConstantItem{ + Timestamp: item.Timestamp, + Level: item.Level, + Address: item.Address, + LinksCount: item.LinksCount, + } +} diff --git a/cmd/api/handlers/run_code.go b/cmd/api/handlers/run_code.go index 74a15aee1..3d550e959 100644 --- a/cmd/api/handlers/run_code.go +++ b/cmd/api/handlers/run_code.go @@ -1,6 +1,7 @@ package handlers import ( + "context" "net/http" "time" @@ -13,9 +14,9 @@ import ( "github.com/baking-bad/bcdhub/internal/models/protocol" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" + "github.com/baking-bad/bcdhub/internal/parsers" "github.com/baking-bad/bcdhub/internal/parsers/operations" "github.com/baking-bad/bcdhub/internal/parsers/protocols" - "github.com/baking-bad/bcdhub/internal/postgres" "github.com/gin-gonic/gin" "github.com/pkg/errors" ) @@ -34,16 +35,16 @@ func RunOperation() gin.HandlerFunc { return } - state, err := ctx.Blocks.Last() + state, err := ctx.Blocks.Last(c.Request.Context()) if handleError(c, ctx.Storage, err, 0) { return } - predecessor, err := ctx.Blocks.Get(state.Level - 1) + predecessor, err := ctx.Blocks.Get(c.Request.Context(), state.Level-1) if handleError(c, ctx.Storage, err, 0) { return } - parameters, err := buildParametersForExecution(ctx, req.Address, state.Protocol.SymLink, reqRunOp.Name, reqRunOp.Data) + parameters, err := buildParametersForExecution(c.Request.Context(), ctx, req.Address, state.Protocol.SymLink, reqRunOp.Name, reqRunOp.Data) if handleError(c, ctx.Storage, err, 0) { return } @@ -85,6 +86,7 @@ func RunOperation() gin.HandlerFunc { } parserParams, err := operations.NewParseParams( + c.Request.Context(), ctx, operations.WithProtocol(&state.Protocol), operations.WithHead(header), @@ -94,19 +96,15 @@ func RunOperation() gin.HandlerFunc { } parser := operations.NewGroup(parserParams) - store := postgres.NewStore(ctx.StorageDB.DB, ctx.Partitions) - if err := parser.Parse(response, store); handleError(c, ctx.Storage, err, 0) { + store := parsers.NewTestStore() + if err := parser.Parse(c.Request.Context(), response, store); handleError(c, ctx.Storage, err, 0) { return } operations := store.ListOperations() resp := make([]Operation, len(operations)) for i := range operations { - bmd := make([]bigmapdiff.BigMapDiff, 0) - for j := range operations[i].BigMapDiffs { - bmd = append(bmd, *operations[i].BigMapDiffs[j]) - } - op, err := prepareOperation(ctx, *operations[i], bmd, true) + op, err := prepareOperation(c.Request.Context(), ctx, *operations[i], true) if handleError(c, ctx.Storage, err, 0) { return } @@ -145,17 +143,17 @@ func RunCode() gin.HandlerFunc { return } - state, err := ctx.Blocks.Last() + state, err := ctx.Blocks.Last(c.Request.Context()) if handleError(c, ctx.Storage, err, 0) { return } - scriptBytes, err := getScriptBytes(ctx.Contracts, req.Address, state.Protocol.SymLink) + scriptBytes, err := getScriptBytes(c.Request.Context(), ctx.Cache, req.Address, state.Protocol.SymLink) if handleError(c, ctx.Storage, err, 0) { return } - input, err := buildParametersForExecution(ctx, req.Address, state.Protocol.SymLink, reqRunCode.Name, reqRunCode.Data) + input, err := buildParametersForExecution(c.Request.Context(), ctx, req.Address, state.Protocol.SymLink, reqRunCode.Name, reqRunCode.Data) if handleError(c, ctx.Storage, err, 0) { return } @@ -226,7 +224,7 @@ func RunCode() gin.HandlerFunc { } } -func parseAppliedRunCode(c *gin.Context, ctx *config.Context, response noderpc.RunCodeResponse, script *ast.Script, main *Operation, proto protocol.Protocol) ([]Operation, error) { +func parseAppliedRunCode(c context.Context, ctx *config.Context, response noderpc.RunCodeResponse, script *ast.Script, main *Operation, proto protocol.Protocol) ([]Operation, error) { operations := []Operation{*main} for i := range response.Operations { @@ -248,7 +246,7 @@ func parseAppliedRunCode(c *gin.Context, ctx *config.Context, response noderpc.R s = script } else { var err error - s, err = getScript(ctx.Contracts, op.Destination, proto.SymLink) + s, err = getScript(c, ctx.Cache, op.Destination, proto.SymLink) if err != nil { return nil, err } @@ -275,7 +273,7 @@ func parseAppliedRunCode(c *gin.Context, ctx *config.Context, response noderpc.R return operations, nil } -func parseBigMapDiffs(c *gin.Context, ctx *config.Context, response noderpc.RunCodeResponse, script *ast.Script, operation *Operation, proto protocol.Protocol) ([]bigmapdiff.BigMapDiff, error) { +func parseBigMapDiffs(c context.Context, ctx *config.Context, response noderpc.RunCodeResponse, script *ast.Script, operation *Operation, proto protocol.Protocol) ([]bigmapdiff.BigMapDiff, error) { model := operation.ToModel() model.AST = script @@ -304,12 +302,12 @@ func parseBigMapDiffs(c *gin.Context, ctx *config.Context, response noderpc.RunC }, } - store := postgres.NewStore(ctx.StorageDB.DB, ctx.Partitions) + store := parsers.NewTestStore() switch operation.Kind { case types.OperationKindTransaction.String(): - err = specific.StorageParser.ParseTransaction(nodeOperation, &model, store) + err = specific.StorageParser.ParseTransaction(c, nodeOperation, &model, store) case types.OperationKindOrigination.String(), types.OperationKindOriginationNew.String(): - err = specific.StorageParser.ParseOrigination(nodeOperation, &model, store) + err = specific.StorageParser.ParseOrigination(c, nodeOperation, &model, store) } if err != nil { return nil, err @@ -321,7 +319,7 @@ func parseBigMapDiffs(c *gin.Context, ctx *config.Context, response noderpc.RunC return bmd, nil } -func setSimulateStorageDiff(c *gin.Context, ctx *config.Context, response noderpc.RunCodeResponse, proto protocol.Protocol, script *ast.Script, operation *Operation) error { +func setSimulateStorageDiff(c context.Context, ctx *config.Context, response noderpc.RunCodeResponse, proto protocol.Protocol, script *ast.Script, operation *Operation) error { if len(response.Storage) == 0 || !bcd.IsContract(operation.Destination) || operation.Status != consts.Applied { return nil } @@ -334,12 +332,12 @@ func setSimulateStorageDiff(c *gin.Context, ctx *config.Context, response noderp return err } - destination, err := ctx.Accounts.Get(operation.Destination) + destination, err := ctx.Accounts.Get(c, operation.Destination) if err != nil { return err } - storageDiff, err := getStorageDiff(ctx, destination.ID, bmd, operation.Storage, storageType, operation) + storageDiff, err := getStorageDiff(c, ctx, destination.ID, bmd, operation.Storage, storageType, operation) if err != nil { return err } diff --git a/cmd/api/handlers/script.go b/cmd/api/handlers/script.go index c77827610..661d6a882 100644 --- a/cmd/api/handlers/script.go +++ b/cmd/api/handlers/script.go @@ -1,46 +1,49 @@ package handlers import ( + "context" + "github.com/baking-bad/bcdhub/internal/bcd/ast" "github.com/baking-bad/bcdhub/internal/bcd/consts" + "github.com/baking-bad/bcdhub/internal/cache" "github.com/baking-bad/bcdhub/internal/models/block" "github.com/baking-bad/bcdhub/internal/models/contract" ) -func getScript(contracts contract.Repository, address, symLink string) (*ast.Script, error) { - data, err := getScriptBytes(contracts, address, symLink) +func getScript(ctx context.Context, cache *cache.Cache, address, symLink string) (*ast.Script, error) { + data, err := getScriptBytes(ctx, cache, address, symLink) if err != nil { return nil, err } return ast.NewScriptWithoutCode(data) } -func getScriptBytes(contracts contract.Repository, address, symLink string) ([]byte, error) { - script, err := contracts.Script(address, symLink) +func getScriptBytes(ctx context.Context, cache *cache.Cache, address, symLink string) ([]byte, error) { + script, err := cache.Script(ctx, address, symLink) if err != nil { return nil, err } return script.Full() } -func getParameterType(contracts contract.Repository, address, symLink string) (*ast.TypedAst, error) { - return getScriptPart(contracts, address, symLink, consts.PARAMETER) +func getParameterType(ctx context.Context, contracts contract.Repository, address, symLink string) (*ast.TypedAst, error) { + return getScriptPart(ctx, contracts, address, symLink, consts.PARAMETER) } -func getStorageType(contracts contract.Repository, address, symLink string) (*ast.TypedAst, error) { - return getScriptPart(contracts, address, symLink, consts.STORAGE) +func getStorageType(ctx context.Context, contracts contract.Repository, address, symLink string) (*ast.TypedAst, error) { + return getScriptPart(ctx, contracts, address, symLink, consts.STORAGE) } -func getScriptPart(contracts contract.Repository, address, symLink, part string) (*ast.TypedAst, error) { - data, err := contracts.ScriptPart(address, symLink, part) +func getScriptPart(ctx context.Context, contracts contract.Repository, address, symLink, part string) (*ast.TypedAst, error) { + data, err := contracts.ScriptPart(ctx, address, symLink, part) if err != nil { return nil, err } return ast.NewTypedAstFromBytes(data) } -func getCurrentSymLink(blocks block.Repository) (string, error) { - block, err := blocks.Last() +func getCurrentSymLink(ctx context.Context, blocks block.Repository) (string, error) { + block, err := blocks.Last(ctx) if err != nil { return "", nil } diff --git a/cmd/api/handlers/smart_rollup.go b/cmd/api/handlers/smart_rollup.go index 7495ee29f..6749d6960 100644 --- a/cmd/api/handlers/smart_rollup.go +++ b/cmd/api/handlers/smart_rollup.go @@ -31,7 +31,7 @@ func GetSmartRollup() gin.HandlerFunc { return } - rollup, err := ctx.SmartRollups.Get(req.Address) + rollup, err := ctx.SmartRollups.Get(c.Request.Context(), req.Address) if handleError(c, ctx.Storage, err, 0) { return } @@ -75,7 +75,7 @@ func ListSmartRollups() gin.HandlerFunc { return } - rollups, err := ctx.SmartRollups.List(args.Size, args.Offset, args.Sort) + rollups, err := ctx.SmartRollups.List(c.Request.Context(), args.Size, args.Offset, args.Sort) if handleError(c, ctx.Storage, err, 0) { return } diff --git a/cmd/api/handlers/stats.go b/cmd/api/handlers/stats.go index 253a736e1..b63515cc1 100644 --- a/cmd/api/handlers/stats.go +++ b/cmd/api/handlers/stats.go @@ -32,7 +32,7 @@ func GetStats() gin.HandlerFunc { blocks := make([]Block, 0) for _, network := range networks { - last, err := ctxs[network].Blocks.Last() + last, err := ctxs[network].Blocks.Last(c.Request.Context()) if err != nil { if ctxs[network].Storage.IsRecordNotFound(err) { continue @@ -42,12 +42,21 @@ func GetStats() gin.HandlerFunc { } var block Block block.FromModel(last) - predecessor, err := ctxs[network].Blocks.Get(last.Level) - if handleError(c, ctxs[network].Storage, err, 0) { + predecessor, err := ctxs[network].Blocks.Get(c.Request.Context(), last.Level) + if err != nil && !ctxs[network].Storage.IsRecordNotFound(err) { + handleError(c, ctxs[network].Storage, err, 0) return } block.Network = network.String() block.Predecessor = predecessor.Hash + + stats, err := ctxs[network].Stats.Get(c.Request.Context()) + if err != nil && !ctxs[network].Storage.IsRecordNotFound(err) { + handleError(c, ctxs[network].Storage, err, 0) + return + } + block.Stats = NewStats(stats) + blocks = append(blocks, block) } @@ -86,7 +95,7 @@ func RecentlyCalledContracts() gin.HandlerFunc { page.Size = 10 } - contracts, err := ctx.Contracts.RecentlyCalled(page.Offset, page.Size) + contracts, err := ctx.Accounts.RecentlyCalledContracts(c.Request.Context(), page.Offset, page.Size) if handleError(c, ctx.Storage, err, 0) { return } @@ -117,10 +126,10 @@ func RecentlyCalledContracts() gin.HandlerFunc { func ContractsCount() gin.HandlerFunc { return func(c *gin.Context) { ctx := c.MustGet("context").(*config.Context) - count, err := ctx.Contracts.Count() + stats, err := ctx.Stats.Get(c.Request.Context()) if handleError(c, ctx.Storage, err, 0) { return } - c.SecureJSON(http.StatusOK, count) + c.SecureJSON(http.StatusOK, stats.ContractsCount) } } diff --git a/cmd/api/handlers/storage.go b/cmd/api/handlers/storage.go index 3ed94897d..8d5375fa6 100644 --- a/cmd/api/handlers/storage.go +++ b/cmd/api/handlers/storage.go @@ -1,6 +1,7 @@ package handlers import ( + "context" "net/http" "github.com/baking-bad/bcdhub/internal/bcd" @@ -45,12 +46,12 @@ func GetContractStorage() gin.HandlerFunc { var header block.Block var err error if sReq.Level == 0 { - header, err = ctx.Blocks.Last() + header, err = ctx.Blocks.Last(c.Request.Context()) if handleError(c, ctx.Storage, err, 0) { return } } else { - header, err = ctx.Blocks.Get(int64(sReq.Level)) + header, err = ctx.Blocks.Get(c.Request.Context(), int64(sReq.Level)) if handleError(c, ctx.Storage, err, 0) { return } @@ -60,7 +61,7 @@ func GetContractStorage() gin.HandlerFunc { if handleError(c, ctx.Storage, err, 0) { return } - storageType, err := getStorageType(ctx.Contracts, req.Address, header.Protocol.SymLink) + storageType, err := getStorageType(c.Request.Context(), ctx.Contracts, req.Address, header.Protocol.SymLink) if handleError(c, ctx.Storage, err, 0) { return } @@ -155,17 +156,17 @@ func GetContractStorageRich() gin.HandlerFunc { return } - block, err := ctx.Blocks.Get(int64(sReq.Level)) + block, err := ctx.Blocks.Get(c.Request.Context(), int64(sReq.Level)) if handleError(c, ctx.Storage, err, 0) { return } - storageType, err := getStorageType(ctx.Contracts, req.Address, block.Protocol.SymLink) + storageType, err := getStorageType(c.Request.Context(), ctx.Contracts, req.Address, block.Protocol.SymLink) if handleError(c, ctx.Storage, err, 0) { return } - states, err := ctx.BigMapDiffs.GetForAddress(req.Address) + states, err := ctx.BigMapDiffs.GetForAddress(c.Request.Context(), req.Address) if handleError(c, ctx.Storage, err, 0) { return } @@ -215,12 +216,12 @@ func GetContractStorageSchema() gin.HandlerFunc { return } - symLink, err := getCurrentSymLink(ctx.Blocks) + symLink, err := getCurrentSymLink(c.Request.Context(), ctx.Blocks) if handleError(c, ctx.Storage, err, 0) { return } - storageType, err := getStorageType(ctx.Contracts, req.Address, symLink) + storageType, err := getStorageType(c.Request.Context(), ctx.Contracts, req.Address, symLink) if handleError(c, ctx.Storage, err, 0) { return } @@ -258,7 +259,7 @@ func GetContractStorageSchema() gin.HandlerFunc { return } - bmd, err := ctx.BigMapDiffs.GetForOperation(operation.ID) + bmd, err := ctx.BigMapDiffs.GetForOperation(c.Request.Context(), operation.ID) if handleError(c, ctx.Storage, err, 0) { return } @@ -276,8 +277,8 @@ func GetContractStorageSchema() gin.HandlerFunc { } } -func getDeffattedStorage(c *gin.Context, ctx *config.Context, address string, level int64) ([]byte, error) { - destination, err := ctx.Accounts.Get(address) +func getDeffattedStorage(c context.Context, ctx *config.Context, address string, level int64) ([]byte, error) { + destination, err := ctx.Accounts.Get(c, address) if err != nil { return nil, err } @@ -289,14 +290,14 @@ func getDeffattedStorage(c *gin.Context, ctx *config.Context, address string, le if level > 0 { filters["level"] = level } - operation, err := ctx.Operations.Last(filters, 0) + operation, err := ctx.Operations.Last(c, filters, 0) switch { case err != nil && !ctx.Storage.IsRecordNotFound(err): return nil, err case len(operation.DeffatedStorage) == 0 || ctx.Storage.IsRecordNotFound(err): return ctx.RPC.GetScriptStorageRaw(c, address, level) default: - protocol, err := ctx.Cache.ProtocolByID(operation.ProtocolID) + protocol, err := ctx.Cache.ProtocolByID(c, operation.ProtocolID) if err != nil { return nil, err } @@ -314,12 +315,12 @@ func getDeffattedStorage(c *gin.Context, ctx *config.Context, address string, le } } -func getInitialOperation(c *gin.Context, ctx *config.Context, address string) (operation.Operation, error) { - destination, err := ctx.Accounts.Get(address) +func getInitialOperation(c context.Context, ctx *config.Context, address string) (operation.Operation, error) { + destination, err := ctx.Accounts.Get(c, address) if err != nil { return operation.Operation{}, err } - return ctx.Operations.Origination(destination.ID) + return ctx.Operations.Origination(c, destination.ID) } diff --git a/cmd/api/handlers/tickets.go b/cmd/api/handlers/tickets.go index 2bcea2963..3ad36f2de 100644 --- a/cmd/api/handlers/tickets.go +++ b/cmd/api/handlers/tickets.go @@ -1,9 +1,9 @@ package handlers import ( + "context" "net/http" - "github.com/baking-bad/bcdhub/internal/bcd/ast" "github.com/baking-bad/bcdhub/internal/bcd/encoding" "github.com/baking-bad/bcdhub/internal/config" "github.com/baking-bad/bcdhub/internal/models/ticket" @@ -15,18 +15,71 @@ import ( // @Description Get ticket updates for contract // @Tags contract // @ID get-contract-ticket-updates +// @Param network path string true "network" +// @Param address path string true "KT address" minlength(36) maxlength(36) +// @Param account query string false "Address" minlength(36) maxlength(36) +// @Param ticket_id query integer false "Ticket id" mininum(0) +// @Param size query integer false "Updates count" mininum(1) maximum(10) +// @Param offset query integer false "Offset" mininum(1) +// @Accept json +// @Produce json +// @Success 200 {array} TicketUpdate +// @Failure 400 {object} Error +// @Failure 404 {object} Error +// @Failure 500 {object} Error +// @Router /v1/contract/{network}/{address}/ticket_updates [get] +func GetContractTicketUpdates() gin.HandlerFunc { + return func(c *gin.Context) { + ctx := c.MustGet("context").(*config.Context) + + var req getContractRequest + if err := c.BindUri(&req); handleError(c, ctx.Storage, err, http.StatusBadRequest) { + return + } + + var args ticketUpdatesRequest + if err := c.BindQuery(&args); handleError(c, ctx.Storage, err, http.StatusBadRequest) { + return + } + + updates, err := ctx.Tickets.Updates(c.Request.Context(), + ticket.UpdatesRequest{ + Ticketer: req.Address, + Account: args.Account, + TicketId: args.TicketId, + Limit: args.Size, + Offset: args.Offset, + }, + ) + + if handleError(c, ctx.Storage, err, 0) { + return + } + response, err := prepareTicketUpdates(c.Request.Context(), ctx, updates, nil) + if handleError(c, ctx.Storage, err, 0) { + return + } + c.SecureJSON(http.StatusOK, response) + } +} + +// GetContractTickets godoc +// @Summary Get tickets for contract +// @Description Get tickets for contract +// @Tags contract +// @ID get-contract-tickets // @Param network path string true "network" // @Param address path string true "KT address" minlength(36) maxlength(36) // @Param size query integer false "Updates count" mininum(1) maximum(10) // @Param offset query integer false "Offset" mininum(1) // @Accept json // @Produce json -// @Success 200 {array} GlobalConstant +// @Success 200 {array} Ticket // @Failure 400 {object} Error // @Failure 404 {object} Error // @Failure 500 {object} Error -// @Router /v1/contract/{network}/{address}/ticket_updates [get] -func GetContractTicketUpdates() gin.HandlerFunc { +// @Router /v1/contract/{network}/{address}/tickets [get] +func GetContractTickets() gin.HandlerFunc { return func(c *gin.Context) { ctx := c.MustGet("context").(*config.Context) @@ -40,11 +93,11 @@ func GetContractTicketUpdates() gin.HandlerFunc { return } - updates, err := ctx.TicketUpdates.Get(req.Address, args.Size, args.Offset) + tickets, err := ctx.Tickets.List(c.Request.Context(), req.Address, args.Size, args.Offset) if handleError(c, ctx.Storage, err, 0) { return } - response, err := prepareTicketUpdates(ctx, updates, nil) + response, err := prepareTickets(tickets) if handleError(c, ctx.Storage, err, 0) { return } @@ -62,15 +115,15 @@ func GetTicketUpdatesForOperation() gin.HandlerFunc { if err := c.BindUri(&req); handleError(c, ctx.Storage, err, http.StatusBadRequest) { return } - operation, err := ctx.Operations.GetByID(req.ID) + operation, err := ctx.Operations.GetByID(c.Request.Context(), req.ID) if handleError(c, ctx.Storage, err, 0) { return } - updates, err := ctx.TicketUpdates.ForOperation(req.ID) + updates, err := ctx.Tickets.UpdatesForOperation(c.Request.Context(), req.ID) if handleError(c, ctx.Storage, err, 0) { return } - response, err := prepareTicketUpdates(ctx, updates, operation.Hash) + response, err := prepareTicketUpdates(c.Request.Context(), ctx, updates, operation.Hash) if handleError(c, ctx.Storage, err, 0) { return } @@ -78,34 +131,58 @@ func GetTicketUpdatesForOperation() gin.HandlerFunc { } } -func prepareTicketUpdates(ctx *config.Context, updates []ticket.TicketUpdate, hash []byte) ([]TicketUpdate, error) { - response := make([]TicketUpdate, 0, len(updates)) - for i := range updates { - update := NewTicketUpdateFromModel(updates[i]) +// GetTicketBalancesForAccount - +// @Router /v1/account/{network}/{address}/ticket_balances [get] +func GetTicketBalancesForAccount() gin.HandlerFunc { + return func(c *gin.Context) { + ctx := c.MustGet("context").(*config.Context) - content, err := ast.NewTypedAstFromBytes(updates[i].ContentType) - if err != nil { - return nil, err + var req getAccountRequest + if err := c.BindUri(&req); err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, Error{Message: err.Error()}) + return } - docs, err := content.Docs("") - if err != nil { - return nil, err + + var args ticketBalancesRequest + if err := c.BindQuery(&args); err != nil { + c.AbortWithStatusJSON(http.StatusBadRequest, Error{Message: err.Error()}) + return } - update.ContentType = docs - if err := content.SettleFromBytes(updates[i].Content); err != nil { - return nil, err + acc, err := ctx.Accounts.Get(c.Request.Context(), req.Address) + if handleError(c, ctx.Storage, err, 0) { + return } - contentMiguel, err := content.ToMiguel() + + balances, err := ctx.Tickets.BalancesForAccount(c.Request.Context(), acc.ID, ticket.BalanceRequest{ + Limit: args.Size, + Offset: args.Offset, + WithoutZeroBalances: args.WithoutZeroBalances, + }) + if handleError(c, ctx.Storage, err, 0) { + return + } + response, err := prepareTicketBalances(balances) + if handleError(c, ctx.Storage, err, 0) { + return + } + c.SecureJSON(http.StatusOK, response) + } +} + +func prepareTicketUpdates(c context.Context, ctx *config.Context, updates []ticket.TicketUpdate, hash []byte) ([]TicketUpdate, error) { + response := make([]TicketUpdate, 0, len(updates)) + for i := range updates { + update := NewTicketUpdateFromModel(updates[i]) + ticket, err := NewTicket(updates[i].Ticket) if err != nil { return nil, err } - if len(contentMiguel) > 0 { - update.Content = contentMiguel[0] - } + update.ContentType = ticket.ContentType + update.Content = ticket.Content if len(hash) == 0 { - operation, err := ctx.Operations.GetByID(updates[i].OperationID) + operation, err := ctx.Operations.GetByID(c, updates[i].OperationId) if err != nil { return nil, err } @@ -120,3 +197,30 @@ func prepareTicketUpdates(ctx *config.Context, updates []ticket.TicketUpdate, ha return response, nil } + +func prepareTicketBalances(balances []ticket.Balance) ([]TicketBalance, error) { + response := make([]TicketBalance, len(balances)) + for i := range balances { + balance := NewTicketBalance(balances[i]) + ticket, err := NewTicket(balances[i].Ticket) + if err != nil { + return nil, err + } + balance.ContentType = ticket.ContentType + balance.Content = ticket.Content + response[i] = balance + } + return response, nil +} + +func prepareTickets(tickets []ticket.Ticket) ([]Ticket, error) { + response := make([]Ticket, len(tickets)) + for i := range tickets { + ticket, err := NewTicket(tickets[i]) + if err != nil { + return nil, err + } + response[i] = ticket + } + return response, nil +} diff --git a/cmd/api/handlers/views.go b/cmd/api/handlers/views.go index 21d5443ca..13327d710 100644 --- a/cmd/api/handlers/views.go +++ b/cmd/api/handlers/views.go @@ -54,7 +54,7 @@ func GetViewsSchema() gin.HandlerFunc { views := make([]ViewSchema, 0) if args.Kind == EmptyView || args.Kind == OnchainView { - onChain, err := getOnChainViewsSchema(ctx.Contracts, ctx.Blocks, req.Address) + onChain, err := getOnChainViewsSchema(c.Request.Context(), ctx.Contracts, ctx.Blocks, req.Address) if err != nil { if !ctx.Storage.IsRecordNotFound(err) { handleError(c, ctx.Storage, err, 0) @@ -129,12 +129,12 @@ func getOffChainViewSchema(view contract.View) *ViewSchema { return nil } -func getOnChainViewsSchema(contracts contract.Repository, blocks block.Repository, address string) ([]ViewSchema, error) { - block, err := blocks.Last() +func getOnChainViewsSchema(ctx context.Context, contracts contract.Repository, blocks block.Repository, address string) ([]ViewSchema, error) { + block, err := blocks.Last(ctx) if err != nil { return nil, err } - rawViews, err := contracts.ScriptPart(address, block.Protocol.SymLink, consts.VIEWS) + rawViews, err := contracts.ScriptPart(ctx, address, block.Protocol.SymLink, consts.VIEWS) if err != nil { return nil, err } @@ -211,12 +211,12 @@ func ExecuteView() gin.HandlerFunc { return } - view, parameters, err := getViewForExecute(ctx.Contracts, ctx.Blocks, req.Address, execView) + view, parameters, err := getViewForExecute(c.Request.Context(), ctx.Contracts, ctx.Blocks, req.Address, execView) if handleError(c, ctx.Storage, err, 0) { return } - state, err := ctx.Blocks.Last() + state, err := ctx.Blocks.Last(c.Request.Context()) if handleError(c, ctx.Storage, err, 0) { return } @@ -267,14 +267,14 @@ func ExecuteView() gin.HandlerFunc { } } -func getViewForExecute(contracts contract.Repository, blocks block.Repository, address string, req executeViewRequest) (views.View, []byte, error) { +func getViewForExecute(ctx context.Context, contracts contract.Repository, blocks block.Repository, address string, req executeViewRequest) (views.View, []byte, error) { switch req.Kind { case OnchainView: - block, err := blocks.Last() + block, err := blocks.Last(ctx) if err != nil { return nil, nil, err } - rawViews, err := contracts.ScriptPart(address, block.Protocol.SymLink, consts.VIEWS) + rawViews, err := contracts.ScriptPart(ctx, address, block.Protocol.SymLink, consts.VIEWS) if err != nil { return nil, nil, err } diff --git a/cmd/api/main.go b/cmd/api/main.go index 05eeb9089..6b28860d8 100644 --- a/cmd/api/main.go +++ b/cmd/api/main.go @@ -3,9 +3,7 @@ package main import ( "context" "errors" - "fmt" "net/http" - "os" "runtime" "time" @@ -19,10 +17,13 @@ import ( "github.com/gin-contrib/cache" "github.com/gin-contrib/cache/persistence" "github.com/gin-contrib/cors" + ginLogger "github.com/gin-contrib/logger" + "github.com/gin-contrib/timeout" "github.com/gin-gonic/gin" "github.com/gin-gonic/gin/binding" "github.com/go-playground/validator/v10" "github.com/grafana/pyroscope-go" + "github.com/rs/zerolog/log" ) type app struct { @@ -41,6 +42,8 @@ func newApp() *app { panic(err) } + logger.New(cfg.LogLevel) + if cfg.API.SentryEnabled { helpers.InitSentry(cfg.Sentry.Debug, cfg.Sentry.Environment, cfg.Sentry.URI) helpers.SetTagSentry("project", cfg.API.ProjectName) @@ -78,7 +81,7 @@ func newApp() *app { } app.Contexts = config.NewContexts(cfg, cfg.API.Networks, - config.WithStorage(cfg.Storage, cfg.API.ProjectName, int64(cfg.API.PageSize), cfg.API.Connections.Open, cfg.API.Connections.Idle, false), + config.WithStorage(cfg.Storage, cfg.API.ProjectName, int64(cfg.API.PageSize)), config.WithRPC(cfg.RPC), config.WithMempool(cfg.Services), config.WithLoadErrorDescriptions(), @@ -90,7 +93,12 @@ func newApp() *app { } func (api *app) makeRouter() { + gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) { + log.Info().Str("method", httpMethod).Str("path", absolutePath).Str("name", handlerName).Msg("endpoint") + } + r := gin.New() + store := persistence.NewInMemoryStore(time.Second * 30) r.MaxMultipartMemory = 4 << 20 // max upload size 4 MiB @@ -111,12 +119,13 @@ func (api *app) makeRouter() { } r.Use(gin.Recovery()) - - if env := os.Getenv(config.EnvironmentVar); env == config.EnvironmentProd { - r.Use(loggerFormat()) - } else { - r.Use(gin.Logger()) - } + r.Use(ginLogger.SetLogger()) + r.Use(timeout.New( + timeout.WithTimeout(30*time.Second), + timeout.WithHandler(func(c *gin.Context) { + c.Next() + }), + )) v1 := r.Group("v1") { @@ -124,7 +133,7 @@ func (api *app) makeRouter() { v1.GET("head", handlers.ContextsMiddleware(api.Contexts), cache.CachePage(store, time.Second*10, handlers.GetHead())) v1.GET("head/:network", handlers.NetworkMiddleware(api.Contexts), cache.CachePage(store, time.Second*10, handlers.GetHeadByNetwork())) - opg := v1.Group("opg/:hash") + opg := v1.Group("/opg/:network/:hash") { opg.GET("", handlers.ContextsMiddleware(api.Contexts), handlers.GetOperation()) opg.GET(":counter", handlers.ContextsMiddleware(api.Contexts), handlers.GetByHashAndCounter()) @@ -178,11 +187,11 @@ func (api *app) makeRouter() { { contract.GET("", handlers.ContextsMiddleware(api.Contexts), handlers.GetContract()) contract.GET("code", handlers.GetContractCode()) - contract.GET("operations", handlers.GetContractOperations()) contract.GET("opg", handlers.GetOperationGroups()) contract.GET("migrations", handlers.GetContractMigrations()) contract.GET("global_constants", handlers.GetContractGlobalConstants()) contract.GET("ticket_updates", handlers.GetContractTicketUpdates()) + contract.GET("tickets", handlers.GetContractTickets()) contract.GET("events", handlers.ListEvents()) storage := contract.Group("storage") @@ -216,6 +225,7 @@ func (api *app) makeRouter() { acc := account.Group(":address") { acc.GET("", handlers.GetInfo()) + acc.GET("ticket_balances", handlers.GetTicketBalancesForAccount()) } } @@ -262,7 +272,7 @@ func (api *app) Run() { if errors.Is(err, http.ErrServerClosed) { return } - logger.Err(err) + log.Err(err).Msg("API running error") helpers.CatchErrorSentry(err) } } @@ -294,20 +304,6 @@ func corsSettings() gin.HandlerFunc { }) } -func loggerFormat() gin.HandlerFunc { - return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string { - return fmt.Sprintf("%15s | %3d | %13v | %-7s %s | %s\n%s", - param.ClientIP, - param.StatusCode, - param.Latency, - param.Method, - param.Path, - param.Request.UserAgent(), - param.ErrorMessage, - ) - }) -} - func (api *app) handleUrlChanged(ctx context.Context, network, url string) error { if value, ok := api.Config.RPC[network]; ok { value.URI = url diff --git a/cmd/indexer/indexer/indexer.go b/cmd/indexer/indexer/indexer.go index fe7629297..abb27ba73 100644 --- a/cmd/indexer/indexer/indexer.go +++ b/cmd/indexer/indexer/indexer.go @@ -6,13 +6,11 @@ import ( "sync" "time" - "github.com/baking-bad/bcdhub/internal/bcd" "github.com/baking-bad/bcdhub/internal/config" "github.com/baking-bad/bcdhub/internal/helpers" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models/block" - "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/protocol" + "github.com/baking-bad/bcdhub/internal/models/stats" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" "github.com/baking-bad/bcdhub/internal/parsers" @@ -21,10 +19,11 @@ import ( "github.com/baking-bad/bcdhub/internal/parsers/protocols" "github.com/baking-bad/bcdhub/internal/postgres" "github.com/baking-bad/bcdhub/internal/postgres/core" + "github.com/baking-bad/bcdhub/internal/postgres/store" "github.com/baking-bad/bcdhub/internal/rollback" "github.com/dipdup-io/workerpool" - "github.com/go-pg/pg/v10" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) var errBcdQuit = errors.New("bcd-quit") @@ -60,10 +59,10 @@ func NewBlockchainIndexer(ctx context.Context, cfg config.Config, network string internalCtx := config.NewContext( networkType, config.WithConfigCopy(cfg), - config.WithStorage(cfg.Storage, "indexer", 10, cfg.Indexer.Connections.Open, cfg.Indexer.Connections.Idle, true), + config.WithStorage(cfg.Storage, "indexer", 10), config.WithRPC(cfg.RPC), ) - logger.Info().Str("network", internalCtx.Network.String()).Msg("Creating indexer object...") + log.Info().Str("network", internalCtx.Network.String()).Msg("Creating indexer object...") bi := &BlockchainIndexer{ Context: internalCtx, @@ -98,14 +97,14 @@ func (bi *BlockchainIndexer) init(ctx context.Context, db *core.Postgres) error return err } - currentState, err := bi.Blocks.Last() + currentState, err := bi.Blocks.Last(ctx) if err != nil { return err } bi.state = currentState - logger.Info().Str("network", bi.Network.String()).Msgf("Current indexer state: %d", currentState.Level) + log.Info().Str("network", bi.Network.String()).Msgf("Current indexer state: %d", currentState.Level) - currentProtocol, err := bi.Protocols.Get("", currentState.Level) + currentProtocol, err := bi.Protocols.Get(ctx, "", currentState.Level) if err != nil { if !bi.Storage.IsRecordNotFound(err) { return err @@ -116,25 +115,38 @@ func (bi *BlockchainIndexer) init(ctx context.Context, db *core.Postgres) error return err } - logger.Info().Str("network", bi.Network.String()).Msgf("Creating new protocol %s starting at %d", header.Protocol, header.Level) - currentProtocol, err = createProtocol(ctx, bi.RPC, header.ChainID, header.Protocol, header.Level) + log.Info(). + Str("network", bi.Network.String()). + Msgf("Creating new protocol %s starting at %d", header.Protocol, header.Level) + + currentProtocol, err = protocols.Create(ctx, bi.RPC, header) if err != nil { return err } - if err := currentProtocol.Save(db.DB); err != nil { + tx, err := core.NewTransaction(ctx, bi.StorageDB.DB) + if err != nil { + return err + } + if err := tx.Protocol(ctx, ¤tProtocol); err != nil { + return err + } + if err := tx.UpdateStats(ctx, stats.Stats{}); err != nil { + return err + } + if err := tx.Commit(); err != nil { return err } } bi.currentProtocol = currentProtocol - logger.Info().Str("network", bi.Network.String()).Msgf("Current network protocol: %s", currentProtocol.Hash) + log.Info().Str("network", bi.Network.String()).Msgf("Current network protocol: %s", currentProtocol.Hash) for { if _, err := bi.Context.RPC.GetLevel(ctx); err == nil { break } - logger.Warning().Str("network", bi.Network.String()).Msg("waiting node rpc...") + log.Warn().Str("network", bi.Network.String()).Msg("waiting node rpc...") time.Sleep(time.Second * 15) } @@ -153,7 +165,7 @@ func (bi *BlockchainIndexer) Start(ctx context.Context) { // First tick if err := bi.process(ctx); err != nil { if !errors.Is(err, errSameLevel) { - logger.Err(err) + log.Err(err).Msg("processing") helpers.LocalCatchErrorSentry(localSentry, err) } } @@ -173,7 +185,7 @@ func (bi *BlockchainIndexer) Start(ctx context.Context) { } continue } - logger.Err(err) + log.Err(err).Msg("processing") helpers.LocalCatchErrorSentry(localSentry, err) } @@ -201,36 +213,38 @@ func (bi *BlockchainIndexer) setUpdateTicker(seconds int) { if bi.updateTicker != nil { bi.updateTicker.Stop() } - logger.Info().Str("network", bi.Network.String()).Msgf("Data will be updated every %.0f seconds", duration.Seconds()) + log.Info().Str("network", bi.Network.String()).Msgf("Data will be updated every %.0f seconds", duration.Seconds()) bi.updateTicker = time.NewTicker(duration) bi.refreshTimer <- struct{}{} } func (bi *BlockchainIndexer) indexBlock(ctx context.Context) { - ticker := time.NewTicker(time.Millisecond) - defer ticker.Stop() - for { select { case <-ctx.Done(): return - case block := <-bi.receiver.Blocks(): - bi.blocks[block.Header.Level] = block + case newBlock := <-bi.receiver.Blocks(): + bi.blocks[newBlock.Header.Level] = newBlock - case <-ticker.C: - if block, ok := bi.blocks[bi.state.Level+1]; ok { + block, ok := bi.blocks[bi.state.Level+1] + for ok { if bi.state.Level > 0 && block.Header.Predecessor != bi.state.Hash { if err := bi.Rollback(ctx); err != nil { - logger.Error().Err(err).Msg("Rollback") + log.Err(err).Msg("rollback") } } else { if err := bi.handleBlock(ctx, block); err != nil { - logger.Error().Err(err).Msg("handleBlock") + log.Err(err). + Str("network", bi.Network.String()). + Int64("block", block.Header.Level). + Stack(). + Msg("handleBlock") } } delete(bi.blocks, block.Header.Level) + block, ok = bi.blocks[bi.state.Level+1] } } } @@ -249,68 +263,121 @@ func (bi *BlockchainIndexer) Index(ctx context.Context, head noderpc.Header) err } } - bi.indicesInit.Do(bi.createIndices) + bi.indicesInit.Do(func() { + if err := bi.createIndices(ctx); err != nil { + log.Err(err).Str("network", bi.Network.String()).Msg("can't create index") + } + }) return nil } func (bi *BlockchainIndexer) handleBlock(ctx context.Context, block *Block) error { start := time.Now() - return bi.StorageDB.DB.RunInTransaction(ctx, - func(tx *pg.Tx) error { - if block.Header.Protocol != bi.currentProtocol.Hash || bi.needVestingMigration(block.Header.Level) { - logger.Info().Str("network", bi.Network.String()).Msgf("New protocol detected: %s -> %s", bi.currentProtocol.Hash, block.Header.Protocol) + if err := bi.doMigration(ctx, block.Header); err != nil { + return errors.Wrap(err, "migration error") + } - if err := bi.migrate(ctx, block.Header, tx); err != nil { - return err - } - } + if err := bi.parseAndSaveBlock(ctx, block); err != nil { + return errors.Wrap(err, "block processing") + } - store := postgres.NewStore(tx, bi.Partitions) - if err := bi.implicitMigration(ctx, block, bi.currentProtocol, store); err != nil { - return err - } + log.Info(). + Str("network", bi.Network.String()). + Int64("processing_time_ms", time.Since(start).Milliseconds()). + Int64("block", block.Header.Level). + Msg("indexed") - if err := bi.getDataFromBlock(block, store); err != nil { - return err - } + return nil +} - if err := store.Save(ctx); err != nil { - return err - } +func (bi *BlockchainIndexer) parseAndSaveBlock(ctx context.Context, block *Block) error { + store := store.NewStore(bi.StorageDB.DB, bi.Stats) + if err := bi.parseImplicitOperations(ctx, block, bi.currentProtocol, store); err != nil { + return err + } - if err := bi.createBlock(block.Header, tx); err != nil { - return err - } + if err := bi.getDataFromBlock(ctx, block, store); err != nil { + return err + } - logger.Info().Str("network", bi.Network.String()).Int64("processing_time_ms", time.Since(start).Milliseconds()).Int64("block", block.Header.Level).Msg("indexed") - return nil - }, - ) + if err := bi.createBlock(ctx, block.Header, store); err != nil { + return err + } + + if err := store.Save(ctx); err != nil { + return err + } + + bi.state = *store.Block + return nil +} + +func (bi *BlockchainIndexer) doMigration(ctx context.Context, header noderpc.Header) error { + if header.Protocol == bi.currentProtocol.Hash && header.Level > 1 { + return nil + } + + log.Info(). + Str("network", bi.Network.String()). + Int64("block", header.Level). + Msgf("New protocol detected: %s -> %s", bi.currentProtocol.Hash, header.Protocol) + + return bi.migrate(ctx, header) +} + +func (bi *BlockchainIndexer) migrate(ctx context.Context, head noderpc.Header) error { + tx, err := core.NewTransaction(ctx, bi.StorageDB.DB) + if err != nil { + return errors.Wrap(err, "create postgres transaction") + } + + migraton := protocols.NewMigration(bi.Network, bi.Context) + newProto, err := migraton.Do(ctx, tx, bi.currentProtocol, head) + if err != nil { + return errors.Wrap(err, "migration.Do") + } + + bi.currentProtocol = newProto + + if err := tx.Commit(); err != nil { + return err + } + + bi.setUpdateTicker(0) + log.Info(). + Str("network", bi.Network.String()). + Msgf("Migration to %s is completed", bi.currentProtocol.Alias) + + return nil } // Rollback - func (bi *BlockchainIndexer) Rollback(ctx context.Context) error { - logger.Warning().Str("network", bi.Network.String()).Msgf("Rollback from %7d", bi.state.Level) + log.Warn().Str("network", bi.Network.String()).Msgf("Rollback from %8d", bi.state.Level) lastLevel, err := bi.getLastRollbackBlock(ctx) if err != nil { return err } - manager := rollback.NewManager(bi.RPC, bi.Storage, bi.Blocks, bi.BigMapDiffs) - if err := manager.Rollback(ctx, bi.StorageDB.DB, bi.Network, bi.state, lastLevel); err != nil { + saver, err := postgres.NewRollback(bi.StorageDB.DB) + if err != nil { + return err + } + manager := rollback.NewManager(bi.Storage, bi.Blocks, saver, bi.Stats) + if err := manager.Rollback(ctx, bi.Network, bi.state, lastLevel); err != nil { return err } - newState, err := bi.Blocks.Last() + newState, err := bi.Blocks.Last(ctx) if err != nil { return err } bi.state = newState - logger.Info().Str("network", bi.Network.String()).Msgf("New indexer state: %7d", bi.state.Level) - logger.Info().Str("network", bi.Network.String()).Msg("Rollback finished") + log.Info().Str("network", bi.Network.String()).Msgf("New indexer state: %8d", bi.state.Level) + log.Info().Str("network", bi.Network.String()).Msg("Rollback finished") return nil } @@ -324,13 +391,13 @@ func (bi *BlockchainIndexer) getLastRollbackBlock(ctx context.Context) (int64, e return 0, err } - block, err := bi.Blocks.Get(level - 1) + block, err := bi.Blocks.Get(ctx, level-1) if err != nil { return 0, err } if block.Hash == headAtLevel.Predecessor { - logger.Warning().Str("network", bi.Network.String()).Msgf("Found equal predecessors at level: %7d", block.Level) + log.Warn().Str("network", bi.Network.String()).Msgf("Found equal predecessors at level: %7d", block.Level) end = true lastLevel = block.Level } @@ -348,7 +415,7 @@ func (bi *BlockchainIndexer) process(ctx context.Context) error { return errors.Errorf("Invalid chain_id: %s (state) != %s (head)", bi.state.Protocol.ChainID, head.ChainID) } - logger.Info().Str("network", bi.Network.String()).Int64("node", head.Level).Int64("indexer", bi.state.Level).Msg("current state") + log.Info().Str("network", bi.Network.String()).Int64("node", head.Level).Int64("indexer", bi.state.Level).Msg("current state") switch { case head.Level > bi.state.Level: @@ -359,7 +426,7 @@ func (bi *BlockchainIndexer) process(ctx context.Context) error { return err } - logger.Info().Str("network", bi.Network.String()).Msg("Synced") + log.Info().Str("network", bi.Network.String()).Msg("Synced") return nil case head.Level < bi.state.Level: return bi.Rollback(ctx) @@ -367,26 +434,23 @@ func (bi *BlockchainIndexer) process(ctx context.Context) error { return errSameLevel } } -func (bi *BlockchainIndexer) createBlock(head noderpc.Header, tx pg.DBI) error { +func (bi *BlockchainIndexer) createBlock(ctx context.Context, head noderpc.Header, store parsers.Store) error { newBlock := block.Block{ Hash: head.Hash, ProtocolID: bi.currentProtocol.ID, Level: head.Level, Timestamp: head.Timestamp, } - if err := newBlock.Save(tx); err != nil { - return err - } - - bi.state = newBlock + store.SetBlock(&newBlock) return nil } -func (bi *BlockchainIndexer) getDataFromBlock(block *Block, store parsers.Store) error { +func (bi *BlockchainIndexer) getDataFromBlock(ctx context.Context, block *Block, store parsers.Store) error { if block.Header.Level <= 1 { return nil } parserParams, err := operations.NewParseParams( + ctx, bi.Context, operations.WithProtocol(&bi.currentProtocol), operations.WithHead(block.Header), @@ -397,69 +461,14 @@ func (bi *BlockchainIndexer) getDataFromBlock(block *Block, store parsers.Store) for i := range block.OPG { parser := operations.NewGroup(parserParams) - if err := parser.Parse(block.OPG[i], store); err != nil { - return err - } - } - - return nil -} - -func (bi *BlockchainIndexer) migrate(ctx context.Context, head noderpc.Header, tx pg.DBI) error { - if bi.currentProtocol.EndLevel == 0 && head.Level > 1 { - logger.Info().Str("network", bi.Network.String()).Msgf("Finalizing the previous protocol: %s", bi.currentProtocol.Alias) - bi.currentProtocol.EndLevel = head.Level - 1 - if err := bi.currentProtocol.Save(bi.StorageDB.DB); err != nil { - return err - } - } - - newProtocol, err := bi.Protocols.Get(head.Protocol, head.Level) - if err != nil { - logger.Info().Str("network", bi.Network.String()).Msgf("Creating new protocol %s starting at %d", head.Protocol, head.Level) - newProtocol, err = createProtocol(ctx, bi.RPC, head.ChainID, head.Protocol, head.Level) - if err != nil { + if err := parser.Parse(ctx, block.OPG[i], store); err != nil { return err } - if err := newProtocol.Save(bi.StorageDB.DB); err != nil { - return err - } - } - - if bi.needVestingMigration(head.Level) { - if err := bi.vestingMigration(ctx, head, tx); err != nil { - return err - } - } else { - if bi.currentProtocol.SymLink == "" { - return errors.Errorf("[%s] Protocol should be initialized", bi.Network) - } - if newProtocol.SymLink != bi.currentProtocol.SymLink { - if err := bi.standartMigration(ctx, newProtocol, head, tx); err != nil { - return err - } - } else { - logger.Info().Str("network", bi.Network.String()).Msgf("Same symlink %s for %s / %s", - newProtocol.SymLink, bi.currentProtocol.Alias, newProtocol.Alias) - } - } - bi.currentProtocol = newProtocol - - bi.setUpdateTicker(0) - logger.Info().Str("network", bi.Network.String()).Msgf("Migration to %s is completed", bi.currentProtocol.Alias) return nil } - -func (bi *BlockchainIndexer) needVestingMigration(level int64) bool { - return (bi.Network == types.Mainnet || - bi.Network == types.Dailynet || - bi.Network == types.Mondaynet) && - level == 1 -} - -func (bi *BlockchainIndexer) implicitMigration(ctx context.Context, block *Block, protocol protocol.Protocol, store parsers.Store) error { +func (bi *BlockchainIndexer) parseImplicitOperations(ctx context.Context, block *Block, protocol protocol.Protocol, store parsers.Store) error { if block == nil || block.Metadata == nil { return nil } @@ -476,123 +485,14 @@ func (bi *BlockchainIndexer) implicitMigration(ctx context.Context, block *Block return implicitParser.Parse(ctx, *block.Metadata, block.Header, store) } -func (bi *BlockchainIndexer) standartMigration(ctx context.Context, newProtocol protocol.Protocol, head noderpc.Header, tx pg.DBI) error { - logger.Info().Str("network", bi.Network.String()).Msg("Try to find migrations...") - - var contracts []contract.Contract - if err := bi.StorageDB.DB.Model((*contract.Contract)(nil)). - Relation("Account"). - Where("tags & 4 = 0"). // except delegator contracts - Select(&contracts); err != nil { - return err - } - logger.Info().Str("network", bi.Network.String()).Msgf("Now %2d contracts are indexed", len(contracts)) - - specific, err := protocols.Get(bi.Context, newProtocol.Hash) - if err != nil { - return err - } - - for i := range contracts { - if !specific.MigrationParser.IsMigratable(contracts[i].Account.Address) && newProtocol.SymLink == bcd.SymLinkJakarta { - if _, err = bi.StorageDB.DB.Model(&contracts[i]). - Set("jakarta_id = babylon_id"). - WherePK(). - Update(&contracts[i]); err != nil { - return err - } - continue - } - - logger.Info().Str("network", bi.Network.String()).Msgf("Migrate %s...", contracts[i].Account.Address) - script, err := bi.RPC.GetScriptJSON(ctx, contracts[i].Account.Address, newProtocol.StartLevel) - if err != nil { - return err - } - - if err := specific.MigrationParser.Parse(script, &contracts[i], bi.currentProtocol, newProtocol, head.Timestamp, tx); err != nil { - return err - } - - switch newProtocol.SymLink { - case bcd.SymLinkBabylon: - if _, err := bi.StorageDB.DB. - Model(&contracts[i]). - Set("babylon_id = ?babylon_id"). - WherePK().Update(&contracts[i]); err != nil { - return err - } - case bcd.SymLinkJakarta: - if _, err := bi.StorageDB.DB. - Model(&contracts[i]). - Set("jakarta_id = ?jakarta_id"). - WherePK().Update(&contracts[i]); err != nil { - return err - } - } - - } - - // only delegator contracts - switch newProtocol.SymLink { - case bcd.SymLinkBabylon: - _, err = bi.StorageDB.DB.Model((*contract.Contract)(nil)). - Set("babylon_id = alpha_id"). - Where("tags & 4 > 0"). - Update() - case bcd.SymLinkJakarta: - _, err = bi.StorageDB.DB.Model((*contract.Contract)(nil)). - Set("jakarta_id = babylon_id"). - Where("tags & 4 > 0"). - Update() - } - return err -} - -func (bi *BlockchainIndexer) vestingMigration(ctx context.Context, head noderpc.Header, tx pg.DBI) error { - addresses, err := bi.RPC.GetContractsByBlock(ctx, head.Level) - if err != nil { - return err - } - - specific, err := protocols.Get(bi.Context, bi.currentProtocol.Hash) - if err != nil { - return err - } - - p, err := migrations.NewVestingParser(bi.Context, specific.ContractParser, bi.currentProtocol) - if err != nil { - return err - } - - store := postgres.NewStore(tx, bi.Partitions) - - for _, address := range addresses { - if !bcd.IsContract(address) { - continue - } - - data, err := bi.RPC.GetContractData(ctx, address, head.Level) - if err != nil { - return err - } - - if err := p.Parse(data, head, address, store); err != nil { - return err - } - } - - return store.Save(ctx) -} - func (bi *BlockchainIndexer) reinit(ctx context.Context, cfg config.Config, indexerConfig config.IndexerConfig) error { bi.Context = config.NewContext( bi.Network, config.WithConfigCopy(cfg), - config.WithStorage(cfg.Storage, "indexer", 10, cfg.Indexer.Connections.Open, cfg.Indexer.Connections.Idle, true), + config.WithStorage(cfg.Storage, "indexer", 10), config.WithRPC(cfg.RPC), ) - logger.Info().Str("network", bi.Context.Network.String()).Msg("Creating indexer object...") + log.Info().Str("network", bi.Context.Network.String()).Msg("Creating indexer object...") bi.receiver = NewReceiver(bi.Context.RPC, 20, indexerConfig.ReceiverThreads) bi.refreshTimer = make(chan struct{}, 10) diff --git a/cmd/indexer/indexer/indices.go b/cmd/indexer/indexer/indices.go index 7e836f90a..74875cc9d 100644 --- a/cmd/indexer/indexer/indices.go +++ b/cmd/indexer/indexer/indices.go @@ -3,246 +3,133 @@ package indexer import ( "context" - "github.com/baking-bad/bcdhub/internal/logger" - "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/bigmapaction" "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" - "github.com/baking-bad/bcdhub/internal/models/block" "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/migration" "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/ticket" - "github.com/go-pg/pg/v10" + "github.com/rs/zerolog/log" ) -func createStartIndices(db pg.DBI) error { - return db.RunInTransaction(context.Background(), func(tx *pg.Tx) error { - // Accounts - if _, err := db.Model((*account.Account)(nil)).Exec(`CREATE INDEX CONCURRENTLY IF NOT EXISTS accounts_address_idx ON ?TableName (address)`); err != nil { - return err - } - - // Blocks - if _, err := db.Model((*block.Block)(nil)).Exec(`CREATE INDEX CONCURRENTLY IF NOT EXISTS blocks_level_idx ON ?TableName (level)`); err != nil { - return err - } - - // Big map diff - if _, err := db.Model((*bigmapdiff.BigMapDiff)(nil)).Exec(`CREATE INDEX IF NOT EXISTS big_map_diff_idx ON ?TableName (contract, ptr)`); err != nil { - return err - } - - if _, err := db.Model((*bigmapdiff.BigMapDiff)(nil)).Exec(`CREATE INDEX IF NOT EXISTS big_map_diff_key_hash_idx ON ?TableName (key_hash, ptr)`); err != nil { - return err - } - - // Big map state - if _, err := db.Model((*bigmapdiff.BigMapState)(nil)).Exec(`CREATE INDEX CONCURRENTLY IF NOT EXISTS big_map_state_ptr_idx ON ?TableName (ptr)`); err != nil { - return err - } - - if _, err := db.Model((*bigmapdiff.BigMapState)(nil)).Exec(`CREATE INDEX CONCURRENTLY IF NOT EXISTS big_map_state_contract_idx ON ?TableName (contract)`); err != nil { - return err - } - - if _, err := db.Model((*bigmapdiff.BigMapState)(nil)).Exec(`CREATE INDEX CONCURRENTLY IF NOT EXISTS big_map_state_last_update_level_idx ON ?TableName (last_update_level)`); err != nil { - return err - } - - // Contracts - if _, err := db.Model((*contract.Contract)(nil)).Exec(`CREATE INDEX CONCURRENTLY IF NOT EXISTS contracts_account_id_idx ON ?TableName (account_id)`); err != nil { - return err - } - - // Operations - if _, err := db.Model((*operation.Operation)(nil)).Exec(`CREATE INDEX IF NOT EXISTS operations_destination_idx ON ?TableName (destination_id)`); err != nil { - return err - } - - if _, err := db.Model((*operation.Operation)(nil)).Exec(`CREATE INDEX IF NOT EXISTS operations_status_idx ON ?TableName (status)`); err != nil { - return err - } - - return nil - }) -} - -func (bi *BlockchainIndexer) createIndices() { - logger.Info().Str("network", bi.Network.String()).Msg("creating database indices...") +func (bi *BlockchainIndexer) createIndices(ctx context.Context) error { + log.Info().Str("network", bi.Network.String()).Msg("creating database indices...") // Big map action - if _, err := bi.Context.StorageDB.DB.Model((*bigmapaction.BigMapAction)(nil)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS big_map_action_level_idx ON ?TableName (level) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + action := (*bigmapaction.BigMapAction)(nil) + if err := bi.Storage.CreateIndex(ctx, "big_map_action_level_idx", "level", action); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*bigmapaction.BigMapAction)(nil)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS big_map_actions_source_ptr_idx ON ?TableName (source_ptr) where source_ptr is not null - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "big_map_actions_source_ptr_idx", "source_ptr", action); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*bigmapaction.BigMapAction)(nil)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS big_map_actions_destination_ptr_idx ON ?TableName (destination_ptr) where destination_ptr is not null - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "big_map_actions_destination_ptr_idx", "destination_ptr", action); err != nil { + return err } // Big map diff - if _, err := bi.Context.StorageDB.DB.Model((*bigmapdiff.BigMapDiff)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS big_map_diff_operation_id_idx ON ?TableName (operation_id) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + diff := (*bigmapdiff.BigMapDiff)(nil) + if err := bi.Storage.CreateIndex(ctx, "big_map_diff_operation_id_idx", "operation_id", diff); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*bigmapdiff.BigMapDiff)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS big_map_diff_level_idx ON ?TableName (level) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "big_map_diff_level_idx", "level", diff); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*bigmapdiff.BigMapDiff)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS big_map_diff_protocol_idx ON ?TableName (protocol_id) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "big_map_diff_protocol_idx", "protocol_id", diff); err != nil { + return err } // Contracts - if _, err := bi.Context.StorageDB.DB.Model((*contract.Contract)(nil)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS contracts_level_idx ON ?TableName (level) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") - } - - if _, err := bi.Context.StorageDB.DB.Model((*contract.Contract)(nil)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS contracts_alpha_id_idx ON ?TableName (alpha_id) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") - } - - if _, err := bi.Context.StorageDB.DB.Model((*contract.Contract)(nil)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS contracts_babylon_id_idx ON ?TableName (babylon_id) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") - } - - if _, err := bi.Context.StorageDB.DB.Model((*contract.Contract)(nil)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS contracts_jakarta_id_idx ON ?TableName (jakarta_id) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + contractModel := (*contract.Contract)(nil) + if err := bi.Storage.CreateIndex(ctx, "contracts_level_idx", "level", contractModel); err != nil { + return err } // Global constants - if _, err := bi.Context.StorageDB.DB.Model((*contract.GlobalConstant)(nil)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS global_constants_address_idx ON ?TableName (address) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + globalConstant := (*contract.GlobalConstant)(nil) + if err := bi.Storage.CreateIndex(ctx, "global_constants_address_idx", "address", globalConstant); err != nil { + return err } // Migrations - if _, err := bi.Context.StorageDB.DB.Model((*migration.Migration)(nil)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS migrations_level_idx ON ?TableName (level) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + migration := (*migration.Migration)(nil) + if err := bi.Storage.CreateIndex(ctx, "migrations_level_idx", "level", migration); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*migration.Migration)(nil)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS migrations_contract_id_idx ON ?TableName (contract_id) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "migrations_contract_id_idx", "contract_id", migration); err != nil { + return err } // Operations - if _, err := bi.Context.StorageDB.DB.Model((*operation.Operation)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS operations_level_idx ON ?TableName (level) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + operation := (*operation.Operation)(nil) + if err := bi.Storage.CreateIndex(ctx, "operations_level_idx", "level", operation); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*operation.Operation)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS operations_source_idx ON ?TableName (source_id) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "operations_source_idx", "source_id", operation); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*operation.Operation)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS operations_opg_idx ON ?TableName (hash, counter, content_index) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "operations_opg_idx", "hash, counter, content_index", operation); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*operation.Operation)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS operations_entrypoint_idx ON ?TableName (entrypoint) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "operations_entrypoint_idx", "entrypoint", operation); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*operation.Operation)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS operations_hash_idx ON ?TableName (hash) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "operations_hash_idx", "hash", operation); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*operation.Operation)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS operations_opg_with_nonce_idx ON ?TableName (hash, counter, nonce) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "operations_opg_with_nonce_idx", "hash, counter, nonce", operation); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*operation.Operation)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS operations_sort_idx ON ?TableName (level, counter, id) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "operations_sort_idx", "level, counter, id", operation); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*operation.Operation)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS operations_timestamp_idx ON ?TableName (timestamp) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "operations_timestamp_idx", "timestamp", operation); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*operation.Operation)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS operations_kind_idx ON ?TableName (kind) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "operations_kind_idx", "kind", operation); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*operation.Operation)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS operations_destination_timestamp_idx ON ?TableName (destination_id, timestamp) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "operations_destination_timestamp_idx", "destination_id, timestamp", operation); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model((*operation.Operation)(nil)).Exec(` - CREATE INDEX IF NOT EXISTS operations_source_timestamp_idx ON ?TableName (source_id, timestamp) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "operations_source_timestamp_idx", "source_id, timestamp", operation); err != nil { + return err } // Scripts to global constants - if _, err := bi.Context.StorageDB.DB.Model(new(contract.ScriptConstants)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS script_id_idx ON ?TableName (script_id) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + scriptConstants := (*contract.ScriptConstants)(nil) + if err := bi.Storage.CreateIndex(ctx, "script_id_idx", "script_id", scriptConstants); err != nil { + return err } - - if _, err := bi.Context.StorageDB.DB.Model(new(contract.ScriptConstants)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS global_constant_id_idx ON ?TableName (global_constant_id) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + if err := bi.Storage.CreateIndex(ctx, "global_constant_id_idx", "global_constant_id", scriptConstants); err != nil { + return err } // Ticket updates - if _, err := bi.Context.StorageDB.DB.Model(new(ticket.TicketUpdate)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS ticket_updates_operation_id_idx ON ?TableName (operation_id) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + ticketUpdate := (*ticket.TicketUpdate)(nil) + if err := bi.Storage.CreateIndex(ctx, "ticket_updates_level_idx", "level", ticketUpdate); err != nil { + return err + } + if err := bi.Storage.CreateIndex(ctx, "ticket_updates_operation_id_idx", "operation_id", ticketUpdate); err != nil { + return err + } + if err := bi.Storage.CreateIndex(ctx, "ticket_updates_ticket_id_idx", "ticket_id", ticketUpdate); err != nil { + return err + } + if err := bi.Storage.CreateIndex(ctx, "ticket_updates_account_id_idx", "account_id", ticketUpdate); err != nil { + return err } - if _, err := bi.Context.StorageDB.DB.Model(new(ticket.TicketUpdate)).Exec(` - CREATE INDEX CONCURRENTLY IF NOT EXISTS ticket_updates_ticketer_id_idx ON ?TableName (ticketer_id) - `); err != nil { - logger.Error().Err(err).Msg("can't create index") + // Tickets + tickets := (*ticket.Ticket)(nil) + if err := bi.Storage.CreateIndex(ctx, "ticket_level_idx", "level", tickets); err != nil { + return err + } + if err := bi.Storage.CreateIndex(ctx, "ticket_ticketer_id_idx", "ticketer_id", tickets); err != nil { + return err } + + log.Info().Str("network", bi.Network.String()).Msg("database indices was created") + + return nil } diff --git a/cmd/indexer/indexer/initializer.go b/cmd/indexer/indexer/initializer.go index d58e9346e..4ba8dcf07 100644 --- a/cmd/indexer/indexer/initializer.go +++ b/cmd/indexer/indexer/initializer.go @@ -3,19 +3,19 @@ package indexer import ( "context" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models" "github.com/baking-bad/bcdhub/internal/models/block" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" - "github.com/go-pg/pg/v10" + "github.com/rs/zerolog/log" + "github.com/uptrace/bun" ) // Initializer - type Initializer struct { repo models.GeneralRepository block block.Repository - db pg.DBI + db bun.IDB network types.Network rpc noderpc.INode isPeriodic bool @@ -26,7 +26,7 @@ func NewInitializer( network types.Network, repo models.GeneralRepository, block block.Repository, - db pg.DBI, + db bun.IDB, rpc noderpc.INode, isPeriodic bool) Initializer { return Initializer{repo, block, db, network, rpc, isPeriodic} @@ -35,29 +35,25 @@ func NewInitializer( // Init - func (initializer Initializer) Init(ctx context.Context) error { if initializer.isPeriodic { - if exists := initializer.repo.TablesExist(); exists { + if exists := initializer.repo.TablesExist(ctx); exists { // check first block in node and in database, compare its hash. // if hash is differed new periodic chain was started. - logger.Info().Str("network", initializer.network.String()).Msg("checking for new periodic chain...") + log.Info().Str("network", initializer.network.String()).Msg("checking for new periodic chain...") blockHash, err := initializer.rpc.BlockHash(ctx, 1) if err != nil { return err } - firstBlock, err := initializer.block.Get(1) + firstBlock, err := initializer.block.Get(ctx, 1) if err == nil && firstBlock.Hash != blockHash { - logger.Info().Str("network", initializer.network.String()).Msg("found new periodic chain") - logger.Warning().Str("network", initializer.network.String()).Msg("drop database...") + log.Info().Str("network", initializer.network.String()).Msg("found new periodic chain") + log.Warn().Str("network", initializer.network.String()).Msg("drop database...") if err := initializer.repo.Drop(ctx); err != nil { return err } - logger.Warning().Str("network", initializer.network.String()).Msg("database was dropped") + log.Warn().Str("network", initializer.network.String()).Msg("database was dropped") } } } - if err := initializer.repo.CreateTables(); err != nil { - return err - } - - return createStartIndices(initializer.db) + return initializer.repo.InitDatabase(ctx) } diff --git a/cmd/indexer/indexer/periodic.go b/cmd/indexer/indexer/periodic.go index 115cbfa00..61c676a25 100644 --- a/cmd/indexer/indexer/periodic.go +++ b/cmd/indexer/indexer/periodic.go @@ -6,11 +6,11 @@ import ( "time" "github.com/baking-bad/bcdhub/internal/config" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" "github.com/baking-bad/bcdhub/internal/periodic" "github.com/dipdup-io/workerpool" + "github.com/rs/zerolog/log" ) // PeriodicIndexer - @@ -91,7 +91,7 @@ func (p *PeriodicIndexer) Rollback(ctx context.Context) error { } func (p *PeriodicIndexer) handleUrlChanged(ctx context.Context, network, url string) error { - logger.Warning().Str("network", network).Str("url", url).Msg("cancelling indexer due to URL changing...") + log.Warn().Str("network", network).Str("url", url).Msg("cancelling indexer due to URL changing...") p.indexerCancel() if err := p.indexer.Close(); err != nil { diff --git a/cmd/indexer/indexer/receiver.go b/cmd/indexer/indexer/receiver.go index 39d15db5b..42ae02c03 100644 --- a/cmd/indexer/indexer/receiver.go +++ b/cmd/indexer/indexer/receiver.go @@ -3,10 +3,10 @@ package indexer import ( "context" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/noderpc" "github.com/dipdup-io/workerpool" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) // Block - @@ -96,7 +96,7 @@ func (r *Receiver) job(ctx context.Context, level int64) { block, err := r.get(ctx, level) if err != nil { if !errors.Is(err, context.Canceled) { - logger.Error().Int64("block", level).Err(err).Msg("Receiver.get") + log.Err(err).Int64("block", level).Msg("Receiver.get") r.pool.AddTask(level) } return diff --git a/cmd/indexer/main.go b/cmd/indexer/main.go index ee042369f..3620d38c3 100644 --- a/cmd/indexer/main.go +++ b/cmd/indexer/main.go @@ -13,15 +13,18 @@ import ( "github.com/baking-bad/bcdhub/internal/profiler" "github.com/dipdup-io/workerpool" "github.com/grafana/pyroscope-go" + "github.com/rs/zerolog/log" ) func main() { cfg, err := config.LoadDefaultConfig() if err != nil { - logger.Err(err) + log.Err(err).Msg("loading config") return } + logger.New(cfg.LogLevel) + if cfg.Indexer.SentryEnabled { helpers.InitSentry(cfg.Sentry.Debug, cfg.Sentry.Environment, cfg.Sentry.URI) helpers.SetTagSentry("project", cfg.Indexer.ProjectName) @@ -42,7 +45,7 @@ func main() { indexers, err := indexer.CreateIndexers(ctx, cfg, g) if err != nil { cancel() - logger.Err(err) + log.Err(err).Msg("indexers creation") helpers.CatchErrorSentry(err) return } @@ -65,5 +68,5 @@ func main() { panic(err) } } - logger.Info().Msg("Stopped") + log.Info().Msg("stopped") } diff --git a/configs/development.yml b/configs/development.yml index a4e392a25..a0850a48a 100644 --- a/configs/development.yml +++ b/configs/development.yml @@ -16,6 +16,8 @@ rpc: # timeout: 20 # requests_per_second: 20 +log_level: ${LOG_LEVEL:-info} + services: mainnet: mempool: https://mempool.dipdup.net/v1/graphql @@ -68,25 +70,19 @@ api: - ghostnet - nairobinet # - oxfordnet - connections: - max: 50 - idle: 50 indexer: project_name: indexer sentry_enabled: false networks: mainnet: - receiver_threads: 15 + receiver_threads: 5 ghostnet: - receiver_threads: 15 + receiver_threads: 5 nairobinet: receiver_threads: 15 # oxfordnet: # receiver_threads: 10 - connections: - max: 5 - idle: 5 scripts: networks: @@ -94,6 +90,3 @@ scripts: - ghostnet - nairobinet # - oxfordnet - connections: - max: 5 - idle: 5 \ No newline at end of file diff --git a/configs/production.yml b/configs/production.yml index 77ea08f88..a88daae7f 100644 --- a/configs/production.yml +++ b/configs/production.yml @@ -15,6 +15,8 @@ rpc: # uri: https://rpc.tzkt.io/oxfordnet # timeout: 20 # requests_per_second: 20 + +log_level: ${LOG_LEVEL:-info} services: mainnet: @@ -71,9 +73,6 @@ api: - ghostnet - nairobinet # - oxfordnet - connections: - max: 50 - idle: 10 indexer: project_name: indexer @@ -87,9 +86,6 @@ indexer: receiver_threads: ${TESTNET_THREADS:-10} # oxfordnet: # receiver_threads: ${TESTNET_THREADS:-10} - connections: - max: 5 - idle: 5 scripts: aws: @@ -102,6 +98,3 @@ scripts: - ghostnet - nairobinet # - oxfordnet - connections: - max: 5 - idle: 5 diff --git a/configs/sandbox.yml b/configs/sandbox.yml index 652737694..6eae2d113 100644 --- a/configs/sandbox.yml +++ b/configs/sandbox.yml @@ -14,6 +14,8 @@ storage: sslmode: disable timeout: 10 +log_level: ${LOG_LEVEL:-info} + share_path: /etc/bcd base_url: http://localhost:8000 @@ -40,9 +42,6 @@ indexer: networks: sandboxnet: receiver_threads: 5 - connections: - max: 5 - idle: 5 scripts: networks: diff --git a/configs/testnets.yml b/configs/testnets.yml index d08c34058..80d785699 100644 --- a/configs/testnets.yml +++ b/configs/testnets.yml @@ -8,6 +8,8 @@ rpc: timeout: 20 requests_per_second: 10 +log_level: ${LOG_LEVEL:-info} + storage: pg: host: ${DB_HOSTNAME:-127.0.0.1} @@ -50,9 +52,6 @@ api: networks: - dailynet - mondaynet - connections: - max: 50 - idle: 50 indexer: project_name: indexer @@ -68,14 +67,8 @@ indexer: periodic: info_base_url: https://teztnets.xyz schedule: "0 5 0 * * MON" # at 00:05:00 every monday - connections: - max: 5 - idle: 5 scripts: networks: - dailynet - mondaynet - connections: - max: 5 - idle: 5 diff --git a/docker-compose.flextesa.yml b/docker-compose.flextesa.yml index e1e2fe465..02b8c8b85 100644 --- a/docker-compose.flextesa.yml +++ b/docker-compose.flextesa.yml @@ -1,7 +1,7 @@ version: "3.6" services: db: - image: postgres:14 + image: timescale/timescaledb:latest-pg15 shm_size: 1g restart: always environment: @@ -18,7 +18,7 @@ services: api: restart: always - image: ghcr.io/baking-bad/bcdhub-api:${TAG} + image: ghcr.io/baking-bad/bcdhub-api:${TAG_BACK} environment: - BCD_ENV=sandbox - GIN_MODE=debug @@ -38,7 +38,7 @@ services: indexer: restart: always - image: ghcr.io/baking-bad/bcdhub-indexer:${TAG} + image: ghcr.io/baking-bad/bcdhub-indexer:${TAG_BACK} environment: - BCD_ENV=sandbox - POSTGRES_USER=root @@ -69,7 +69,7 @@ services: gui: container_name: sandbox-gui restart: always - image: ghcr.io/baking-bad/bcdhub-gui:${TAG} + image: ghcr.io/baking-bad/bcdhub-gui:${TAG_FRONT} depends_on: - api ports: diff --git a/docker-compose.yml b/docker-compose.yml index 53e1e43f9..a625e7e92 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,7 +1,7 @@ version: "3.6" services: db: - image: postgres:14 + image: timescale/timescaledb:latest-pg15 shm_size: 1g user: postgres restart: always diff --git a/go.mod b/go.mod index a817f0638..49f142951 100644 --- a/go.mod +++ b/go.mod @@ -1,82 +1,126 @@ module github.com/baking-bad/bcdhub -go 1.20 +go 1.21 require ( github.com/btcsuite/btcutil v1.0.2 github.com/dipdup-io/workerpool v0.0.4 + github.com/dipdup-net/go-lib v0.3.5 github.com/ebellocchia/go-base58 v0.1.0 github.com/fatih/color v1.13.0 github.com/getsentry/sentry-go v0.13.0 github.com/gin-contrib/cache v1.2.0 github.com/gin-contrib/cors v1.4.0 + github.com/gin-contrib/logger v0.2.6 + github.com/gin-contrib/timeout v0.0.3 github.com/gin-gonic/gin v1.9.1 - github.com/go-pg/pg/v10 v10.10.6 - github.com/go-playground/validator/v10 v10.14.1 + github.com/go-playground/validator/v10 v10.15.5 + github.com/go-testfixtures/testfixtures/v3 v3.9.0 github.com/google/uuid v1.3.0 github.com/grafana/pyroscope-go v1.0.3 - github.com/iancoleman/strcase v0.2.0 + github.com/iancoleman/strcase v0.3.0 github.com/ipfs/go-cid v0.3.2 github.com/jessevdk/go-flags v1.5.0 github.com/json-iterator/go v1.1.12 github.com/karlseguin/ccache v2.0.3+incompatible - github.com/lib/pq v1.10.7 + github.com/lib/pq v1.10.9 github.com/machinebox/graphql v0.2.2 github.com/microcosm-cc/bluemonday v1.0.20 github.com/pkg/errors v0.9.1 github.com/robfig/cron/v3 v3.0.1 - github.com/rs/zerolog v1.28.0 - github.com/sergi/go-diff v1.2.0 + github.com/rs/zerolog v1.30.0 + github.com/sergi/go-diff v1.3.1 github.com/shopspring/decimal v1.3.1 - github.com/stretchr/testify v1.8.3 - github.com/tidwall/gjson v1.14.3 + github.com/stretchr/testify v1.8.4 + github.com/tidwall/gjson v1.16.0 + github.com/uptrace/bun v1.1.16 + github.com/uptrace/bun/dialect/pgdialect v1.1.16 + github.com/uptrace/bun/driver/pgdriver v1.1.16 github.com/yhirose/go-peg v0.0.0-20210804202551-de25d6753cf1 go.uber.org/mock v0.2.0 - golang.org/x/crypto v0.12.0 + golang.org/x/crypto v0.14.0 golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 gopkg.in/yaml.v3 v3.0.1 ) require ( + dario.cat/mergo v1.0.0 // indirect + github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect + github.com/ClickHouse/ch-go v0.55.0 // indirect + github.com/ClickHouse/clickhouse-go/v2 v2.9.1 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/andybalholm/brotli v1.0.5 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d // indirect - github.com/bytedance/sonic v1.9.1 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/bytedance/sonic v1.10.2 // indirect + github.com/cenkalti/backoff/v4 v4.2.1 // indirect + github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect + github.com/chenzhuoyu/iasm v0.9.0 // indirect + github.com/containerd/containerd v1.7.3 // indirect + github.com/cpuguy83/dockercfg v0.3.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/docker/distribution v2.8.2+incompatible // indirect + github.com/docker/docker v24.0.5+incompatible // indirect + github.com/docker/go-connections v0.4.0 // indirect + github.com/docker/go-units v0.5.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-faster/city v1.0.1 // indirect + github.com/go-faster/errors v0.6.1 // indirect + github.com/go-pg/pg/v10 v10.10.6 // indirect github.com/go-pg/zerochecker v0.2.0 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-sql-driver/mysql v1.7.1 // indirect github.com/goccy/go-json v0.10.2 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/gomodule/redigo v2.0.0+incompatible // indirect - github.com/google/go-cmp v0.5.8 // indirect github.com/gorilla/css v1.0.0 // indirect github.com/grafana/pyroscope-go/godeltaprof v0.1.4 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgx/v5 v5.4.3 // indirect github.com/jinzhu/inflection v1.0.0 // indirect + github.com/jinzhu/now v1.1.5 // indirect github.com/karlseguin/expect v1.0.8 // indirect + github.com/klauspost/compress v1.16.5 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/leodido/go-urn v1.2.4 // indirect + github.com/magiconair/properties v1.8.7 // indirect github.com/matryer/is v1.4.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-sqlite3 v1.14.17 // indirect github.com/memcachier/mc/v3 v3.0.3 // indirect github.com/minio/sha256-simd v1.0.0 // indirect + github.com/moby/patternmatcher v0.5.0 // indirect + github.com/moby/sys/sequential v0.5.0 // indirect + github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/morikuni/aec v1.0.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.1.0 // indirect github.com/multiformats/go-multibase v0.1.1 // indirect github.com/multiformats/go-multihash v0.2.1 // indirect github.com/multiformats/go-varint v0.0.6 // indirect - github.com/onsi/gomega v1.20.2 // indirect - github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/opencontainers/go-digest v1.0.0 // indirect + github.com/opencontainers/image-spec v1.1.0-rc4 // indirect + github.com/opencontainers/runc v1.1.5 // indirect + github.com/paulmach/orb v0.9.0 // indirect + github.com/pelletier/go-toml/v2 v2.1.0 // indirect + github.com/pierrec/lz4/v4 v4.1.17 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62 // indirect + github.com/segmentio/asm v1.2.0 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect + github.com/testcontainers/testcontainers-go v0.22.0 // indirect + github.com/testcontainers/testcontainers-go/modules/postgres v0.22.0 // indirect github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/pretty v1.2.1 // indirect github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect @@ -84,11 +128,22 @@ require ( github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect github.com/vmihailenco/tagparser v0.1.2 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - golang.org/x/arch v0.3.0 // indirect - golang.org/x/net v0.14.0 // indirect - golang.org/x/sys v0.11.0 // indirect - golang.org/x/text v0.12.0 // indirect - google.golang.org/protobuf v1.30.0 // indirect + go.opentelemetry.io/otel v1.15.0 // indirect + go.opentelemetry.io/otel/trace v1.15.0 // indirect + golang.org/x/arch v0.5.0 // indirect + golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea // indirect + golang.org/x/mod v0.9.0 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.13.0 // indirect + golang.org/x/text v0.13.0 // indirect + golang.org/x/tools v0.7.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect + google.golang.org/grpc v1.57.0 // indirect + google.golang.org/protobuf v1.31.0 // indirect + gorm.io/driver/mysql v1.5.1 // indirect + gorm.io/driver/postgres v1.5.2 // indirect + gorm.io/driver/sqlite v1.5.2 // indirect + gorm.io/gorm v1.25.3 // indirect lukechampine.com/blake3 v1.1.6 // indirect mellium.im/sasl v0.3.1 // indirect ) diff --git a/go.sum b/go.sum index f15686997..5349836c4 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,22 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1 h1:EKPd1INOIyr5hWOWhvpmQpY6tKjeG0hT1s3AMC/9fic= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20230106234847-43070de90fa1/go.mod h1:VzwV+t+dZ9j/H867F1M2ziD+yLHtB46oM35FxxMJ4d0= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/ClickHouse/ch-go v0.55.0 h1:jw4Tpx887YXrkyL5DfgUome/po8MLz92nz2heOQ6RjQ= +github.com/ClickHouse/ch-go v0.55.0/go.mod h1:kQT2f+yp2p+sagQA/7kS6G3ukym+GQ5KAu1kuFAFDiU= +github.com/ClickHouse/clickhouse-go/v2 v2.9.1 h1:IeE2bwVvAba7Yw5ZKu98bKI4NpDmykEy6jUaQdJJCk8= +github.com/ClickHouse/clickhouse-go/v2 v2.9.1/go.mod h1:teXfZNM90iQ99Jnuht+dxQXCuhDZ8nvvMoTJOFrcmcg= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/Microsoft/hcsshim v0.10.0-rc.8 h1:YSZVvlIIDD1UxQpJp0h+dnpLUw+TrY0cx8obKsp3bek= +github.com/Microsoft/hcsshim v0.10.0-rc.8/go.mod h1:OEthFdQv/AD2RAdzR6Mm1N1KPCztGKDurW1Z8b8VGMM= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= +github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/bradfitz/gomemcache v0.0.0-20220106215444-fb4bf637b56d h1:pVrfxiGfwelyab6n21ZBkbkmbevaf+WvMIiR7sr97hw= @@ -16,30 +32,64 @@ github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= -github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= +github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= +github.com/bytedance/sonic v1.10.2 h1:GQebETVBxYB7JGWJtLBi07OVzWwt+8dWA00gEVW2ZFE= +github.com/bytedance/sonic v1.10.2/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= +github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= +github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= +github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= +github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= +github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZZJDa8o= +github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+HMvaKUNiqCZB8= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= +github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= +github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cyphar/filepath-securejoin v0.2.3 h1:YX6ebbZCZP7VkM3scTTokDgBL2TY741X51MTk3ycuNI= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/denisenkom/go-mssqldb v0.12.3 h1:pBSGx9Tq67pBOTLmxNuirNTeB8Vjmf886Kx+8Y+8shw= +github.com/denisenkom/go-mssqldb v0.12.3/go.mod h1:k0mtMFOnU+AihqFxPMiF05rtiDrorD1Vrm1KEz5hxDo= github.com/dipdup-io/workerpool v0.0.4 h1:m58fuFY3VIPRc+trWpjw2Lsm4FvIgtjP/4VRe79r+/s= github.com/dipdup-io/workerpool v0.0.4/go.mod h1:m6YMqx7M+fORTyabHD/auKymBRpbDax0t1aPZ1i7GZA= +github.com/dipdup-net/go-lib v0.3.5 h1:UTH3mywL0Euyq/myFJwzbg7OPy5v9zhLa8gSCiHALLE= +github.com/dipdup-net/go-lib v0.3.5/go.mod h1:oBDOSsM/F8fEnmuDnaJ6QA/cHH4lne49ASbsh8WXDe4= +github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8= +github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v24.0.5+incompatible h1:WmgcE4fxyI6EEXxBRxsHnZXrO1pQ3smi0k/jho4HLeY= +github.com/docker/docker v24.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/ebellocchia/go-base58 v0.1.0 h1:0w/ODEfZnOPW5KW0QY/Xpb1fxba/BxQJMUa5iYzpljk= github.com/ebellocchia/go-base58 v0.1.0/go.mod h1:RHE/6C6Ru6YAH9Tc+A9eHQ6ZKEooLC0jw+YLnpt3CAU= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU= github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA= github.com/getsentry/sentry-go v0.13.0 h1:20dgTiUSfxRB/EhMPtxcL9ZEbM1ZdR+W/7f7NWD+xWo= @@ -48,35 +98,64 @@ github.com/gin-contrib/cache v1.2.0 h1:WA+AJR4kmHDTaLLShCHo/IeWVmmGRZ3Lsr3JQ46tF github.com/gin-contrib/cache v1.2.0/go.mod h1:2KkFL8PSnPF3Tt5E2Jpc3HWuBAUKqGZnClCFMm0tXQI= github.com/gin-contrib/cors v1.4.0 h1:oJ6gwtUl3lqV0WEIwM/LxPF1QZ5qe2lGWdY2+bz7y0g= github.com/gin-contrib/cors v1.4.0/go.mod h1:bs9pNM0x/UsmHPBWT2xZz9ROh8xYjYkiURUfmBoMlcs= +github.com/gin-contrib/logger v0.2.6 h1:u+tvbiQhGEyuJgZSHNja3WD800ILduVyk5xKop160dw= +github.com/gin-contrib/logger v0.2.6/go.mod h1:ZDkY/xiMqbZdz83enCHjMqxJUFRzB8bq0kjyMmjr3qU= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-contrib/timeout v0.0.3 h1:ysZQ7kChgqlzBkuLgwTTDjTPP2uqdI68XxRyqIFK68g= +github.com/gin-contrib/timeout v0.0.3/go.mod h1:F3fjkmFc4I1QdF7MyVwtO6ZkPueBckNoiOVpU73HGgU= +github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw= +github.com/go-faster/city v1.0.1/go.mod h1:jKcUJId49qdW3L1qKHH/3wPeUstCVpVSXTM6vO3VcTw= +github.com/go-faster/errors v0.6.1 h1:nNIPOBkprlKzkThvS/0YaX8Zs9KewLCOSFQS5BU06FI= +github.com/go-faster/errors v0.6.1/go.mod h1:5MGV2/2T9yvlrbhe9pD9LO5Z/2zCSq2T8j+Jpi2LAyY= github.com/go-pg/pg/v10 v10.10.6 h1:1vNtPZ4Z9dWUw/TjJwOfFUbF5nEq1IkR6yG8Mq/Iwso= github.com/go-pg/pg/v10 v10.10.6/go.mod h1:GLmFXufrElQHf5uzM3BQlcfwV3nsgnHue5uzjQ6Nqxg= github.com/go-pg/zerochecker v0.2.0 h1:pp7f72c3DobMWOb2ErtZsnrPaSvHd2W4o9//8HtF4mU= github.com/go-pg/zerochecker v0.2.0/go.mod h1:NJZ4wKL0NmTtz0GKCoJ8kym6Xn/EQzXRl2OnAe7MmDo= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos= -github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k= -github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-playground/validator/v10 v10.15.5 h1:LEBecTWb/1j5TNY1YYG2RcOUN3R7NLylN+x8TTueE24= +github.com/go-playground/validator/v10 v10.15.5/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= +github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= +github.com/go-testfixtures/testfixtures/v3 v3.9.0 h1:938g5V+GWLVejm3Hc+nWCuEXRlcglZDDlN/t1gWzcSY= +github.com/go-testfixtures/testfixtures/v3 v3.9.0/go.mod h1:cdsKD2ApFBjdog9jRsz6EJqF+LClq/hrwE9K/1Dzo4s= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= +github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -86,6 +165,9 @@ 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.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -93,9 +175,11 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +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.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -106,42 +190,75 @@ github.com/grafana/pyroscope-go v1.0.3/go.mod h1:0d7ftwSMBV/Awm7CCiYmHQEG8Y44Ma3 github.com/grafana/pyroscope-go/godeltaprof v0.1.4 h1:mDsJ3ngul7UfrHibGQpV66PbZ3q1T8glz/tK3bQKKEk= github.com/grafana/pyroscope-go/godeltaprof v0.1.4/go.mod h1:1HSPtjU8vLG0jE9JrTdzjgFqdJ/VgN7fvxBNq3luJko= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= -github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= +github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ipfs/go-cid v0.3.2 h1:OGgOd+JCFM+y1DjWPmVH+2/4POtpDzwcr7VgnB7mZXc= github.com/ipfs/go-cid v0.3.2/go.mod h1:gQ8pKqT/sUxGY+tIwy1RPpAojYu7jAyCp5Tz1svoupw= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q= +github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0= +github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw= +github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0= +github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE= +github.com/jackc/pgx/v5 v5.4.3 h1:cxFyXhxlvAifxnkKKdlxv8XqUf59tDlYjnV5YYfsJJY= +github.com/jackc/pgx/v5 v5.4.3/go.mod h1:Ig06C2Vu0t5qXC60W8sqIthScaEnFvojjj9dSljmHRA= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= +github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/karlseguin/ccache v2.0.3+incompatible h1:j68C9tWOROiOLWTS/kCGg9IcJG+ACqn5+0+t8Oh83UU= github.com/karlseguin/ccache v2.0.3+incompatible/go.mod h1:CM9tNPzT6EdRh14+jiW8mEF9mkNZuuE51qmgGYUB93w= github.com/karlseguin/expect v1.0.8 h1:Bb0H6IgBWQpadY25UDNkYPDB9ITqK1xnSoZfAq362fw= github.com/karlseguin/expect v1.0.8/go.mod h1:lXdI8iGiQhmzpnnmU/EGA60vqKs8NbRNFnhhrJGoD5g= +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/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/klauspost/compress v1.16.5 h1:IFV2oUNUzZaz+XyusxpLzpzS8Pt5rh0Z16For/djlyI= +github.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= 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/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= 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= 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/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= -github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= -github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/machinebox/graphql v0.2.2 h1:dWKpJligYKhYKO5A2gvNhkJdQMNZeChZYyBbrZkBZfo= github.com/machinebox/graphql v0.2.2/go.mod h1:F+kbVMHuwrQ5tYgU9JXlnskM8nOaFxCAEolaQybkjWA= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -153,19 +270,33 @@ github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27k 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-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM= +github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/memcachier/mc/v3 v3.0.3 h1:qii+lDiPKi36O4Xg+HVKwHu6Oq+Gt17b+uEiA0Drwv4= github.com/memcachier/mc/v3 v3.0.3/go.mod h1:GzjocBahcXPxt2cmqzknrgqCOmMxiSzhVKPOe90Tpug= github.com/microcosm-cc/bluemonday v1.0.20 h1:flpzsq4KU3QIYAYGV/szUat7H+GPOXR0B2JU5A1Wp8Y= github.com/microcosm-cc/bluemonday v1.0.20/go.mod h1:yfBmMi8mxvaZut3Yytv+jTXRY8mxyjJ0/kQBTElld50= 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/moby/patternmatcher v0.5.0 h1:YCZgJOeULcxLw1Q+sVR636pmS7sPEn1Qo2iAN6M7DBo= +github.com/moby/patternmatcher v0.5.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/sequential v0.5.0 h1:OPvI35Lzn9K04PBbCLW0g4LcFAJgHsvXsRyewg5lXtc= +github.com/moby/sys/sequential v0.5.0/go.mod h1:tH2cOOs5V9MlPiXcQzRC+eEyab644PWKGRYaaV5ZZlo= +github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0= +github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= 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.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= 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/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= 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.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= @@ -187,13 +318,26 @@ github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3 h1:gph6h/qe9GSUw1NhH1gp+qb+h8rXD8Cy60Z32Qw3ELA= github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.20.2 h1:8uQq0zMgLEfa0vRrrBgaJF2gyW9Da9BmfGV+OyUzfkY= -github.com/onsi/gomega v1.20.2/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0= +github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8= +github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= +github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/paulmach/orb v0.9.0 h1:MwA1DqOKtvCgm7u9RZ/pnYejTeDJPnr0+0oFajBbJqk= +github.com/paulmach/orb v0.9.0/go.mod h1:SudmOk85SXtmXAB3sLGyJ6tZy/8pdfrV0o6ef98Xc30= +github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY= github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo= -github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= -github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4= +github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pierrec/lz4/v4 v4.1.17 h1:kV4Ip+/hUBC+8T6+2EgburRtkE9ef4nbY3f4dFhGjMc= +github.com/pierrec/lz4/v4 v4.1.17/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= 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.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -205,20 +349,30 @@ github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzG github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62 h1:pyecQtsPmlkCsMkYhT5iZ+sUXuwee+OvfuJjinEA3ko= github.com/robfig/go-cache v0.0.0-20130306151617-9fc39e0dbf62/go.mod h1:65XQgovT59RWatovFwnwocoUxiI/eENTnOY5GK3STuY= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY= -github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= +github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys= +github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= +github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= +github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/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.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= 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= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -228,22 +382,40 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= -github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw= -github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/testcontainers/testcontainers-go v0.22.0 h1:hOK4NzNu82VZcKEB1aP9LO1xYssVFMvlfeuDW9JMmV0= +github.com/testcontainers/testcontainers-go v0.22.0/go.mod h1:k0YiPa26xJCRUbUkYqy5rY6NGvSbVCeUBXCvucscBR4= +github.com/testcontainers/testcontainers-go/modules/postgres v0.22.0 h1:OHVaqu9MRGMSlro9AD5UCfj8XiHwQdhB9thE4vINq+E= +github.com/testcontainers/testcontainers-go/modules/postgres v0.22.0/go.mod h1:Gv5Gcp3JWOKdCa1CXkC2KZmE9Ofnx6e3bMTD+osHzKQ= +github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg= +github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc h1:9lRDQMhESg+zvGYmW5DyG0UqvY96Bu5QYsTLvCHdrgo= github.com/tmthrgd/go-hex v0.0.0-20190904060850-447a3041c3bc/go.mod h1:bciPuU6GHm1iF1pBvUfxfsH0Wmnc2VbpgvbI9ZWuIRs= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/uptrace/bun v1.1.16 h1:cn9cgEMFwcyYRsQLfxCRMUxyK1WaHwOVrR3TvzEFZ/A= +github.com/uptrace/bun v1.1.16/go.mod h1:7HnsMRRvpLFUcquJxp22JO8PsWKpFQO/gNXqqsuGWg8= +github.com/uptrace/bun/dialect/pgdialect v1.1.16 h1:eUPZ+YCJ69BA+W1X1ZmpOJSkv1oYtinr0zCXf7zCo5g= +github.com/uptrace/bun/dialect/pgdialect v1.1.16/go.mod h1:KQjfx/r6JM0OXfbv0rFrxAbdkPD7idK8VitnjIV9fZI= +github.com/uptrace/bun/driver/pgdriver v1.1.16 h1:b/NiSXk6Ldw7KLfMLbOqIkm4odHd7QiNOCPLqPFJjK4= +github.com/uptrace/bun/driver/pgdriver v1.1.16/go.mod h1:Rmfbc+7lx1z/umjMyAxkOHK81LgnGj71XC5YpA6k1vU= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94= github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= github.com/vmihailenco/msgpack/v5 v5.3.4/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= @@ -255,47 +427,79 @@ github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAh github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ= github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/yhirose/go-peg v0.0.0-20210804202551-de25d6753cf1 h1:7iTmQ0lZwTtfm4XMgP5ezzWMDCjo7GTS0ZgCj6jpVzM= github.com/yhirose/go-peg v0.0.0-20210804202551-de25d6753cf1/go.mod h1:q2QWLflHsZxT6ixYcXveTYicEvxGh5Uv6CnI7f7BfjQ= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.mongodb.org/mongo-driver v1.11.1/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= +go.opentelemetry.io/otel v1.15.0 h1:NIl24d4eiLJPM0vKn4HjLYM+UZf6gSfi9Z+NmCxkWbk= +go.opentelemetry.io/otel v1.15.0/go.mod h1:qfwLEbWhLPk5gyWrne4XnF0lC8wtywbuJbgfAE3zbek= +go.opentelemetry.io/otel/trace v1.15.0 h1:5Fwje4O2ooOxkfyqI/kJwxWotggDLix4BSAvpE1wlpo= +go.opentelemetry.io/otel/trace v1.15.0/go.mod h1:CUsmE2Ht1CRkvE8OsMESvraoZrrcgD1J2W8GV1ev0Y4= go.uber.org/mock v0.2.0 h1:TaP3xedm7JaAgScZO7tlvlKrqT0p7I6OsdGB5YNSMDU= go.uber.org/mock v0.2.0/go.mod h1:J0y0rp9L3xiff1+ZBfKxlC1fz2+aO16tw0tsDOixfuM= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= -golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= -golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.5.0 h1:jpGode6huXQxcskEIpOCvrU+tzo81b6+oFLUYXWtH/Y= +golang.org/x/arch v0.5.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= -golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= +golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea h1:vLCWI/yYrdEHyN2JzIzPO3aaQJHQdp89IZBA/+azVC4= +golang.org/x/exp v0.0.0-20230510235704-dd950f8aeaea/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.9.0 h1:KENHtAZL2y3NLMYZeHY9DW8HW8V+kQyJsY/V9JlKvCs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= 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-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-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= -golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-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/sys v0.0.0-20180830151530-49385e6e1522/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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -303,24 +507,32 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/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-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210923061019-b8560ed6a9b7/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-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/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.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= -golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= +golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= -golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 h1:ftMN5LMiBFjbzleLqtoBZk7KdJwhuybIU+FckUHgoyQ= golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -328,15 +540,28 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm 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-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.7.0 h1:W4OVu8VVOaIO0yzWMNdepAulS7YfoS3Zabrm8DOXXU4= +golang.org/x/tools v0.7.0/go.mod h1:4pg6aUX35JBAogB10C9AtvVL+qowtN4pT3CGSQex14s= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= +google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= 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= @@ -347,9 +572,11 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 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.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/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= @@ -363,12 +590,25 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWD gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/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-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/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw= +gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o= +gorm.io/driver/postgres v1.5.2 h1:ytTDxxEv+MplXOfFe3Lzm7SjG09fcdb3Z/c056DTBx0= +gorm.io/driver/postgres v1.5.2/go.mod h1:fmpX0m2I1PKuR7mKZiEluwrP3hbs+ps7JIGMUBpCgl8= +gorm.io/driver/sqlite v1.5.2 h1:TpQ+/dqCY4uCigCFyrfnrJnrW9zjpelWVoEVNy5qJkc= +gorm.io/driver/sqlite v1.5.2/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4= +gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gorm.io/gorm v1.25.3 h1:zi4rHZj1anhZS2EuEODMhDisGy+Daq9jtPrNGgbQYD8= +gorm.io/gorm v1.25.3/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k= +gotest.tools/v3 v3.5.0 h1:Ljk6PdHdOhAb5aDMWXjDLMMhph+BpztA4v1QdqEW2eY= +gotest.tools/v3 v3.5.0/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= lukechampine.com/blake3 v1.1.6 h1:H3cROdztr7RCfoaTpGZFQsrqvweFLrqS73j7L7cmR5c= @@ -376,4 +616,5 @@ lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R mellium.im/sasl v0.2.1/go.mod h1:ROaEDLQNuf9vjKqE1SrAfnsobm2YKXT1gnN1uDp1PjQ= mellium.im/sasl v0.3.1 h1:wE0LW6g7U83vhvxjC1IY8DnXM+EU095yeo8XClvCdfo= mellium.im/sasl v0.3.1/go.mod h1:xm59PUYpZHhgQ9ZqoJ5QaCqzWMi8IeS49dhp6plPCzw= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/internal/bcd/ast/ast_test.go b/internal/bcd/ast/ast_test.go index fc64b1d55..b70fe1116 100644 --- a/internal/bcd/ast/ast_test.go +++ b/internal/bcd/ast/ast_test.go @@ -12,6 +12,8 @@ import ( ) func TestTypedAst_ToJSONSchema(t *testing.T) { + ts := time.Now().UTC() + tests := []struct { name string data string @@ -185,7 +187,7 @@ func TestTypedAst_ToJSONSchema(t *testing.T) { Prim: "timestamp", Title: "refund_time", Format: "date-time", - Default: time.Now().UTC().Format(time.RFC3339), + Default: ts.Format(time.RFC3339), }, }, }, @@ -605,18 +607,15 @@ func TestTypedAst_ToJSONSchema(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { ta, err := NewTypedAstFromString(tt.data) - if err != nil { - t.Errorf("NewTypedAstFromString error = %v", err) - return - } + require.NoError(t, err) got, err := ta.ToJSONSchema() - if (err != nil) != tt.wantErr { - t.Errorf("TypedAst.ToJSONSchema() error = %v, wantErr %v", err, tt.wantErr) + require.Equal(t, tt.wantErr, err != nil) + if err != nil { return } - assert.Equal(t, tt.want, got) + require.Equal(t, tt.want, got) }) } } diff --git a/internal/bcd/base/node.go b/internal/bcd/base/node.go index 0617c3423..6bdd151af 100644 --- a/internal/bcd/base/node.go +++ b/internal/bcd/base/node.go @@ -8,8 +8,8 @@ import ( "github.com/baking-bad/bcdhub/internal/bcd/consts" "github.com/baking-bad/bcdhub/internal/bcd/types" - "github.com/baking-bad/bcdhub/internal/logger" jsoniter "github.com/json-iterator/go" + "github.com/rs/zerolog/log" ) var json = jsoniter.ConfigCompatibleWithStandardLibrary @@ -126,7 +126,7 @@ func (node *Node) IsLambda() bool { } b, err := hex.DecodeString(input[22:24]) if err != nil { - logger.Err(err) + log.Err(err).Str("input", input).Msg("decoding lambda") return false } if len(b) != 1 { diff --git a/internal/bcd/encoding/base58_test.go b/internal/bcd/encoding/base58_test.go index 577147fb4..0993112ad 100644 --- a/internal/bcd/encoding/base58_test.go +++ b/internal/bcd/encoding/base58_test.go @@ -52,6 +52,10 @@ func TestDecodeBase58String(t *testing.T) { name: "smart rollup commitment hash", data: "src13MtM1eBzxCH1FBhLAkAiWGW6JbjvycLeH6vuz5k9GSiTYTCTja", want: "751b92ce705ebc551917bb488310498e969d7a1261fda86b509e7da2c780ec8d", + }, { + name: "operation", + data: "opMhUv6wNFN1k5DofyPonyts1mSo4cTjCsk19i4Li7reT1oAQ1K", + want: "e1e56182ae0a8738f804ac7edfd199a6ce617a6ee6751a0c69a4ad972098ebc7", }, } for _, tt := range tests { @@ -181,6 +185,11 @@ func TestEncodeBase58String(t *testing.T) { prefix: "src1", data: "751b92ce705ebc551917bb488310498e969d7a1261fda86b509e7da2c780ec8d", want: "src13MtM1eBzxCH1FBhLAkAiWGW6JbjvycLeH6vuz5k9GSiTYTCTja", + }, { + name: "operation", + prefix: "o", + data: "53E4FC89A78AD0D8C5B02A03C679DE44A42ED2EF8283D7CB759DD57877646EBC", + want: "ooHAF4skSPJe5NwF7Xy9tJy4GSGZUDF5UCNfDFQ4GNKjg1uKajf", }, } for _, tt := range tests { diff --git a/internal/bcd/formatter/formatter.go b/internal/bcd/formatter/formatter.go index d77685c56..78ac7934b 100644 --- a/internal/bcd/formatter/formatter.go +++ b/internal/bcd/formatter/formatter.go @@ -26,6 +26,7 @@ func IsFramed(n gjson.Result) bool { "key", "unit", "signature", "operation", "int", "nat", "string", "bytes", "mutez", "bool", "key_hash", "timestamp", "address", "bls12_381_g1", "bls12_381_g2", "bls12_381_fr", "chain_id", "never", + "chest", "chest_key", "tx_rollup_l2_address", }) { return n.Get("annots").Exists() } diff --git a/internal/bcd/formatter/formatter_test.go b/internal/bcd/formatter/formatter_test.go index edf99e8f9..d5a39728f 100644 --- a/internal/bcd/formatter/formatter_test.go +++ b/internal/bcd/formatter/formatter_test.go @@ -97,6 +97,9 @@ func TestMichelineToMichelson(t *testing.T) { "KT1WhouvVKZFH94VXj9pa8v4szvfrBwXoBUj", "KT1XFnSFqmXsBmNQVPByuYYkBFoNcXne4Ktu", "KT1XRwPmdw7j4LhHgTw8S2dTVbmsXqT6VtpX", + "KT1LfmcX6usZoHYNf9LPrBL1sYCGDDeuApJq", + "KT1U4Gb8FjnmyyiUxu4Uy5iFuBRzp4ezbYa7", + "KT1BcTXqU4TW1tPuujvyWYvnUJ2VrpY3WnzY", } for _, tt := range tests { diff --git a/internal/bcd/formatter/formatter_tests/KT1BcTXqU4TW1tPuujvyWYvnUJ2VrpY3WnzY/code_KT1BcT.json b/internal/bcd/formatter/formatter_tests/KT1BcTXqU4TW1tPuujvyWYvnUJ2VrpY3WnzY/code_KT1BcT.json new file mode 100644 index 000000000..f0daa0549 --- /dev/null +++ b/internal/bcd/formatter/formatter_tests/KT1BcTXqU4TW1tPuujvyWYvnUJ2VrpY3WnzY/code_KT1BcT.json @@ -0,0 +1 @@ +[{"prim":"parameter","args":[{"prim":"pair","args":[{"prim":"string"},{"prim":"nat"},{"prim":"tx_rollup_l2_address"},{"prim":"address"}]}]},{"prim":"storage","args":[{"prim":"unit"}]},{"prim":"code","args":[[{"prim":"CAR"},{"prim":"UNPAIR","args":[{"int":"4"}]},{"prim":"TICKET_DEPRECATED"},{"prim":"PAIR"},{"prim":"SWAP"},{"prim":"CONTRACT","args":[{"prim":"pair","args":[{"prim":"ticket","args":[{"prim":"string"}]},{"prim":"tx_rollup_l2_address"}]}],"annots":["%deposit"]},[{"prim":"IF_NONE","args":[[[{"prim":"UNIT"},{"prim":"FAILWITH"}]],[]]}],{"prim":"SWAP"},{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"0"}]},{"prim":"SWAP"},{"prim":"TRANSFER_TOKENS"},{"prim":"UNIT"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"DIG","args":[{"int":"2"}]},{"prim":"CONS"},{"prim":"PAIR"}]]}] \ No newline at end of file diff --git a/internal/bcd/formatter/formatter_tests/KT1BcTXqU4TW1tPuujvyWYvnUJ2VrpY3WnzY/code_KT1BcT.tz b/internal/bcd/formatter/formatter_tests/KT1BcTXqU4TW1tPuujvyWYvnUJ2VrpY3WnzY/code_KT1BcT.tz new file mode 100644 index 000000000..a82baa768 --- /dev/null +++ b/internal/bcd/formatter/formatter_tests/KT1BcTXqU4TW1tPuujvyWYvnUJ2VrpY3WnzY/code_KT1BcT.tz @@ -0,0 +1,18 @@ +parameter (pair string nat tx_rollup_l2_address address); +storage unit; +code { CAR ; + UNPAIR 4 ; + TICKET_DEPRECATED ; + PAIR ; + SWAP ; + CONTRACT %deposit (pair (ticket string) tx_rollup_l2_address) ; + { IF_NONE { { UNIT ; FAILWITH } } {} } ; + SWAP ; + PUSH mutez 0 ; + SWAP ; + TRANSFER_TOKENS ; + UNIT ; + NIL operation ; + DIG 2 ; + CONS ; + PAIR } \ No newline at end of file diff --git a/internal/bcd/formatter/formatter_tests/KT1LfmcX6usZoHYNf9LPrBL1sYCGDDeuApJq/code_KT1Lfm.json b/internal/bcd/formatter/formatter_tests/KT1LfmcX6usZoHYNf9LPrBL1sYCGDDeuApJq/code_KT1Lfm.json new file mode 100644 index 000000000..8dfc24d10 --- /dev/null +++ b/internal/bcd/formatter/formatter_tests/KT1LfmcX6usZoHYNf9LPrBL1sYCGDDeuApJq/code_KT1Lfm.json @@ -0,0 +1 @@ +[{"prim":"parameter","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"chest","annots":["%commit"]},{"prim":"pair","args":[{"prim":"address","annots":["%target"]},{"prim":"chest_key","annots":["%proposedKey"]}],"annots":["%reveal"]}]},{"prim":"unit","annots":["%roll"]}]}]},{"prim":"storage","args":[{"prim":"pair","args":[{"prim":"nat","annots":["%lotterykey"]},{"prim":"pair","args":[{"prim":"nat","annots":["%chest_time"]},{"prim":"map","args":[{"prim":"address"},{"prim":"pair","args":[{"prim":"chest","annots":["%randomhash"]},{"prim":"bool","annots":["%revealed"]}]}],"annots":["%participants"]}]}]}]},{"prim":"code","args":[[{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"DIG","args":[{"int":"1"}]},{"prim":"UNPAIR"},{"prim":"DIP","args":[[{"prim":"UNPAIR","args":[{"int":"3"}]}]]},{"prim":"IF_LEFT","args":[[{"prim":"IF_LEFT","args":[[{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"1000000"}]},{"prim":"AMOUNT"},{"prim":"COMPARE"},{"prim":"GE"},{"prim":"NOT"},{"prim":"IF","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"Entry cost is 1tz"}]},{"prim":"FAILWITH"}],[]]},{"prim":"DUP","args":[{"int":"4"}]},{"prim":"SENDER"},{"prim":"MEM"},{"prim":"IF","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"participants"}]},{"prim":"PUSH","args":[{"prim":"string"},{"string":"KeyExists"}]},{"prim":"PAIR"},{"prim":"FAILWITH"}],[{"prim":"DUP","args":[{"int":"4"}]},{"prim":"PUSH","args":[{"prim":"bool"},{"prim":"False"}]},{"prim":"DUP","args":[{"int":"3"}]},{"prim":"PAIR"},{"prim":"SOME"},{"prim":"SENDER"},{"prim":"UPDATE"},{"prim":"DIP","args":[[{"prim":"DIG","args":[{"int":"3"}]},{"prim":"DROP"}]]},{"prim":"DUG","args":[{"int":"3"}]}]]},{"prim":"DROP"},{"prim":"PAIR","args":[{"int":"3"}]},{"prim":"DIG","args":[{"int":"1"}]},{"prim":"PAIR"}],[{"prim":"UNPAIR"},{"prim":"SWAP"},{"prim":"PUSH","args":[{"prim":"timestamp"},{"int":"1654436582"}]},{"prim":"NOW"},{"prim":"COMPARE"},{"prim":"LT"},{"prim":"IF","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"The lottery has been closed"}]},{"prim":"FAILWITH"}],[]]},{"prim":"DUP","args":[{"int":"5"}]},{"prim":"SENDER"},{"prim":"GET"},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"participants"}]},{"prim":"PUSH","args":[{"prim":"string"},{"string":"AssetNotFound"}]},{"prim":"PAIR"},{"prim":"FAILWITH"}],[]]},{"prim":"CDR"},{"prim":"IF","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"You have already revealed your key"}]},{"prim":"FAILWITH"}],[]]},{"prim":"DUP","args":[{"int":"4"}]},{"prim":"DUP","args":[{"int":"6"}]},{"prim":"DUP","args":[{"int":"4"}]},{"prim":"GET"},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"participants"}]},{"prim":"PUSH","args":[{"prim":"string"},{"string":"AssetNotFound"}]},{"prim":"PAIR"},{"prim":"FAILWITH"}],[]]},{"prim":"CAR"},{"prim":"DUP","args":[{"int":"3"}]},{"prim":"OPEN_CHEST"},{"prim":"IF_LEFT","args":[[{"prim":"DUP"},{"prim":"UNPACK","args":[{"prim":"nat"}]},{"prim":"IF_NONE","args":[[{"prim":"DUP","args":[{"int":"6"}]},{"prim":"NONE","args":[{"prim":"pair","args":[{"prim":"chest"},{"prim":"bool"}]}]},{"prim":"DUP","args":[{"int":"5"}]},{"prim":"UPDATE"},{"prim":"DIP","args":[[{"prim":"DIG","args":[{"int":"5"}]},{"prim":"DROP"}]]},{"prim":"DUG","args":[{"int":"5"}]}],[{"prim":"DUP"},{"prim":"DUP","args":[{"int":"6"}]},{"prim":"ADD"},{"prim":"DIP","args":[[{"prim":"DIG","args":[{"int":"4"}]},{"prim":"DROP"}]]},{"prim":"DUG","args":[{"int":"4"}]},{"prim":"DUP","args":[{"int":"7"}]},{"prim":"DUP","args":[{"int":"8"}]},{"prim":"SENDER"},{"prim":"GET"},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"participants"}]},{"prim":"PUSH","args":[{"prim":"string"},{"string":"AssetNotFound"}]},{"prim":"PAIR"},{"prim":"FAILWITH"}],[]]},{"prim":"UNPAIR"},{"prim":"SWAP"},{"prim":"DROP"},{"prim":"PUSH","args":[{"prim":"bool"},{"prim":"True"}]},{"prim":"SWAP"},{"prim":"PAIR"},{"prim":"SOME"},{"prim":"SENDER"},{"prim":"UPDATE"},{"prim":"DIP","args":[[{"prim":"DIG","args":[{"int":"6"}]},{"prim":"DROP"}]]},{"prim":"DUG","args":[{"int":"6"}]},{"prim":"DROP"}]]},{"prim":"DROP"}],[{"prim":"DUP"},{"prim":"IF","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"INVALID_CHEST_KEY"}]},{"prim":"FAILWITH"}],[{"prim":"DUP","args":[{"int":"6"}]},{"prim":"NONE","args":[{"prim":"pair","args":[{"prim":"chest"},{"prim":"bool"}]}]},{"prim":"DUP","args":[{"int":"5"}]},{"prim":"UPDATE"},{"prim":"DIP","args":[[{"prim":"DIG","args":[{"int":"5"}]},{"prim":"DROP"}]]},{"prim":"DUG","args":[{"int":"5"}]}]]},{"prim":"DROP"}]]},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"DUP","args":[{"int":"8"}]},{"prim":"ITER","args":[[{"prim":"CONS"}]]},{"prim":"SENDER"},{"prim":"CONTRACT","args":[{"prim":"unit"}]},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"EntryNotFound"}]},{"prim":"FAILWITH"}],[]]},{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"350000"}]},{"prim":"UNIT"},{"prim":"TRANSFER_TOKENS"},{"prim":"CONS"},{"prim":"ITER","args":[[{"prim":"CONS"}]]},{"prim":"DIP","args":[[{"prim":"DIG","args":[{"int":"5"}]},{"prim":"DROP"}]]},{"prim":"DUG","args":[{"int":"5"}]},{"prim":"DROP","args":[{"int":"2"}]},{"prim":"PAIR","args":[{"int":"3"}]},{"prim":"DIG","args":[{"int":"1"}]},{"prim":"PAIR"}]]}],[{"prim":"DROP"},{"prim":"PUSH","args":[{"prim":"address"},{"string":"tz1f8jaMYrtQ1qRv7JG5ZX6AJEtTzaDUT2vk"}]},{"prim":"SENDER"},{"prim":"COMPARE"},{"prim":"EQ"},{"prim":"NOT"},{"prim":"IF","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"InvalidCaller"}]},{"prim":"FAILWITH"}],[]]},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"DUP","args":[{"int":"6"}]},{"prim":"ITER","args":[[{"prim":"CONS"}]]},{"prim":"NONE","args":[{"prim":"address"}]},{"prim":"PUSH","args":[{"prim":"nat"},{"int":"0"}]},{"prim":"PAIR"},{"prim":"DUP","args":[{"int":"6"}]},{"prim":"ITER","args":[[{"prim":"UNPAIR"},{"prim":"DUP","args":[{"int":"8"}]},{"prim":"SIZE"},{"prim":"INT"},{"prim":"DUP","args":[{"int":"7"}]},{"prim":"INT"},{"prim":"EDIV"},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"DivByZero"}]},{"prim":"FAILWITH"}],[{"prim":"DUP"},{"prim":"CDR"},{"prim":"SWAP"},{"prim":"DROP"}]]},{"prim":"DUP","args":[{"int":"4"}]},{"prim":"CAR"},{"prim":"COMPARE"},{"prim":"EQ"},{"prim":"IF","args":[[{"prim":"DUP"},{"prim":"SOME"},{"prim":"PUSH","args":[{"prim":"nat"},{"int":"1"}]},{"prim":"DUP","args":[{"int":"5"}]},{"prim":"CAR"},{"prim":"ADD"},{"prim":"PAIR"}],[{"prim":"DUP","args":[{"int":"3"}]},{"prim":"CDR"},{"prim":"PUSH","args":[{"prim":"nat"},{"int":"1"}]},{"prim":"DUP","args":[{"int":"5"}]},{"prim":"CAR"},{"prim":"ADD"},{"prim":"PAIR"}]]},{"prim":"DIP","args":[[{"prim":"DIG","args":[{"int":"2"}]},{"prim":"DROP"}]]},{"prim":"DUG","args":[{"int":"2"}]},{"prim":"DROP","args":[{"int":"2"}]}]]},{"prim":"CDR"},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"NotFound"}]},{"prim":"FAILWITH"}],[]]},{"prim":"CONTRACT","args":[{"prim":"unit"}]},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"EntryNotFound"}]},{"prim":"FAILWITH"}],[]]},{"prim":"BALANCE"},{"prim":"UNIT"},{"prim":"TRANSFER_TOKENS"},{"prim":"CONS"},{"prim":"ITER","args":[[{"prim":"CONS"}]]},{"prim":"DIP","args":[[{"prim":"DIG","args":[{"int":"3"}]},{"prim":"DROP"}]]},{"prim":"DUG","args":[{"int":"3"}]},{"prim":"PAIR","args":[{"int":"3"}]},{"prim":"DIG","args":[{"int":"1"}]},{"prim":"PAIR"}]]}]]}] \ No newline at end of file diff --git a/internal/bcd/formatter/formatter_tests/KT1LfmcX6usZoHYNf9LPrBL1sYCGDDeuApJq/code_KT1Lfm.tz b/internal/bcd/formatter/formatter_tests/KT1LfmcX6usZoHYNf9LPrBL1sYCGDDeuApJq/code_KT1Lfm.tz new file mode 100644 index 000000000..3897fbf15 --- /dev/null +++ b/internal/bcd/formatter/formatter_tests/KT1LfmcX6usZoHYNf9LPrBL1sYCGDDeuApJq/code_KT1Lfm.tz @@ -0,0 +1,175 @@ +parameter (or (or (chest %commit) (pair %reveal (address %target) (chest_key %proposedKey))) + (unit %roll)); +storage (pair (nat %lotterykey) + (pair (nat %chest_time) + (map %participants address (pair (chest %randomhash) (bool %revealed))))); +code { NIL operation ; + DIG 1 ; + UNPAIR ; + DIP { UNPAIR 3 } ; + IF_LEFT + { IF_LEFT + { PUSH mutez 1000000 ; + AMOUNT ; + COMPARE ; + GE ; + NOT ; + IF { PUSH string "Entry cost is 1tz" ; FAILWITH } {} ; + DUP 4 ; + SENDER ; + MEM ; + IF + { PUSH string "participants" ; PUSH string "KeyExists" ; PAIR ; FAILWITH } + { DUP 4 ; + PUSH bool False ; + DUP 3 ; + PAIR ; + SOME ; + SENDER ; + UPDATE ; + DIP { DIG 3 ; DROP } ; + DUG 3 } ; + DROP ; + PAIR 3 ; + DIG 1 ; + PAIR } + { UNPAIR ; + SWAP ; + PUSH timestamp 1654436582 ; + NOW ; + COMPARE ; + LT ; + IF { PUSH string "The lottery has been closed" ; FAILWITH } {} ; + DUP 5 ; + SENDER ; + GET ; + IF_NONE + { PUSH string "participants" ; PUSH string "AssetNotFound" ; PAIR ; FAILWITH } + {} ; + CDR ; + IF { PUSH string "You have already revealed your key" ; FAILWITH } {} ; + DUP 4 ; + DUP 6 ; + DUP 4 ; + GET ; + IF_NONE + { PUSH string "participants" ; PUSH string "AssetNotFound" ; PAIR ; FAILWITH } + {} ; + CAR ; + DUP 3 ; + OPEN_CHEST ; + IF_LEFT + { DUP ; + UNPACK nat ; + IF_NONE + { DUP 6 ; + NONE (pair chest bool) ; + DUP 5 ; + UPDATE ; + DIP { DIG 5 ; DROP } ; + DUG 5 } + { DUP ; + DUP 6 ; + ADD ; + DIP { DIG 4 ; DROP } ; + DUG 4 ; + DUP 7 ; + DUP 8 ; + SENDER ; + GET ; + IF_NONE + { PUSH string "participants" ; + PUSH string "AssetNotFound" ; + PAIR ; + FAILWITH } + {} ; + UNPAIR ; + SWAP ; + DROP ; + PUSH bool True ; + SWAP ; + PAIR ; + SOME ; + SENDER ; + UPDATE ; + DIP { DIG 6 ; DROP } ; + DUG 6 ; + DROP } ; + DROP } + { DUP ; + IF + { PUSH string "INVALID_CHEST_KEY" ; FAILWITH } + { DUP 6 ; + NONE (pair chest bool) ; + DUP 5 ; + UPDATE ; + DIP { DIG 5 ; DROP } ; + DUG 5 } ; + DROP } ; + NIL operation ; + NIL operation ; + DUP 8 ; + ITER { CONS } ; + SENDER ; + CONTRACT unit ; + IF_NONE { PUSH string "EntryNotFound" ; FAILWITH } {} ; + PUSH mutez 350000 ; + UNIT ; + TRANSFER_TOKENS ; + CONS ; + ITER { CONS } ; + DIP { DIG 5 ; DROP } ; + DUG 5 ; + DROP 2 ; + PAIR 3 ; + DIG 1 ; + PAIR } } + { DROP ; + PUSH address "tz1f8jaMYrtQ1qRv7JG5ZX6AJEtTzaDUT2vk" ; + SENDER ; + COMPARE ; + EQ ; + NOT ; + IF { PUSH string "InvalidCaller" ; FAILWITH } {} ; + NIL operation ; + NIL operation ; + DUP 6 ; + ITER { CONS } ; + NONE address ; + PUSH nat 0 ; + PAIR ; + DUP 6 ; + ITER { UNPAIR ; + DUP 8 ; + SIZE ; + INT ; + DUP 7 ; + INT ; + EDIV ; + IF_NONE + { PUSH string "DivByZero" ; FAILWITH } + { DUP ; CDR ; SWAP ; DROP } ; + DUP 4 ; + CAR ; + COMPARE ; + EQ ; + IF + { DUP ; SOME ; PUSH nat 1 ; DUP 5 ; CAR ; ADD ; PAIR } + { DUP 3 ; CDR ; PUSH nat 1 ; DUP 5 ; CAR ; ADD ; PAIR } ; + DIP { DIG 2 ; DROP } ; + DUG 2 ; + DROP 2 } ; + CDR ; + IF_NONE { PUSH string "NotFound" ; FAILWITH } {} ; + CONTRACT unit ; + IF_NONE { PUSH string "EntryNotFound" ; FAILWITH } {} ; + BALANCE ; + UNIT ; + TRANSFER_TOKENS ; + CONS ; + ITER { CONS } ; + DIP { DIG 3 ; DROP } ; + DUG 3 ; + PAIR 3 ; + DIG 1 ; + PAIR } } \ No newline at end of file diff --git a/internal/bcd/formatter/formatter_tests/KT1U4Gb8FjnmyyiUxu4Uy5iFuBRzp4ezbYa7/code_KT1U4G.json b/internal/bcd/formatter/formatter_tests/KT1U4Gb8FjnmyyiUxu4Uy5iFuBRzp4ezbYa7/code_KT1U4G.json new file mode 100644 index 000000000..59b8027c9 --- /dev/null +++ b/internal/bcd/formatter/formatter_tests/KT1U4Gb8FjnmyyiUxu4Uy5iFuBRzp4ezbYa7/code_KT1U4G.json @@ -0,0 +1 @@ +[{"prim":"parameter","args":[{"prim":"or","args":[{"prim":"unit","annots":["%auto_call"]},{"prim":"ticket","args":[{"prim":"int"}],"annots":["%run"]}]}]},{"prim":"storage","args":[{"prim":"pair","args":[{"prim":"option","args":[{"prim":"ticket","args":[{"prim":"int"}]}],"annots":["%x"]},{"prim":"option","args":[{"prim":"ticket","args":[{"prim":"string"}]}],"annots":["%y"]}]}]},{"prim":"code","args":[[{"prim":"UNPAIR"},{"prim":"IF_LEFT","args":[[{"prim":"DROP"},{"prim":"PUSH","args":[{"prim":"nat"},{"int":"43"}]},{"prim":"PUSH","args":[{"prim":"int"},{"int":"1"}]},{"prim":"TICKET_DEPRECATED"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"SELF","annots":["%run"]},{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"0"}]},{"prim":"DIG","args":[{"int":"3"}]},{"prim":"TRANSFER_TOKENS"},{"prim":"CONS"}],[{"prim":"READ_TICKET"},{"prim":"PUSH","args":[{"prim":"nat"},{"int":"42"}]},{"prim":"PUSH","args":[{"prim":"string"},{"string":"abc"}]},{"prim":"TICKET_DEPRECATED"},{"prim":"DIG","args":[{"int":"3"}]},{"prim":"SWAP"},{"prim":"SOME"},{"prim":"SWAP"},{"prim":"CAR"},{"prim":"PAIR"},{"prim":"DUG","args":[{"int":"2"}]},{"prim":"GET","args":[{"int":"4"}]},{"prim":"DUP"},{"prim":"PUSH","args":[{"prim":"nat"},{"int":"3"}]},{"prim":"SWAP"},{"prim":"EDIV"},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"int"},{"int":"20"}]},{"prim":"FAILWITH"}],[{"prim":"CAR"}]]},{"prim":"SWAP"},{"prim":"DUP"},{"prim":"DUG","args":[{"int":"2"}]},{"prim":"SUB"},{"prim":"ISNAT"},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"int"},{"int":"20"}]},{"prim":"FAILWITH"}],[]]},{"prim":"PUSH","args":[{"prim":"nat"},{"int":"3"}]},{"prim":"DIG","args":[{"int":"2"}]},{"prim":"EDIV"},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"int"},{"int":"20"}]},{"prim":"FAILWITH"}],[{"prim":"CAR"}]]},{"prim":"PAIR"},{"prim":"SWAP"},{"prim":"SPLIT_TICKET"},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"int"},{"int":"20"}]},{"prim":"FAILWITH"}],[]]},{"prim":"UNPAIR"},{"prim":"SWAP"},{"prim":"PAIR"},{"prim":"JOIN_TICKETS"},{"prim":"SWAP"},{"prim":"CDR"},{"prim":"SWAP"},{"prim":"PAIR"},{"prim":"NIL","args":[{"prim":"operation"}]}]]},{"prim":"PAIR"}]]}] \ No newline at end of file diff --git a/internal/bcd/formatter/formatter_tests/KT1U4Gb8FjnmyyiUxu4Uy5iFuBRzp4ezbYa7/code_KT1U4G.tz b/internal/bcd/formatter/formatter_tests/KT1U4Gb8FjnmyyiUxu4Uy5iFuBRzp4ezbYa7/code_KT1U4G.tz new file mode 100644 index 000000000..1e6766599 --- /dev/null +++ b/internal/bcd/formatter/formatter_tests/KT1U4Gb8FjnmyyiUxu4Uy5iFuBRzp4ezbYa7/code_KT1U4G.tz @@ -0,0 +1,55 @@ +parameter (or (unit %auto_call) (ticket %run int)); +storage (pair (option %x (ticket int)) (option %y (ticket string))); +code { UNPAIR ; + IF_LEFT + { DROP ; + PUSH nat 43 ; + PUSH int 1 ; + TICKET_DEPRECATED ; + NIL operation ; + SELF %run ; + PUSH mutez 0 ; + DIG 3 ; + TRANSFER_TOKENS ; + CONS } + { READ_TICKET ; + PUSH nat 42 ; + PUSH string "abc" ; + TICKET_DEPRECATED ; + DIG 3 ; + SWAP ; + SOME ; + SWAP ; + CAR ; + PAIR ; + DUG 2 ; + GET 4 ; + DUP ; + PUSH nat 3 ; + SWAP ; + EDIV ; + IF_NONE { PUSH int 20 ; FAILWITH } { CAR } ; + SWAP ; + DUP ; + DUG 2 ; + SUB ; + ISNAT ; + IF_NONE { PUSH int 20 ; FAILWITH } {} ; + PUSH nat 3 ; + DIG 2 ; + EDIV ; + IF_NONE { PUSH int 20 ; FAILWITH } { CAR } ; + PAIR ; + SWAP ; + SPLIT_TICKET ; + IF_NONE { PUSH int 20 ; FAILWITH } {} ; + UNPAIR ; + SWAP ; + PAIR ; + JOIN_TICKETS ; + SWAP ; + CDR ; + SWAP ; + PAIR ; + NIL operation } ; + PAIR } \ No newline at end of file diff --git a/internal/bcd/raw_script.go b/internal/bcd/raw_script.go index 65043cf69..21b0428a3 100644 --- a/internal/bcd/raw_script.go +++ b/internal/bcd/raw_script.go @@ -10,10 +10,10 @@ import ( // RawScript - type RawScript struct { - Code []byte - Parameter []byte - Storage []byte - Views []byte + Code []byte `json:"-"` + Parameter []byte `json:"-"` + Storage []byte `json:"-"` + Views []byte `json:"-"` } type prim struct { diff --git a/internal/bcd/tezerrors/error.go b/internal/bcd/tezerrors/error.go index ab4b0f58e..91a92df86 100644 --- a/internal/bcd/tezerrors/error.go +++ b/internal/bcd/tezerrors/error.go @@ -6,7 +6,6 @@ import ( "fmt" "strings" - "encoding/hex" stdJSON "encoding/json" jsoniter "github.com/json-iterator/go" @@ -39,17 +38,11 @@ func (e *Errors) Scan(value interface{}) error { return fmt.Errorf("pg: can't parse bytea: %q", tmp) } - if tmp[0] != '\\' || tmp[1] != 'x' { - return fmt.Errorf("pg: can't parse bytea: %q", tmp) - } - tmp = tmp[2:] - - b := make([]byte, len(tmp)) - if _, err := hex.Decode(b, tmp); err != nil { - return err + if tmp[0] == '\\' && tmp[1] == 'x' { + tmp = tmp[2:] } - return json.Unmarshal(b, e) + return json.Unmarshal(tmp, e) } // Value return json value, implement driver.Valuer interface diff --git a/internal/bcd/tezerrors/error_test.go b/internal/bcd/tezerrors/error_test.go index 877da51b9..7c0483309 100644 --- a/internal/bcd/tezerrors/error_test.go +++ b/internal/bcd/tezerrors/error_test.go @@ -286,3 +286,23 @@ func TestInvalidSyntacticConstantError_Parse(t *testing.T) { }) } } + +func TestErrors_Scan(t *testing.T) { + tests := []struct { + name string + e Errors + value interface{} + }{ + { + name: "Test 1", + e: make(Errors, 0), + value: []byte(`[{"id":"proto.011-PtHangz2.contract.non_existing_contract","kind":"temporary","title":"Non existing contract","descr":"A contract handle is not present in the context (either it never was or it has been destroyed)"}]`), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.e.Scan(tt.value) + require.NoError(t, err) + }) + } +} diff --git a/internal/bcd/translator/converter.go b/internal/bcd/translator/converter.go index 5c06c88c4..6e5fa6e5b 100644 --- a/internal/bcd/translator/converter.go +++ b/internal/bcd/translator/converter.go @@ -4,7 +4,7 @@ import ( "os" "regexp" - "github.com/baking-bad/bcdhub/internal/logger" + "github.com/rs/zerolog/log" "github.com/yhirose/go-peg" ) @@ -71,11 +71,11 @@ func (c Converter) FromString(input string) (string, error) { func (c Converter) trace() { if c.debug { c.parser.TracerEnter = func(name string, s string, v *peg.Values, d peg.Any, p int) { - logger.Info().Msgf("Enter: %s %d %d %s", name, p, len(s), s[p:]) + log.Info().Msgf("Enter: %s %d %d %s", name, p, len(s), s[p:]) } c.parser.TracerLeave = func(name string, s string, v *peg.Values, d peg.Any, p int, l int) { if l != -1 { - logger.Info().Msgf("Leave: %s %d %d", name, len(s), l+p) + log.Info().Msgf("Leave: %s %d %d", name, len(s), l+p) } } } diff --git a/internal/cache/cache.go b/internal/cache/cache.go index 43abaaccf..f39176a45 100644 --- a/internal/cache/cache.go +++ b/internal/cache/cache.go @@ -41,45 +41,22 @@ func NewCache(rpc noderpc.INode, accounts account.Repository, contracts contract } } -// Alias - -func (cache *Cache) Alias(address string) string { - if !bcd.IsContract(address) { - return "" - } - key := fmt.Sprintf("alias:%s", address) - item, err := cache.Fetch(key, time.Minute*30, func() (interface{}, error) { - acc, err := cache.accounts.Get(address) - if err == nil && acc.Alias != "" { - return acc.Alias, nil - } - - return "", err - }) - if err != nil { - return "" - } - - if data, ok := item.Value().(string); ok && data != "" { - return cache.sanitizer.Sanitize(data) - } - return "" -} - // ContractTags - -func (cache *Cache) ContractTags(address string) (types.Tags, error) { +func (cache *Cache) ContractTags(ctx context.Context, address string) (types.Tags, error) { if !bcd.IsContract(address) { return 0, nil } key := fmt.Sprintf("contract:%s", address) item, err := cache.Fetch(key, time.Minute*10, func() (interface{}, error) { - c, err := cache.contracts.Get(address) + c, err := cache.contracts.Get(ctx, address) if err != nil { return 0, err } return c.Tags, nil }) if err != nil { + cache.Delete(key) return 0, err } return item.Value().(types.Tags), nil @@ -92,35 +69,50 @@ func (cache *Cache) TezosBalance(ctx context.Context, address string, level int6 return cache.rpc.GetContractBalance(ctx, address, level) }) if err != nil { + cache.Delete(key) return 0, err } return item.Value().(int64), nil } // StorageTypeBytes - -func (cache *Cache) StorageTypeBytes(address, symLink string) ([]byte, error) { +func (cache *Cache) StorageTypeBytes(ctx context.Context, address, symLink string) ([]byte, error) { if !bcd.IsContract(address) { return nil, nil } key := fmt.Sprintf("storage:%s", address) item, err := cache.Fetch(key, 5*time.Minute, func() (interface{}, error) { - return cache.contracts.ScriptPart(address, symLink, consts.STORAGE) + return cache.contracts.ScriptPart(ctx, address, symLink, consts.STORAGE) }) if err != nil { + cache.Delete(key) return nil, err } return item.Value().([]byte), nil } // ProtocolByID - -func (cache *Cache) ProtocolByID(id int64) (protocol.Protocol, error) { +func (cache *Cache) ProtocolByID(ctx context.Context, id int64) (protocol.Protocol, error) { key := fmt.Sprintf("protocol_id:%d", id) item, err := cache.Fetch(key, time.Hour, func() (interface{}, error) { - return cache.protocols.GetByID(id) + return cache.protocols.GetByID(ctx, id) }) if err != nil { + cache.Delete(key) return protocol.Protocol{}, err } return item.Value().(protocol.Protocol), nil } + +func (cache *Cache) Script(ctx context.Context, address, symLink string) (contract.Script, error) { + key := fmt.Sprintf("script:%s:%s", address, symLink) + item, err := cache.Fetch(key, time.Hour, func() (interface{}, error) { + return cache.contracts.Script(ctx, address, symLink) + }) + if err != nil { + cache.Delete(key) + return contract.Script{}, err + } + return item.Value().(contract.Script), nil +} diff --git a/internal/config/config.go b/internal/config/config.go index 9ecbfaaf6..772ee3069 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -6,6 +6,7 @@ import ( "regexp" "github.com/baking-bad/bcdhub/internal/periodic" + "github.com/baking-bad/bcdhub/internal/postgres/core" "gopkg.in/yaml.v3" ) @@ -27,6 +28,7 @@ type Config struct { SharePath string `yaml:"share_path"` BaseURL string `yaml:"base_url"` Profiler *Profiler `yaml:"profiler"` + LogLevel string `yaml:"log_level"` API APIConfig `yaml:"api"` @@ -34,12 +36,10 @@ type Config struct { Networks map[string]IndexerConfig `yaml:"networks"` ProjectName string `yaml:"project_name"` SentryEnabled bool `yaml:"sentry_enabled"` - Connections Connections `yaml:"connections"` } `yaml:"indexer"` Scripts struct { - Networks []string `yaml:"networks"` - Connections Connections `yaml:"connections"` + Networks []string `yaml:"networks"` } `yaml:"scripts"` } @@ -77,9 +77,9 @@ type ServiceConfig struct { // StorageConfig - type StorageConfig struct { - Postgres PostgresConfig `yaml:"pg"` - Timeout int `yaml:"timeout"` - LogQueries bool `yaml:"log_queries,omitempty"` + Postgres core.Config `yaml:"pg"` + Timeout int `yaml:"timeout"` + LogQueries bool `yaml:"log_queries,omitempty"` } // PostgresConfig - @@ -142,17 +142,6 @@ type SeedConfig struct { AvatarURL string `yaml:"avatar_url"` Token string `yaml:"token"` } `yaml:"user"` - Subscriptions []struct { - Address string `yaml:"address"` - Network string `yaml:"network"` - Alias string `yaml:"alias"` - WatchMask uint `yaml:"watch_mask"` - } `yaml:"subscriptions"` - Aliases []struct { - Alias string `yaml:"alias"` - Network string `yaml:"network"` - Address string `yaml:"address"` - } `yaml:"aliases"` Accounts []struct { PrivateKey string `yaml:"private_key"` PublicKeyHash string `yaml:"public_key_hash"` @@ -171,7 +160,6 @@ type APIConfig struct { Seed SeedConfig `yaml:"seed"` Networks []string `yaml:"networks"` PageSize uint64 `yaml:"page_size"` - Connections Connections `yaml:"connections"` Periodic *periodic.Config `yaml:"periodic"` } @@ -186,12 +174,6 @@ type SentryConfig struct { // TezosDomainsConfig - type TezosDomainsConfig map[string]string -// Connections - -type Connections struct { - Open int `yaml:"open"` - Idle int `yaml:"idle"` -} - // LoadDefaultConfig - func LoadDefaultConfig() (Config, error) { configurations := map[string]string{ diff --git a/internal/config/context.go b/internal/config/context.go index 855600c40..9fe24024b 100644 --- a/internal/config/context.go +++ b/internal/config/context.go @@ -2,7 +2,6 @@ package config import ( "github.com/baking-bad/bcdhub/internal/cache" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models" "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/bigmapaction" @@ -14,13 +13,14 @@ import ( "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/protocol" smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" + "github.com/baking-bad/bcdhub/internal/models/stats" "github.com/baking-bad/bcdhub/internal/models/ticket" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" - "github.com/baking-bad/bcdhub/internal/postgres" "github.com/baking-bad/bcdhub/internal/postgres/core" "github.com/baking-bad/bcdhub/internal/services/mempool" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) // Context - @@ -44,11 +44,11 @@ type Context struct { Migrations migration.Repository Operations operation.Repository Protocols protocol.Repository - TicketUpdates ticket.Repository + Tickets ticket.Repository Domains domains.Repository Scripts contract.ScriptRepository SmartRollups smartrollup.Repository - Partitions *postgres.PartitionManager + Stats stats.Repository Cache *cache.Cache } @@ -93,7 +93,7 @@ func NewContexts(cfg Config, networks []string, opts ...ContextOption) Contexts for i := range networks { networkType := types.NewNetwork(networks[i]) if networkType == types.Empty { - logger.Warning().Msgf("unknown network: %s", networks[i]) + log.Warn().Str("network", networks[i]).Msg("unknown network") continue } ctxs[networkType] = NewContext(networkType, opts...) diff --git a/internal/config/options.go b/internal/config/options.go index 5866f3b6c..4742fef26 100644 --- a/internal/config/options.go +++ b/internal/config/options.go @@ -4,7 +4,6 @@ import ( "time" "github.com/baking-bad/bcdhub/internal/bcd/tezerrors" - "github.com/baking-bad/bcdhub/internal/postgres" "github.com/baking-bad/bcdhub/internal/postgres/account" "github.com/baking-bad/bcdhub/internal/postgres/bigmapdiff" "github.com/baking-bad/bcdhub/internal/postgres/contract" @@ -14,6 +13,7 @@ import ( "github.com/baking-bad/bcdhub/internal/postgres/operation" "github.com/baking-bad/bcdhub/internal/postgres/protocol" smartrollup "github.com/baking-bad/bcdhub/internal/postgres/smart_rollup" + "github.com/baking-bad/bcdhub/internal/postgres/stats" "github.com/baking-bad/bcdhub/internal/postgres/ticket" "github.com/baking-bad/bcdhub/internal/services/mempool" @@ -68,7 +68,7 @@ func WithWaitRPC(rpcConfig map[string]RPCConfig) ContextOption { } // WithStorage - -func WithStorage(cfg StorageConfig, appName string, maxPageSize int64, maxConnCount, idleConnCount int, createDatabaseIfNotExists bool) ContextOption { +func WithStorage(cfg StorageConfig, appName string, maxPageSize int64) ContextOption { return func(ctx *Context) { if len(cfg.Postgres.Host) == 0 { panic("Please set connection strings to storage in config") @@ -76,8 +76,6 @@ func WithStorage(cfg StorageConfig, appName string, maxPageSize int64, maxConnCo opts := []pgCore.PostgresOption{ pgCore.WithPageSize(maxPageSize), - pgCore.WithIdleConnections(idleConnCount), - pgCore.WithMaxConnections(maxConnCount), } if cfg.LogQueries { @@ -85,7 +83,7 @@ func WithStorage(cfg StorageConfig, appName string, maxPageSize int64, maxConnCo } conn := pgCore.WaitNew( - cfg.Postgres.ConnectionString(), ctx.Network.String(), + cfg.Postgres, ctx.Network.String(), appName, cfg.Timeout, opts..., ) @@ -102,10 +100,10 @@ func WithStorage(cfg StorageConfig, appName string, maxPageSize int64, maxConnCo ctx.Protocols = protocol.NewStorage(conn) ctx.GlobalConstants = global_constant.NewStorage(conn) ctx.Domains = domains.NewStorage(conn) - ctx.TicketUpdates = ticket.NewStorage(conn) + ctx.Tickets = ticket.NewStorage(conn) ctx.Scripts = contractStorage ctx.SmartRollups = smartrollup.NewStorage(conn) - ctx.Partitions = postgres.NewPartitionManager(conn) + ctx.Stats = stats.NewStorage(conn) } } diff --git a/internal/helpers/sentry.go b/internal/helpers/sentry.go index a7ae4c904..e127c06a8 100644 --- a/internal/helpers/sentry.go +++ b/internal/helpers/sentry.go @@ -3,11 +3,11 @@ package helpers import ( "time" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/getsentry/sentry-go" sentrygin "github.com/getsentry/sentry-go/gin" "github.com/gin-gonic/gin" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) // InitSentry - @@ -19,12 +19,12 @@ func InitSentry(debug bool, environment, dsn string) { AttachStacktrace: true, BeforeSend: beforeSend, }); err != nil { - logger.Info().Msgf("Sentry initialization failed: %v\n", err) + log.Err(err).Msg("Sentry initialization failed") } } func beforeSend(event *sentry.Event, hint *sentry.EventHint) *sentry.Event { - logger.Info().Msgf("[Sentry message] %s", event.Message) + log.Info().Msgf("[Sentry message] %s", event.Message) return event } diff --git a/internal/logger/logger.go b/internal/logger/logger.go index 0067d0b5c..ddd235a37 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -1,13 +1,9 @@ package logger import ( - "bufio" - "bytes" - "encoding/json" "fmt" "os" - "runtime" - "strings" + "strconv" "github.com/fatih/color" "github.com/rs/zerolog" @@ -19,9 +15,7 @@ type Loggable interface { LogFields() map[string]interface{} } -var logger = newBCDLogger() - -func newBCDLogger() zerolog.Logger { +func New(level string) { consoleWriter := zerolog.ConsoleWriter{Out: os.Stderr} switch os.Getenv("BCD_ENV") { @@ -32,107 +26,35 @@ func newBCDLogger() zerolog.Logger { return "" } } - zerolog.SetGlobalLevel(zerolog.InfoLevel) - return log.Output(consoleWriter) -} - -// Info - -func Info() *zerolog.Event { - return logger.Info() -} - -// Warning - -func Warning() *zerolog.Event { - return logger.Warn() -} - -// Error - -func Error() *zerolog.Event { - return logger.Error() -} - -// Err - -func Err(err error) { - logger.Error().Err(err).Msg("") -} -// Fatal - -func Fatal() *zerolog.Event { - return logger.Fatal() -} - -// Debug - -func Debug(values ...interface{}) { - if len(values) == 0 { - return - } - _, file, line, ok := runtime.Caller(1) - if !ok { - fmt.Printf("[DEBUG] can't capture stack for dump\n") - return - } - targetFile, openErr := os.Open(file) - if openErr != nil { - fmt.Printf("[DEBUG] can't open file: %v\n", file) - return + if err := setLevel(level); err != nil { + log.Err(err).Msg("init log level") } - defer func() { - err := targetFile.Close() - if err != nil { - fmt.Printf("[DEBUG] can't close file: %v; err: %v\n", file, err) - } - }() - scanner := bufio.NewScanner(targetFile) - lineCnt := 0 - targetLine := "" - for scanner.Scan() { - lineCnt++ - if lineCnt != line { - continue - } - fileLine := strings.Trim(scanner.Text(), ` `) - dumpStartIdx := strings.Index(fileLine, "Debug(") - dumpEndIdx := strings.LastIndex(fileLine, ")") - if dumpStartIdx < 0 || dumpEndIdx < 0 { - fmt.Printf("[DEBUG] target line is invalid. Debug should start with `Debug(` and end with `)`: %v\n", fileLine) - return - } - targetLine = fileLine[dumpStartIdx+5 : dumpEndIdx] - break - } - dumpVariables := strings.Split(targetLine, ", ") - if len(dumpVariables) != len(values) { - buff := &bytes.Buffer{} - _, _ = fmt.Fprintf(buff, "[DEBUG] %v:%v: ", file, line) - _, _ = fmt.Fprintf(buff, "%v: ", targetLine) - for idx, val := range values { - _, _ = fmt.Fprintf(buff, "`%+v`", val) - if idx < len(values)-1 { - _, _ = fmt.Fprintf(buff, "; ") + zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string { + short := file + for i := len(file) - 1; i > 0; i-- { + if file[i] == '/' { + short = file[i+1:] + break } } - _, _ = fmt.Fprintf(buff, "\n") - fmt.Print(buff.String()) - return + file = short + return file + ":" + strconv.Itoa(line) } + log.Logger = log.Logger.With().Caller().Logger().Output(consoleWriter) +} - buff := &bytes.Buffer{} - _, _ = fmt.Fprintf(buff, "[DEBUG] %v:%v: ", file, line) - for idx, variable := range dumpVariables { - isStringLiteral := strings.HasPrefix(variable, `"`) && strings.HasSuffix(variable, `"`) - isStringLiteral = isStringLiteral || strings.HasPrefix(variable, "`") && strings.HasSuffix(variable, "`") - if isStringLiteral { - _, _ = fmt.Fprintf(buff, "%v", variable[1:len(variable)-1]) - } else { - _, _ = fmt.Fprintf(buff, "%v: `%+v`", variable, values[idx]) - if idx < len(values)-1 { - _, _ = fmt.Fprintf(buff, "; ") - } - } +func setLevel(level string) error { + if level == "" { + level = "info" } - _, _ = fmt.Fprintf(buff, "\n") - fmt.Print(buff.String()) + logLevel, err := zerolog.ParseLevel(level) + if err != nil { + return err + } + zerolog.SetGlobalLevel(logLevel) + return nil } // Question - @@ -140,13 +62,3 @@ func Question(format string, v ...interface{}) { blue := color.New(color.FgMagenta).SprintFunc() fmt.Printf("[%s] %s", blue("?"), fmt.Sprintf(format, v...)) } - -// InterfaceToJSON - -func InterfaceToJSON(v interface{}) { - data, err := json.MarshalIndent(v, "", " ") - if err != nil { - Info().Err(err).Msg("") - return - } - Info().Msg(string(data)) -} diff --git a/internal/models/account/model.go b/internal/models/account/model.go index 905899b86..053962dd8 100644 --- a/internal/models/account/model.go +++ b/internal/models/account/model.go @@ -1,19 +1,25 @@ package account import ( + "time" + "github.com/baking-bad/bcdhub/internal/models/types" - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // Account - type Account struct { - // nolint - tableName struct{} `pg:"accounts"` + bun.BaseModel `bun:"accounts"` - ID int64 - Type types.AccountType `pg:",type:SMALLINT"` - Address string `pg:",unique:account"` - Alias string + ID int64 `bun:"id,pk,notnull,autoincrement"` + Type types.AccountType `bun:"type,type:SMALLINT"` + Address string `bun:"address,type:text,unique:address_hash"` + Level int64 `bun:"level"` + LastAction time.Time `bun:"last_action"` + OperationsCount int64 `bun:"operations_count"` + MigrationsCount int64 `bun:"migrations_count"` + EventsCount int64 `bun:"events_count"` + TicketUpdatesCount int64 `bun:"ticket_updates_count"` } // GetID - @@ -21,20 +27,10 @@ func (a *Account) GetID() int64 { return a.ID } -// GetIndex - -func (a *Account) GetIndex() string { +func (Account) TableName() string { return "accounts" } -// Save - -func (a *Account) Save(tx pg.DBI) error { - _, err := tx.Model(a). - Where("address = ?", a.Address). - Returning("id"). - SelectOrInsert(a) - return err -} - // IsEmpty - func (a *Account) IsEmpty() bool { return a.Address == "" || a.Type == types.AccountTypeUnknown diff --git a/internal/models/account/repository.go b/internal/models/account/repository.go index ba8e14e60..de2e15b02 100644 --- a/internal/models/account/repository.go +++ b/internal/models/account/repository.go @@ -1,6 +1,11 @@ package account +import ( + "context" +) + //go:generate mockgen -source=$GOFILE -destination=../mock/account/mock.go -package=account -typed type Repository interface { - Get(address string) (Account, error) + Get(ctx context.Context, address string) (Account, error) + RecentlyCalledContracts(ctx context.Context, offset, size int64) (accounts []Account, err error) } diff --git a/internal/models/bigmapaction/model.go b/internal/models/bigmapaction/model.go index 20f32b6f6..06cd92024 100644 --- a/internal/models/bigmapaction/model.go +++ b/internal/models/bigmapaction/model.go @@ -4,22 +4,21 @@ import ( "time" "github.com/baking-bad/bcdhub/internal/models/types" - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // BigMapAction - type BigMapAction struct { - // nolint - tableName struct{} `pg:"big_map_actions"` + bun.BaseModel `bun:"big_map_actions"` - ID int64 - Action types.BigMapAction `pg:",type:SMALLINT"` + ID int64 `bun:"id,pk,notnull,autoincrement"` + Action types.BigMapAction `bun:"action,type:SMALLINT"` SourcePtr *int64 DestinationPtr *int64 OperationID int64 Level int64 - Address string - Timestamp time.Time + Address string `bun:"address,type:text"` + Timestamp time.Time `bun:"timestamp,pk,notnull"` } // GetID - @@ -27,22 +26,6 @@ func (b *BigMapAction) GetID() int64 { return b.ID } -// GetIndex - -func (b *BigMapAction) GetIndex() string { +func (b *BigMapAction) TableName() string { return "big_map_actions" } - -// Save - -func (b *BigMapAction) Save(tx pg.DBI) error { - _, err := tx.Model(b).OnConflict("(id) DO UPDATE"). - Set(` - action = excluded.action, - source_ptr = excluded.source_ptr, - destination_ptr = excluded.destination_ptr, - operation_id = excluded.operation_id, - level = excluded.level, - address = excluded.address, - timestamp = excluded.timestamp`). - Returning("id").Insert() - return err -} diff --git a/internal/models/bigmapaction/repository.go b/internal/models/bigmapaction/repository.go index 525cdfbda..5fede0128 100644 --- a/internal/models/bigmapaction/repository.go +++ b/internal/models/bigmapaction/repository.go @@ -1,6 +1,8 @@ package bigmapaction +import "context" + //go:generate mockgen -source=$GOFILE -destination=../mock/bigmapaction/mock.go -package=bigmapaction -typed type Repository interface { - Get(ptr, limit, offset int64) ([]BigMapAction, error) + Get(ctx context.Context, ptr, limit, offset int64) ([]BigMapAction, error) } diff --git a/internal/models/bigmapdiff/bigmapstate.go b/internal/models/bigmapdiff/bigmapstate.go index 7183bd198..0f825c9c2 100644 --- a/internal/models/bigmapdiff/bigmapstate.go +++ b/internal/models/bigmapdiff/bigmapstate.go @@ -1,29 +1,29 @@ package bigmapdiff import ( + "fmt" "time" "github.com/baking-bad/bcdhub/internal/models/types" - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // BigMapState - type BigMapState struct { - // nolint - tableName struct{} `pg:"big_map_states"` + bun.BaseModel `bun:"big_map_states"` - ID int64 `pg:",pk"` - Ptr int64 `pg:",notnull,unique:big_map_key,use_zero"` - LastUpdateLevel int64 `pg:"last_update_level"` - Count int64 `pg:",use_zero"` - LastUpdateTime time.Time `pg:"last_update_time"` - KeyHash string `pg:",notnull,unique:big_map_key"` - Contract string `pg:",notnull,unique:big_map_key"` // contract is in primary key for supporting alpha protocol (mainnet before babylon) - Key types.Bytes `pg:",type:bytea,notnull"` - Value types.Bytes `pg:",type:bytea"` - Removed bool `pg:",use_zero"` + ID int64 `bun:"id,pk,notnull,autoincrement"` + Ptr int64 `bun:"ptr,notnull,unique:big_map_state_unique"` + LastUpdateLevel int64 `bun:"last_update_level"` + Count int64 `bun:"count"` + LastUpdateTime time.Time `bun:"last_update_time"` + KeyHash string `bun:"key_hash,type:text,notnull,unique:big_map_state_unique"` + Contract string `bun:"contract,type:text,notnull,unique:big_map_state_unique"` + Key types.Bytes `bun:"key,type:bytea,notnull"` + Value types.Bytes `bun:"value,type:bytea"` + Removed bool `bun:"removed"` - IsRollback bool `pg:"-"` + IsRollback bool `bun:"-"` } // GetID - @@ -31,22 +31,10 @@ func (b *BigMapState) GetID() int64 { return b.ID } -// GetIndex - -func (b *BigMapState) GetIndex() string { +func (BigMapState) TableName() string { return "big_map_states" } -// Save - -func (b *BigMapState) Save(tx pg.DBI) error { - _, err := tx. - Model(b). - OnConflict("(contract, ptr, key_hash) DO UPDATE"). - Set("removed = EXCLUDED.removed, last_update_level = EXCLUDED.last_update_level, last_update_time = EXCLUDED.last_update_time, count = big_map_state.count + 1, value = CASE WHEN EXCLUDED.removed THEN big_map_state.value ELSE EXCLUDED.value END"). - Returning("id"). - Insert(b) - return err -} - // LogFields - func (b *BigMapState) LogFields() map[string]interface{} { return map[string]interface{}{ @@ -56,6 +44,10 @@ func (b *BigMapState) LogFields() map[string]interface{} { } } +func (b BigMapState) String() string { + return fmt.Sprintf("%s_%s_%d", b.Contract, b.KeyHash, b.Ptr) +} + // ToDiff - func (b *BigMapState) ToDiff() BigMapDiff { bmd := BigMapDiff{ diff --git a/internal/models/bigmapdiff/model.go b/internal/models/bigmapdiff/model.go index d1cf4f737..36427a334 100644 --- a/internal/models/bigmapdiff/model.go +++ b/internal/models/bigmapdiff/model.go @@ -4,23 +4,22 @@ import ( "time" "github.com/baking-bad/bcdhub/internal/models/types" - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // BigMapDiff - type BigMapDiff struct { - // nolint - tableName struct{} `pg:"big_map_diffs,partition_by:RANGE(timestamp)"` + bun.BaseModel `bun:"big_map_diffs"` - ID int64 `pg:",pk"` - Ptr int64 `pg:",use_zero"` - Key types.Bytes `pg:",notnull,type:bytea"` - KeyHash string - Value types.Bytes `pg:",type:bytea"` + ID int64 `bun:"id,pk,notnull,autoincrement"` + Ptr int64 `bun:"ptr"` + Key types.Bytes `bun:"key,notnull,type:bytea"` + KeyHash string `bun:"key_hash,type:text"` + Value types.Bytes `bun:"value,type:bytea"` Level int64 - Contract string - Timestamp time.Time `pg:",pk"` - ProtocolID int64 `pg:",type:SMALLINT"` + Contract string `bun:"contract,type:text"` + Timestamp time.Time `bun:"timestamp,pk,notnull"` + ProtocolID int64 `bun:"protocol_id,type:SMALLINT"` OperationID int64 } @@ -29,30 +28,10 @@ func (b *BigMapDiff) GetID() int64 { return b.ID } -// GetIndex - -func (b *BigMapDiff) GetIndex() string { +func (BigMapDiff) TableName() string { return "big_map_diffs" } -// Save - -func (b *BigMapDiff) Save(tx pg.DBI) error { - _, err := tx.Model(b). - OnConflict("(id, timestamp) DO UPDATE"). - Set(` - ptr = excluded.ptr, - key = excluded.key, - key_hash = excluded.key_hash, - value = excluded.value, - level = excluded.level, - contract = excluded.contract, - timestamp = excluded.timestamp, - protocol_id = excluded.protocol_id, - operation_id = excluded.operation_id`). - Returning("id"). - Insert() - return err -} - // LogFields - func (b *BigMapDiff) LogFields() map[string]interface{} { return map[string]interface{}{ diff --git a/internal/models/bigmapdiff/repository.go b/internal/models/bigmapdiff/repository.go index 34d608c31..7b59f3e4b 100644 --- a/internal/models/bigmapdiff/repository.go +++ b/internal/models/bigmapdiff/repository.go @@ -1,20 +1,17 @@ package bigmapdiff +import "context" + //go:generate mockgen -source=$GOFILE -destination=../mock/bigmapdiff/mock.go -package=bigmapdiff -typed type Repository interface { - Get(ctx GetContext) ([]Bucket, error) - GetByAddress(address string) ([]BigMapDiff, error) - GetForOperation(id int64) ([]BigMapDiff, error) - GetByPtr(contract string, ptr int64) ([]BigMapState, error) - GetByPtrAndKeyHash(ptr int64, keyHash string, size int64, offset int64) ([]BigMapDiff, int64, error) - GetForAddress(address string) ([]BigMapState, error) - GetValuesByKey(keyHash string) ([]BigMapState, error) - Count(ptr int64) (int64, error) - Current(keyHash string, ptr int64) (BigMapState, error) - CurrentByContract(contract string) ([]BigMapState, error) - Previous([]BigMapDiff) ([]BigMapDiff, error) - GetStats(ptr int64) (Stats, error) - StatesChangedAfter(level int64) ([]BigMapState, error) - LastDiff(ptr int64, keyHash string, skipRemoved bool) (BigMapDiff, error) - Keys(ctx GetContext) (states []BigMapState, err error) + Get(ctx context.Context, reqCtx GetContext) ([]Bucket, error) + GetForOperation(ctx context.Context, id int64) ([]BigMapDiff, error) + GetByPtr(ctx context.Context, contract string, ptr int64) ([]BigMapState, error) + GetByPtrAndKeyHash(ctx context.Context, ptr int64, keyHash string, size int64, offset int64) ([]BigMapDiff, int64, error) + GetForAddress(ctx context.Context, address string) ([]BigMapState, error) + Count(ctx context.Context, ptr int64) (int, error) + Current(ctx context.Context, keyHash string, ptr int64) (BigMapState, error) + Previous(ctx context.Context, diffs []BigMapDiff) ([]BigMapDiff, error) + GetStats(ctx context.Context, ptr int64) (Stats, error) + Keys(ctx context.Context, reqCtx GetContext) (states []BigMapState, err error) } diff --git a/internal/models/block/model.go b/internal/models/block/model.go index 8e3456ffd..bf1ed7909 100644 --- a/internal/models/block/model.go +++ b/internal/models/block/model.go @@ -4,21 +4,20 @@ import ( "time" "github.com/baking-bad/bcdhub/internal/models/protocol" - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // Block - type Block struct { - // nolint - tableName struct{} `pg:"blocks"` + bun.BaseModel `bun:"blocks"` - Hash string - Timestamp time.Time - ID int64 - Level int64 - ProtocolID int64 `pg:",type:SMALLINT"` + ID int64 `bun:"id,pk,notnull,autoincrement"` + Hash string `bun:"hash,type:text"` + Timestamp time.Time `bun:"timestamp,pk,notnull"` + Level int64 `bun:"level"` + ProtocolID int64 `bun:"protocol_id,type:SMALLINT"` - Protocol protocol.Protocol `pg:",rel:has-one"` + Protocol protocol.Protocol `bun:",rel:belongs-to"` } // GetID - @@ -26,13 +25,6 @@ func (b *Block) GetID() int64 { return b.ID } -// GetIndex - -func (b *Block) GetIndex() string { +func (Block) TableName() string { return "blocks" } - -// Save - -func (b *Block) Save(tx pg.DBI) error { - _, err := tx.Model(b).Returning("id").Insert(b) - return err -} diff --git a/internal/models/block/repository.go b/internal/models/block/repository.go index b426ef9bd..c0a88a57e 100644 --- a/internal/models/block/repository.go +++ b/internal/models/block/repository.go @@ -1,7 +1,9 @@ package block +import "context" + //go:generate mockgen -source=$GOFILE -destination=../mock/block/mock.go -package=block -typed type Repository interface { - Get(level int64) (Block, error) - Last() (Block, error) + Get(ctx context.Context, level int64) (Block, error) + Last(ctx context.Context) (Block, error) } diff --git a/internal/models/consts.go b/internal/models/consts.go index 6811575c9..fcce7eb62 100644 --- a/internal/models/consts.go +++ b/internal/models/consts.go @@ -10,6 +10,7 @@ import ( "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/protocol" smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" + "github.com/baking-bad/bcdhub/internal/models/stats" "github.com/baking-bad/bcdhub/internal/models/ticket" ) @@ -27,7 +28,10 @@ const ( DocProtocol = "protocols" DocScripts = "scripts" DocTicketUpdates = "ticket_updates" + DocTickets = "tickets" + DocTicketBalances = "ticket_balances" DocSmartRollups = "smart_rollup" + DocStats = "stats" ) // AllDocuments - returns all document names @@ -45,7 +49,10 @@ func AllDocuments() []string { DocProtocol, DocScripts, DocTicketUpdates, + DocTicketBalances, + DocTickets, DocSmartRollups, + DocStats, } } @@ -58,7 +65,9 @@ func AllModels() []Model { &bigmapaction.BigMapAction{}, &bigmapdiff.BigMapDiff{}, &bigmapdiff.BigMapState{}, + &ticket.Ticket{}, &ticket.TicketUpdate{}, + &ticket.Balance{}, &operation.Operation{}, &contract.GlobalConstant{}, &contract.Script{}, @@ -66,6 +75,7 @@ func AllModels() []Model { &contract.Contract{}, &migration.Migration{}, &smartrollup.SmartRollup{}, + &stats.Stats{}, } } diff --git a/internal/models/contract/constant.go b/internal/models/contract/constant.go index 6e25dae83..6105362a7 100644 --- a/internal/models/contract/constant.go +++ b/internal/models/contract/constant.go @@ -3,21 +3,20 @@ package contract import ( "time" - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // GlobalConstant - type GlobalConstant struct { - // nolint - tableName struct{} `pg:"global_constants"` + bun.BaseModel `bun:"global_constants"` - ID int64 `json:"-"` + ID int64 `bun:"id,pk,notnull,autoincrement"` Timestamp time.Time `json:"timestamp"` Level int64 `json:"level"` - Address string `json:"address"` - Value []byte `json:"value,omitempty"` + Address string `bun:"address,type:text"` + Value []byte - Scripts []Script `pg:",many2many:script_constants"` + Scripts []Script `bun:"m2m:script_constants,join:GlobalConstant=Script"` } // GetID - @@ -25,17 +24,10 @@ func (m *GlobalConstant) GetID() int64 { return m.ID } -// GetIndex - -func (m *GlobalConstant) GetIndex() string { +func (GlobalConstant) TableName() string { return "global_constants" } -// Save - -func (m *GlobalConstant) Save(tx pg.DBI) error { - _, err := tx.Model(m).Returning("id").Insert() - return err -} - // LogFields - func (m *GlobalConstant) LogFields() map[string]interface{} { return map[string]interface{}{ @@ -43,3 +35,7 @@ func (m *GlobalConstant) LogFields() map[string]interface{} { "block": m.Level, } } + +func (GlobalConstant) PartitionBy() string { + return "" +} diff --git a/internal/models/contract/model.go b/internal/models/contract/model.go index 653a0d72d..6afd69fc6 100644 --- a/internal/models/contract/model.go +++ b/internal/models/contract/model.go @@ -7,36 +7,32 @@ import ( "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/types" - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // Contract - entity for contract type Contract struct { - // nolint - tableName struct{} `pg:"contracts"` + bun.BaseModel `bun:"contracts"` - ID int64 - Level int64 - Timestamp time.Time + ID int64 `bun:"id,pk,notnull,autoincrement"` + Level int64 `bun:"level"` + Timestamp time.Time `bun:"timestamp,pk,notnull"` AccountID int64 - Account account.Account `pg:",rel:has-one"` + Account account.Account `bun:"rel:belongs-to"` ManagerID int64 - Manager account.Account `pg:",rel:has-one"` + Manager account.Account `bun:"rel:belongs-to"` DelegateID int64 - Delegate account.Account `pg:",rel:has-one"` + Delegate account.Account `bun:"rel:belongs-to"` - TxCount int64 `pg:",use_zero"` - LastAction time.Time - MigrationsCount int64 `pg:",use_zero"` - Tags types.Tags `pg:",use_zero"` + Tags types.Tags AlphaID int64 - Alpha Script `pg:",rel:has-one"` + Alpha Script `bun:"rel:belongs-to"` BabylonID int64 - Babylon Script `pg:",rel:has-one"` + Babylon Script `bun:"rel:belongs-to"` JakartaID int64 - Jakarta Script `pg:",rel:has-one"` + Jakarta Script `bun:"rel:belongs-to"` } // GetID - @@ -44,17 +40,10 @@ func (c *Contract) GetID() int64 { return c.ID } -// GetIndex - -func (c *Contract) GetIndex() string { +func (Contract) TableName() string { return "contracts" } -// Save - -func (c *Contract) Save(tx pg.DBI) error { - _, err := tx.Model(c).OnConflict("DO NOTHING").Returning("id").Insert() - return err -} - // LogFields - func (c *Contract) LogFields() map[string]interface{} { return map[string]interface{}{ @@ -110,3 +99,11 @@ type View struct { type ViewImplementation struct { MichelsonStorageView Sections `json:"michelsonStorageView"` } + +type Update struct { + bun.BaseModel `bun:"contracts"` + + AccountID int64 + LastAction time.Time + TxCount uint64 +} diff --git a/internal/models/contract/repository.go b/internal/models/contract/repository.go index 7cd6d6c73..083b7ba67 100644 --- a/internal/models/contract/repository.go +++ b/internal/models/contract/repository.go @@ -1,6 +1,7 @@ package contract import ( + "context" "time" "github.com/baking-bad/bcdhub/internal/models/types" @@ -8,45 +9,37 @@ import ( //go:generate mockgen -source=$GOFILE -destination=../mock/contract/mock.go -package=contract -typed type Repository interface { - Get(address string) (Contract, error) - GetAll(filters map[string]interface{}) ([]Contract, error) - GetRandom() (Contract, error) - GetTokens(tokenInterface string, offset, size int64) ([]Contract, int64, error) - RecentlyCalled(offset, size int64) ([]Contract, error) - Count() (int, error) - - Script(address string, symLink string) (Script, error) + Get(ctx context.Context, address string) (Contract, error) + Script(ctx context.Context, address string, symLink string) (Script, error) // ScriptPart - returns part of script type. Part can be `storage`, `parameter` or `code`. - ScriptPart(address string, symLink, part string) ([]byte, error) - FindOne(tags types.Tags) (Contract, error) + ScriptPart(ctx context.Context, address string, symLink, part string) ([]byte, error) + FindOne(ctx context.Context, tags types.Tags) (Contract, error) + AllExceptDelegators(ctx context.Context) ([]Contract, error) } //go:generate mockgen -source=$GOFILE -destination=../mock/contract/mock.go -package=contract -typed type ScriptRepository interface { - GetScripts(limit, offset int) ([]Script, error) - ByHash(hash string) (Script, error) - UpdateProjectID(script []Script) error - - Code(id int64) ([]byte, error) - Parameter(id int64) ([]byte, error) - Storage(id int64) ([]byte, error) - Views(id int64) ([]byte, error) + ByHash(ctx context.Context, hash string) (Script, error) + Code(ctx context.Context, id int64) ([]byte, error) + Parameter(ctx context.Context, id int64) ([]byte, error) + Storage(ctx context.Context, id int64) ([]byte, error) + Views(ctx context.Context, id int64) ([]byte, error) } //go:generate mockgen -source=$GOFILE -destination=../mock/contract/mock.go -package=contract -typed type ConstantRepository interface { - Get(address string) (GlobalConstant, error) - All(addresses ...string) ([]GlobalConstant, error) - List(size, offset int64, orderBy, sort string) ([]ListGlobalConstantItem, error) - ForContract(address string, size, offset int64) ([]GlobalConstant, error) - ContractList(address string, size, offset int64) ([]Contract, error) + Get(ctx context.Context, address string) (GlobalConstant, error) + All(ctx context.Context, addresses ...string) ([]GlobalConstant, error) + List(ctx context.Context, size, offset int64, orderBy, sort string) ([]ListGlobalConstantItem, error) + ForContract(ctx context.Context, address string, size, offset int64) ([]GlobalConstant, error) + ContractList(ctx context.Context, address string, size, offset int64) ([]Contract, error) } // ListGlobalConstantItem - type ListGlobalConstantItem struct { - Timestamp time.Time `json:"timestamp" pg:"timestamp"` - Level int64 `json:"level" pg:"level"` - Address string `json:"address" pg:"address"` - LinksCount uint64 `json:"links_count" pg:"links_count"` + Timestamp time.Time `bun:"timestamp"` + Level int64 `bun:"level"` + Address string `bun:"address"` + LinksCount uint64 `bun:"links_count"` } diff --git a/internal/models/contract/script.go b/internal/models/contract/script.go index 79ffd459c..e70e0ac11 100644 --- a/internal/models/contract/script.go +++ b/internal/models/contract/script.go @@ -4,28 +4,28 @@ import ( "bytes" "github.com/baking-bad/bcdhub/internal/models/types" - "github.com/go-pg/pg/v10" "github.com/lib/pq" + "github.com/uptrace/bun" ) // Scripts - type Script struct { - // nolint - tableName struct{} `pg:"scripts"` + bun.BaseModel `bun:"scripts"` - ID int64 - Hash string `pg:",unique"` - Code []byte `pg:",type:bytea"` - Parameter []byte `pg:",type:bytea"` - Storage []byte `pg:",type:bytea"` - Views []byte `pg:",type:bytea"` - Entrypoints pq.StringArray `pg:",type:text[]"` - FailStrings pq.StringArray `pg:",type:text[]"` - Annotations pq.StringArray `pg:",type:text[]"` - Hardcoded pq.StringArray `pg:",type:text[]"` - Tags types.Tags `pg:",use_zero"` + ID int64 `bun:"id,pk,notnull,autoincrement"` + Level int64 `bun:"level"` + Hash string `bun:"hash,type:text"` + Code []byte `bun:",type:bytea"` + Parameter []byte `bun:",type:bytea"` + Storage []byte `bun:",type:bytea"` + Views []byte `bun:",type:bytea"` + Entrypoints pq.StringArray `bun:",type:text[]"` + FailStrings pq.StringArray `bun:",type:text[]"` + Annotations pq.StringArray `bun:",type:text[]"` + Hardcoded pq.StringArray `bun:",type:text[]"` + Tags types.Tags - Constants []GlobalConstant `pg:",many2many:script_constants"` + Constants []GlobalConstant `bun:"m2m:script_constants,join:Script=GlobalConstant"` } // GetID - @@ -33,20 +33,10 @@ func (s *Script) GetID() int64 { return s.ID } -// GetIndex - -func (s *Script) GetIndex() string { +func (Script) TableName() string { return "scripts" } -// Save - -func (s *Script) Save(tx pg.DBI) error { - _, err := tx.Model(s). - Where("hash = ?hash"). - OnConflict("DO NOTHING"). - Returning("id").SelectOrInsert() - return err -} - // Full - func (s *Script) Full() ([]byte, error) { var buf bytes.Buffer diff --git a/internal/models/contract/script_constants.go b/internal/models/contract/script_constants.go index 5791f8ab6..1c00f5370 100644 --- a/internal/models/contract/script_constants.go +++ b/internal/models/contract/script_constants.go @@ -1,14 +1,19 @@ package contract -import "github.com/go-pg/pg/v10" +import ( + "context" + + "github.com/uptrace/bun" +) // ScriptConstants - type ScriptConstants struct { - // nolint - tableName struct{} `pg:"script_constants"` + bun.BaseModel `bun:"script_constants"` ScriptId int64 + Script Script `bun:"rel:belongs-to,join:script_id=id"` GlobalConstantId int64 + GlobalConstant GlobalConstant `bun:"rel:belongs-to,join:global_constant_id=id"` } // GetID - @@ -16,12 +21,11 @@ func (ScriptConstants) GetID() int64 { return 0 } -// GetIndex - -func (ScriptConstants) GetIndex() string { +func (ScriptConstants) TableName() string { return "script_constants" } // Save - -func (ScriptConstants) Save(tx pg.DBI) error { +func (ScriptConstants) Save(ctx context.Context, tx bun.IDB) error { return nil } diff --git a/internal/models/domains/data.go b/internal/models/domains/data.go index 371ffaa81..6205427a5 100644 --- a/internal/models/domains/data.go +++ b/internal/models/domains/data.go @@ -1,20 +1,9 @@ package domains import ( - "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" "github.com/baking-bad/bcdhub/internal/models/contract" - "github.com/baking-bad/bcdhub/internal/models/operation" - "github.com/baking-bad/bcdhub/internal/models/protocol" ) -// BigMapDiff - -type BigMapDiff struct { - *bigmapdiff.BigMapDiff - - Operation *operation.Operation `pg:"rel:has-one"` - Protocol *protocol.Protocol `pg:"rel:has-one"` -} - // Same - type Same struct { contract.Contract diff --git a/internal/models/domains/repository.go b/internal/models/domains/repository.go index b122362f8..c294be619 100644 --- a/internal/models/domains/repository.go +++ b/internal/models/domains/repository.go @@ -1,13 +1,13 @@ package domains import ( + "context" + "github.com/baking-bad/bcdhub/internal/models/contract" ) //go:generate mockgen -source=$GOFILE -destination=../mock/domains/mock.go -package=domains -typed type Repository interface { - BigMapDiffs(lastID, size int64) ([]BigMapDiff, error) - - Same(network string, c contract.Contract, limit, offset int, availiableNetworks ...string) ([]Same, error) - SameCount(c contract.Contract, availiableNetworks ...string) (int, error) + Same(ctx context.Context, network string, c contract.Contract, limit, offset int, availiableNetworks ...string) ([]Same, error) + SameCount(ctx context.Context, c contract.Contract, availiableNetworks ...string) (int, error) } diff --git a/internal/models/interface.go b/internal/models/interface.go index f994fc98c..e3026c0a0 100644 --- a/internal/models/interface.go +++ b/internal/models/interface.go @@ -2,22 +2,60 @@ package models import ( "context" + + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/baking-bad/bcdhub/internal/models/bigmapaction" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/block" + "github.com/baking-bad/bcdhub/internal/models/contract" + "github.com/baking-bad/bcdhub/internal/models/migration" + "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/protocol" + smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" + "github.com/baking-bad/bcdhub/internal/models/stats" + "github.com/baking-bad/bcdhub/internal/models/ticket" ) //go:generate mockgen -source=$GOFILE -destination=mock/general.go -package=mock -typed type GeneralRepository interface { - CreateTables() error - DeleteByContract(indices []string, address string) error - GetByID(output Model) error - GetAll(index string) ([]Model, error) - UpdateDoc(model Model) (err error) + InitDatabase(ctx context.Context) error + TablesExist(ctx context.Context) bool + CreateIndex(ctx context.Context, name, columns string, model any) error IsRecordNotFound(err error) bool - // Save - performs insert or update items. - Save(ctx context.Context, items []Model) error - BulkDelete(context.Context, []Model) error - - TablesExist() bool // Drop - drops full database Drop(ctx context.Context) error } + +//go:generate mockgen -source=$GOFILE -destination=mock/general.go -package=mock -typed +type Transaction interface { + Save(ctx context.Context, data any) error + Migrations(ctx context.Context, migrations ...*migration.Migration) error + GlobalConstants(ctx context.Context, constants ...*contract.GlobalConstant) error + BigMapStates(ctx context.Context, states ...*bigmapdiff.BigMapState) error + BigMapDiffs(ctx context.Context, bigmapdiffs ...*bigmapdiff.BigMapDiff) error + BigMapActions(ctx context.Context, bigmapdiffs ...*bigmapaction.BigMapAction) error + Accounts(ctx context.Context, accounts ...*account.Account) error + SmartRollups(ctx context.Context, rollups ...*smartrollup.SmartRollup) error + Operations(ctx context.Context, operations ...*operation.Operation) error + TickerUpdates(ctx context.Context, updates ...*ticket.TicketUpdate) error + Contracts(ctx context.Context, contracts ...*contract.Contract) error + Scripts(ctx context.Context, scripts ...*contract.Script) error + ScriptConstant(ctx context.Context, data ...*contract.ScriptConstants) error + Block(ctx context.Context, block *block.Block) error + Protocol(ctx context.Context, proto *protocol.Protocol) error + UpdateStats(ctx context.Context, stats stats.Stats) error + Tickets(ctx context.Context, tickets ...*ticket.Ticket) error + TicketBalances(ctx context.Context, balances ...*ticket.Balance) error + + ToBabylon(ctx context.Context) error + BabylonUpdateNonDelegator(ctx context.Context, contract *contract.Contract) error + ToJakarta(ctx context.Context) error + JakartaVesting(ctx context.Context, contract *contract.Contract) error + JakartaUpdateNonDelegator(ctx context.Context, contract *contract.Contract) error + BabylonUpdateBigMapDiffs(ctx context.Context, contract string, ptr int64) (int, error) + DeleteBigMapStatesByContract(ctx context.Context, contract string) ([]bigmapdiff.BigMapState, error) + + Commit() error + Rollback() error +} diff --git a/internal/models/migration/model.go b/internal/models/migration/model.go index d79cae752..baf7017a9 100644 --- a/internal/models/migration/model.go +++ b/internal/models/migration/model.go @@ -5,23 +5,22 @@ import ( "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/types" - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // Migration - type Migration struct { - // nolint - tableName struct{} `pg:"migrations"` + bun.BaseModel `bun:"migrations"` - ID int64 - ProtocolID int64 `pg:",type:SMALLINT"` + ID int64 `bun:"id,pk,notnull,autoincrement"` + ProtocolID int64 `bun:"protocol_id,type:SMALLINT"` PrevProtocolID int64 Hash []byte - Timestamp time.Time + Timestamp time.Time `bun:"timestamp,pk,notnull"` Level int64 - Kind types.MigrationKind `pg:",type:SMALLINT"` + Kind types.MigrationKind `bun:"kind,type:SMALLINT"` ContractID int64 - Contract *contract.Contract `pg:",rel:has-one"` + Contract contract.Contract `bun:"rel:belongs-to"` } // GetID - @@ -29,17 +28,11 @@ func (m *Migration) GetID() int64 { return m.ID } -// GetIndex - -func (m *Migration) GetIndex() string { +// TableName - +func (Migration) TableName() string { return "migrations" } -// Save - -func (m *Migration) Save(tx pg.DBI) error { - _, err := tx.Model(m).Returning("id").Insert() - return err -} - // LogFields - func (m *Migration) LogFields() map[string]interface{} { return map[string]interface{}{ diff --git a/internal/models/migration/repository.go b/internal/models/migration/repository.go index 324bbd134..bb8607880 100644 --- a/internal/models/migration/repository.go +++ b/internal/models/migration/repository.go @@ -1,6 +1,8 @@ package migration +import "context" + //go:generate mockgen -source=$GOFILE -destination=../mock/migration/mock.go -package=migration -typed type Repository interface { - Get(contractID int64) ([]Migration, error) + Get(ctx context.Context, contractID int64) ([]Migration, error) } diff --git a/internal/models/mock/account/mock.go b/internal/models/mock/account/mock.go index 8a628efe6..192cc783d 100644 --- a/internal/models/mock/account/mock.go +++ b/internal/models/mock/account/mock.go @@ -9,6 +9,7 @@ package account import ( + context "context" reflect "reflect" account "github.com/baking-bad/bcdhub/internal/models/account" @@ -39,18 +40,18 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { } // Get mocks base method. -func (m *MockRepository) Get(address string) (account.Account, error) { +func (m *MockRepository) Get(ctx context.Context, address string) (account.Account, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", address) + ret := m.ctrl.Call(m, "Get", ctx, address) ret0, _ := ret[0].(account.Account) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get. -func (mr *MockRepositoryMockRecorder) Get(address any) *RepositoryGetCall { +func (mr *MockRepositoryMockRecorder) Get(ctx, address any) *RepositoryGetCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), address) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), ctx, address) return &RepositoryGetCall{Call: call} } @@ -66,13 +67,52 @@ func (c *RepositoryGetCall) Return(arg0 account.Account, arg1 error) *Repository } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetCall) Do(f func(string) (account.Account, error)) *RepositoryGetCall { +func (c *RepositoryGetCall) Do(f func(context.Context, string) (account.Account, error)) *RepositoryGetCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetCall) DoAndReturn(f func(string) (account.Account, error)) *RepositoryGetCall { +func (c *RepositoryGetCall) DoAndReturn(f func(context.Context, string) (account.Account, error)) *RepositoryGetCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// RecentlyCalledContracts mocks base method. +func (m *MockRepository) RecentlyCalledContracts(ctx context.Context, offset, size int64) ([]account.Account, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "RecentlyCalledContracts", ctx, offset, size) + ret0, _ := ret[0].([]account.Account) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// RecentlyCalledContracts indicates an expected call of RecentlyCalledContracts. +func (mr *MockRepositoryMockRecorder) RecentlyCalledContracts(ctx, offset, size any) *RepositoryRecentlyCalledContractsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecentlyCalledContracts", reflect.TypeOf((*MockRepository)(nil).RecentlyCalledContracts), ctx, offset, size) + return &RepositoryRecentlyCalledContractsCall{Call: call} +} + +// RepositoryRecentlyCalledContractsCall wrap *gomock.Call +type RepositoryRecentlyCalledContractsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RepositoryRecentlyCalledContractsCall) Return(accounts []account.Account, err error) *RepositoryRecentlyCalledContractsCall { + c.Call = c.Call.Return(accounts, err) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RepositoryRecentlyCalledContractsCall) Do(f func(context.Context, int64, int64) ([]account.Account, error)) *RepositoryRecentlyCalledContractsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RepositoryRecentlyCalledContractsCall) DoAndReturn(f func(context.Context, int64, int64) ([]account.Account, error)) *RepositoryRecentlyCalledContractsCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/internal/models/mock/bigmapaction/mock.go b/internal/models/mock/bigmapaction/mock.go index 79b5903dd..846b98385 100644 --- a/internal/models/mock/bigmapaction/mock.go +++ b/internal/models/mock/bigmapaction/mock.go @@ -9,6 +9,7 @@ package bigmapaction import ( + context "context" reflect "reflect" bigmapaction "github.com/baking-bad/bcdhub/internal/models/bigmapaction" @@ -39,18 +40,18 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { } // Get mocks base method. -func (m *MockRepository) Get(ptr, limit, offset int64) ([]bigmapaction.BigMapAction, error) { +func (m *MockRepository) Get(ctx context.Context, ptr, limit, offset int64) ([]bigmapaction.BigMapAction, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", ptr, limit, offset) + ret := m.ctrl.Call(m, "Get", ctx, ptr, limit, offset) ret0, _ := ret[0].([]bigmapaction.BigMapAction) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get. -func (mr *MockRepositoryMockRecorder) Get(ptr, limit, offset any) *RepositoryGetCall { +func (mr *MockRepositoryMockRecorder) Get(ctx, ptr, limit, offset any) *RepositoryGetCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), ptr, limit, offset) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), ctx, ptr, limit, offset) return &RepositoryGetCall{Call: call} } @@ -66,13 +67,13 @@ func (c *RepositoryGetCall) Return(arg0 []bigmapaction.BigMapAction, arg1 error) } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetCall) Do(f func(int64, int64, int64) ([]bigmapaction.BigMapAction, error)) *RepositoryGetCall { +func (c *RepositoryGetCall) Do(f func(context.Context, int64, int64, int64) ([]bigmapaction.BigMapAction, error)) *RepositoryGetCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetCall) DoAndReturn(f func(int64, int64, int64) ([]bigmapaction.BigMapAction, error)) *RepositoryGetCall { +func (c *RepositoryGetCall) DoAndReturn(f func(context.Context, int64, int64, int64) ([]bigmapaction.BigMapAction, error)) *RepositoryGetCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/internal/models/mock/bigmapdiff/mock.go b/internal/models/mock/bigmapdiff/mock.go index 958169e8d..494a1b59f 100644 --- a/internal/models/mock/bigmapdiff/mock.go +++ b/internal/models/mock/bigmapdiff/mock.go @@ -9,6 +9,7 @@ package bigmapdiff import ( + context "context" reflect "reflect" bigmapdiff "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" @@ -39,18 +40,18 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { } // Count mocks base method. -func (m *MockRepository) Count(ptr int64) (int64, error) { +func (m *MockRepository) Count(ctx context.Context, ptr int64) (int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Count", ptr) - ret0, _ := ret[0].(int64) + ret := m.ctrl.Call(m, "Count", ctx, ptr) + ret0, _ := ret[0].(int) ret1, _ := ret[1].(error) return ret0, ret1 } // Count indicates an expected call of Count. -func (mr *MockRepositoryMockRecorder) Count(ptr any) *RepositoryCountCall { +func (mr *MockRepositoryMockRecorder) Count(ctx, ptr any) *RepositoryCountCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Count", reflect.TypeOf((*MockRepository)(nil).Count), ptr) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Count", reflect.TypeOf((*MockRepository)(nil).Count), ctx, ptr) return &RepositoryCountCall{Call: call} } @@ -60,36 +61,36 @@ type RepositoryCountCall struct { } // Return rewrite *gomock.Call.Return -func (c *RepositoryCountCall) Return(arg0 int64, arg1 error) *RepositoryCountCall { +func (c *RepositoryCountCall) Return(arg0 int, arg1 error) *RepositoryCountCall { c.Call = c.Call.Return(arg0, arg1) return c } // Do rewrite *gomock.Call.Do -func (c *RepositoryCountCall) Do(f func(int64) (int64, error)) *RepositoryCountCall { +func (c *RepositoryCountCall) Do(f func(context.Context, int64) (int, error)) *RepositoryCountCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryCountCall) DoAndReturn(f func(int64) (int64, error)) *RepositoryCountCall { +func (c *RepositoryCountCall) DoAndReturn(f func(context.Context, int64) (int, error)) *RepositoryCountCall { c.Call = c.Call.DoAndReturn(f) return c } // Current mocks base method. -func (m *MockRepository) Current(keyHash string, ptr int64) (bigmapdiff.BigMapState, error) { +func (m *MockRepository) Current(ctx context.Context, keyHash string, ptr int64) (bigmapdiff.BigMapState, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Current", keyHash, ptr) + ret := m.ctrl.Call(m, "Current", ctx, keyHash, ptr) ret0, _ := ret[0].(bigmapdiff.BigMapState) ret1, _ := ret[1].(error) return ret0, ret1 } // Current indicates an expected call of Current. -func (mr *MockRepositoryMockRecorder) Current(keyHash, ptr any) *RepositoryCurrentCall { +func (mr *MockRepositoryMockRecorder) Current(ctx, keyHash, ptr any) *RepositoryCurrentCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Current", reflect.TypeOf((*MockRepository)(nil).Current), keyHash, ptr) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Current", reflect.TypeOf((*MockRepository)(nil).Current), ctx, keyHash, ptr) return &RepositoryCurrentCall{Call: call} } @@ -105,69 +106,30 @@ func (c *RepositoryCurrentCall) Return(arg0 bigmapdiff.BigMapState, arg1 error) } // Do rewrite *gomock.Call.Do -func (c *RepositoryCurrentCall) Do(f func(string, int64) (bigmapdiff.BigMapState, error)) *RepositoryCurrentCall { +func (c *RepositoryCurrentCall) Do(f func(context.Context, string, int64) (bigmapdiff.BigMapState, error)) *RepositoryCurrentCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryCurrentCall) DoAndReturn(f func(string, int64) (bigmapdiff.BigMapState, error)) *RepositoryCurrentCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// CurrentByContract mocks base method. -func (m *MockRepository) CurrentByContract(contract string) ([]bigmapdiff.BigMapState, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CurrentByContract", contract) - ret0, _ := ret[0].([]bigmapdiff.BigMapState) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// CurrentByContract indicates an expected call of CurrentByContract. -func (mr *MockRepositoryMockRecorder) CurrentByContract(contract any) *RepositoryCurrentByContractCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CurrentByContract", reflect.TypeOf((*MockRepository)(nil).CurrentByContract), contract) - return &RepositoryCurrentByContractCall{Call: call} -} - -// RepositoryCurrentByContractCall wrap *gomock.Call -type RepositoryCurrentByContractCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryCurrentByContractCall) Return(arg0 []bigmapdiff.BigMapState, arg1 error) *RepositoryCurrentByContractCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryCurrentByContractCall) Do(f func(string) ([]bigmapdiff.BigMapState, error)) *RepositoryCurrentByContractCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryCurrentByContractCall) DoAndReturn(f func(string) ([]bigmapdiff.BigMapState, error)) *RepositoryCurrentByContractCall { +func (c *RepositoryCurrentCall) DoAndReturn(f func(context.Context, string, int64) (bigmapdiff.BigMapState, error)) *RepositoryCurrentCall { c.Call = c.Call.DoAndReturn(f) return c } // Get mocks base method. -func (m *MockRepository) Get(ctx bigmapdiff.GetContext) ([]bigmapdiff.Bucket, error) { +func (m *MockRepository) Get(ctx context.Context, reqCtx bigmapdiff.GetContext) ([]bigmapdiff.Bucket, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", ctx) + ret := m.ctrl.Call(m, "Get", ctx, reqCtx) ret0, _ := ret[0].([]bigmapdiff.Bucket) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get. -func (mr *MockRepositoryMockRecorder) Get(ctx any) *RepositoryGetCall { +func (mr *MockRepositoryMockRecorder) Get(ctx, reqCtx any) *RepositoryGetCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), ctx) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), ctx, reqCtx) return &RepositoryGetCall{Call: call} } @@ -183,69 +145,30 @@ func (c *RepositoryGetCall) Return(arg0 []bigmapdiff.Bucket, arg1 error) *Reposi } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetCall) Do(f func(bigmapdiff.GetContext) ([]bigmapdiff.Bucket, error)) *RepositoryGetCall { +func (c *RepositoryGetCall) Do(f func(context.Context, bigmapdiff.GetContext) ([]bigmapdiff.Bucket, error)) *RepositoryGetCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetCall) DoAndReturn(f func(bigmapdiff.GetContext) ([]bigmapdiff.Bucket, error)) *RepositoryGetCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// GetByAddress mocks base method. -func (m *MockRepository) GetByAddress(address string) ([]bigmapdiff.BigMapDiff, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByAddress", address) - ret0, _ := ret[0].([]bigmapdiff.BigMapDiff) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetByAddress indicates an expected call of GetByAddress. -func (mr *MockRepositoryMockRecorder) GetByAddress(address any) *RepositoryGetByAddressCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByAddress", reflect.TypeOf((*MockRepository)(nil).GetByAddress), address) - return &RepositoryGetByAddressCall{Call: call} -} - -// RepositoryGetByAddressCall wrap *gomock.Call -type RepositoryGetByAddressCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryGetByAddressCall) Return(arg0 []bigmapdiff.BigMapDiff, arg1 error) *RepositoryGetByAddressCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryGetByAddressCall) Do(f func(string) ([]bigmapdiff.BigMapDiff, error)) *RepositoryGetByAddressCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetByAddressCall) DoAndReturn(f func(string) ([]bigmapdiff.BigMapDiff, error)) *RepositoryGetByAddressCall { +func (c *RepositoryGetCall) DoAndReturn(f func(context.Context, bigmapdiff.GetContext) ([]bigmapdiff.Bucket, error)) *RepositoryGetCall { c.Call = c.Call.DoAndReturn(f) return c } // GetByPtr mocks base method. -func (m *MockRepository) GetByPtr(contract string, ptr int64) ([]bigmapdiff.BigMapState, error) { +func (m *MockRepository) GetByPtr(ctx context.Context, contract string, ptr int64) ([]bigmapdiff.BigMapState, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByPtr", contract, ptr) + ret := m.ctrl.Call(m, "GetByPtr", ctx, contract, ptr) ret0, _ := ret[0].([]bigmapdiff.BigMapState) ret1, _ := ret[1].(error) return ret0, ret1 } // GetByPtr indicates an expected call of GetByPtr. -func (mr *MockRepositoryMockRecorder) GetByPtr(contract, ptr any) *RepositoryGetByPtrCall { +func (mr *MockRepositoryMockRecorder) GetByPtr(ctx, contract, ptr any) *RepositoryGetByPtrCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByPtr", reflect.TypeOf((*MockRepository)(nil).GetByPtr), contract, ptr) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByPtr", reflect.TypeOf((*MockRepository)(nil).GetByPtr), ctx, contract, ptr) return &RepositoryGetByPtrCall{Call: call} } @@ -261,21 +184,21 @@ func (c *RepositoryGetByPtrCall) Return(arg0 []bigmapdiff.BigMapState, arg1 erro } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetByPtrCall) Do(f func(string, int64) ([]bigmapdiff.BigMapState, error)) *RepositoryGetByPtrCall { +func (c *RepositoryGetByPtrCall) Do(f func(context.Context, string, int64) ([]bigmapdiff.BigMapState, error)) *RepositoryGetByPtrCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetByPtrCall) DoAndReturn(f func(string, int64) ([]bigmapdiff.BigMapState, error)) *RepositoryGetByPtrCall { +func (c *RepositoryGetByPtrCall) DoAndReturn(f func(context.Context, string, int64) ([]bigmapdiff.BigMapState, error)) *RepositoryGetByPtrCall { c.Call = c.Call.DoAndReturn(f) return c } // GetByPtrAndKeyHash mocks base method. -func (m *MockRepository) GetByPtrAndKeyHash(ptr int64, keyHash string, size, offset int64) ([]bigmapdiff.BigMapDiff, int64, error) { +func (m *MockRepository) GetByPtrAndKeyHash(ctx context.Context, ptr int64, keyHash string, size, offset int64) ([]bigmapdiff.BigMapDiff, int64, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByPtrAndKeyHash", ptr, keyHash, size, offset) + ret := m.ctrl.Call(m, "GetByPtrAndKeyHash", ctx, ptr, keyHash, size, offset) ret0, _ := ret[0].([]bigmapdiff.BigMapDiff) ret1, _ := ret[1].(int64) ret2, _ := ret[2].(error) @@ -283,9 +206,9 @@ func (m *MockRepository) GetByPtrAndKeyHash(ptr int64, keyHash string, size, off } // GetByPtrAndKeyHash indicates an expected call of GetByPtrAndKeyHash. -func (mr *MockRepositoryMockRecorder) GetByPtrAndKeyHash(ptr, keyHash, size, offset any) *RepositoryGetByPtrAndKeyHashCall { +func (mr *MockRepositoryMockRecorder) GetByPtrAndKeyHash(ctx, ptr, keyHash, size, offset any) *RepositoryGetByPtrAndKeyHashCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByPtrAndKeyHash", reflect.TypeOf((*MockRepository)(nil).GetByPtrAndKeyHash), ptr, keyHash, size, offset) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByPtrAndKeyHash", reflect.TypeOf((*MockRepository)(nil).GetByPtrAndKeyHash), ctx, ptr, keyHash, size, offset) return &RepositoryGetByPtrAndKeyHashCall{Call: call} } @@ -301,30 +224,30 @@ func (c *RepositoryGetByPtrAndKeyHashCall) Return(arg0 []bigmapdiff.BigMapDiff, } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetByPtrAndKeyHashCall) Do(f func(int64, string, int64, int64) ([]bigmapdiff.BigMapDiff, int64, error)) *RepositoryGetByPtrAndKeyHashCall { +func (c *RepositoryGetByPtrAndKeyHashCall) Do(f func(context.Context, int64, string, int64, int64) ([]bigmapdiff.BigMapDiff, int64, error)) *RepositoryGetByPtrAndKeyHashCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetByPtrAndKeyHashCall) DoAndReturn(f func(int64, string, int64, int64) ([]bigmapdiff.BigMapDiff, int64, error)) *RepositoryGetByPtrAndKeyHashCall { +func (c *RepositoryGetByPtrAndKeyHashCall) DoAndReturn(f func(context.Context, int64, string, int64, int64) ([]bigmapdiff.BigMapDiff, int64, error)) *RepositoryGetByPtrAndKeyHashCall { c.Call = c.Call.DoAndReturn(f) return c } // GetForAddress mocks base method. -func (m *MockRepository) GetForAddress(address string) ([]bigmapdiff.BigMapState, error) { +func (m *MockRepository) GetForAddress(ctx context.Context, address string) ([]bigmapdiff.BigMapState, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetForAddress", address) + ret := m.ctrl.Call(m, "GetForAddress", ctx, address) ret0, _ := ret[0].([]bigmapdiff.BigMapState) ret1, _ := ret[1].(error) return ret0, ret1 } // GetForAddress indicates an expected call of GetForAddress. -func (mr *MockRepositoryMockRecorder) GetForAddress(address any) *RepositoryGetForAddressCall { +func (mr *MockRepositoryMockRecorder) GetForAddress(ctx, address any) *RepositoryGetForAddressCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetForAddress", reflect.TypeOf((*MockRepository)(nil).GetForAddress), address) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetForAddress", reflect.TypeOf((*MockRepository)(nil).GetForAddress), ctx, address) return &RepositoryGetForAddressCall{Call: call} } @@ -340,30 +263,30 @@ func (c *RepositoryGetForAddressCall) Return(arg0 []bigmapdiff.BigMapState, arg1 } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetForAddressCall) Do(f func(string) ([]bigmapdiff.BigMapState, error)) *RepositoryGetForAddressCall { +func (c *RepositoryGetForAddressCall) Do(f func(context.Context, string) ([]bigmapdiff.BigMapState, error)) *RepositoryGetForAddressCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetForAddressCall) DoAndReturn(f func(string) ([]bigmapdiff.BigMapState, error)) *RepositoryGetForAddressCall { +func (c *RepositoryGetForAddressCall) DoAndReturn(f func(context.Context, string) ([]bigmapdiff.BigMapState, error)) *RepositoryGetForAddressCall { c.Call = c.Call.DoAndReturn(f) return c } // GetForOperation mocks base method. -func (m *MockRepository) GetForOperation(id int64) ([]bigmapdiff.BigMapDiff, error) { +func (m *MockRepository) GetForOperation(ctx context.Context, id int64) ([]bigmapdiff.BigMapDiff, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetForOperation", id) + ret := m.ctrl.Call(m, "GetForOperation", ctx, id) ret0, _ := ret[0].([]bigmapdiff.BigMapDiff) ret1, _ := ret[1].(error) return ret0, ret1 } // GetForOperation indicates an expected call of GetForOperation. -func (mr *MockRepositoryMockRecorder) GetForOperation(id any) *RepositoryGetForOperationCall { +func (mr *MockRepositoryMockRecorder) GetForOperation(ctx, id any) *RepositoryGetForOperationCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetForOperation", reflect.TypeOf((*MockRepository)(nil).GetForOperation), id) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetForOperation", reflect.TypeOf((*MockRepository)(nil).GetForOperation), ctx, id) return &RepositoryGetForOperationCall{Call: call} } @@ -379,30 +302,30 @@ func (c *RepositoryGetForOperationCall) Return(arg0 []bigmapdiff.BigMapDiff, arg } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetForOperationCall) Do(f func(int64) ([]bigmapdiff.BigMapDiff, error)) *RepositoryGetForOperationCall { +func (c *RepositoryGetForOperationCall) Do(f func(context.Context, int64) ([]bigmapdiff.BigMapDiff, error)) *RepositoryGetForOperationCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetForOperationCall) DoAndReturn(f func(int64) ([]bigmapdiff.BigMapDiff, error)) *RepositoryGetForOperationCall { +func (c *RepositoryGetForOperationCall) DoAndReturn(f func(context.Context, int64) ([]bigmapdiff.BigMapDiff, error)) *RepositoryGetForOperationCall { c.Call = c.Call.DoAndReturn(f) return c } // GetStats mocks base method. -func (m *MockRepository) GetStats(ptr int64) (bigmapdiff.Stats, error) { +func (m *MockRepository) GetStats(ctx context.Context, ptr int64) (bigmapdiff.Stats, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetStats", ptr) + ret := m.ctrl.Call(m, "GetStats", ctx, ptr) ret0, _ := ret[0].(bigmapdiff.Stats) ret1, _ := ret[1].(error) return ret0, ret1 } // GetStats indicates an expected call of GetStats. -func (mr *MockRepositoryMockRecorder) GetStats(ptr any) *RepositoryGetStatsCall { +func (mr *MockRepositoryMockRecorder) GetStats(ctx, ptr any) *RepositoryGetStatsCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStats", reflect.TypeOf((*MockRepository)(nil).GetStats), ptr) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetStats", reflect.TypeOf((*MockRepository)(nil).GetStats), ctx, ptr) return &RepositoryGetStatsCall{Call: call} } @@ -418,69 +341,30 @@ func (c *RepositoryGetStatsCall) Return(arg0 bigmapdiff.Stats, arg1 error) *Repo } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetStatsCall) Do(f func(int64) (bigmapdiff.Stats, error)) *RepositoryGetStatsCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetStatsCall) DoAndReturn(f func(int64) (bigmapdiff.Stats, error)) *RepositoryGetStatsCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// GetValuesByKey mocks base method. -func (m *MockRepository) GetValuesByKey(keyHash string) ([]bigmapdiff.BigMapState, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetValuesByKey", keyHash) - ret0, _ := ret[0].([]bigmapdiff.BigMapState) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetValuesByKey indicates an expected call of GetValuesByKey. -func (mr *MockRepositoryMockRecorder) GetValuesByKey(keyHash any) *RepositoryGetValuesByKeyCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetValuesByKey", reflect.TypeOf((*MockRepository)(nil).GetValuesByKey), keyHash) - return &RepositoryGetValuesByKeyCall{Call: call} -} - -// RepositoryGetValuesByKeyCall wrap *gomock.Call -type RepositoryGetValuesByKeyCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryGetValuesByKeyCall) Return(arg0 []bigmapdiff.BigMapState, arg1 error) *RepositoryGetValuesByKeyCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryGetValuesByKeyCall) Do(f func(string) ([]bigmapdiff.BigMapState, error)) *RepositoryGetValuesByKeyCall { +func (c *RepositoryGetStatsCall) Do(f func(context.Context, int64) (bigmapdiff.Stats, error)) *RepositoryGetStatsCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetValuesByKeyCall) DoAndReturn(f func(string) ([]bigmapdiff.BigMapState, error)) *RepositoryGetValuesByKeyCall { +func (c *RepositoryGetStatsCall) DoAndReturn(f func(context.Context, int64) (bigmapdiff.Stats, error)) *RepositoryGetStatsCall { c.Call = c.Call.DoAndReturn(f) return c } // Keys mocks base method. -func (m *MockRepository) Keys(ctx bigmapdiff.GetContext) ([]bigmapdiff.BigMapState, error) { +func (m *MockRepository) Keys(ctx context.Context, reqCtx bigmapdiff.GetContext) ([]bigmapdiff.BigMapState, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Keys", ctx) + ret := m.ctrl.Call(m, "Keys", ctx, reqCtx) ret0, _ := ret[0].([]bigmapdiff.BigMapState) ret1, _ := ret[1].(error) return ret0, ret1 } // Keys indicates an expected call of Keys. -func (mr *MockRepositoryMockRecorder) Keys(ctx any) *RepositoryKeysCall { +func (mr *MockRepositoryMockRecorder) Keys(ctx, reqCtx any) *RepositoryKeysCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Keys", reflect.TypeOf((*MockRepository)(nil).Keys), ctx) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Keys", reflect.TypeOf((*MockRepository)(nil).Keys), ctx, reqCtx) return &RepositoryKeysCall{Call: call} } @@ -496,69 +380,30 @@ func (c *RepositoryKeysCall) Return(states []bigmapdiff.BigMapState, err error) } // Do rewrite *gomock.Call.Do -func (c *RepositoryKeysCall) Do(f func(bigmapdiff.GetContext) ([]bigmapdiff.BigMapState, error)) *RepositoryKeysCall { +func (c *RepositoryKeysCall) Do(f func(context.Context, bigmapdiff.GetContext) ([]bigmapdiff.BigMapState, error)) *RepositoryKeysCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryKeysCall) DoAndReturn(f func(bigmapdiff.GetContext) ([]bigmapdiff.BigMapState, error)) *RepositoryKeysCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// LastDiff mocks base method. -func (m *MockRepository) LastDiff(ptr int64, keyHash string, skipRemoved bool) (bigmapdiff.BigMapDiff, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "LastDiff", ptr, keyHash, skipRemoved) - ret0, _ := ret[0].(bigmapdiff.BigMapDiff) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// LastDiff indicates an expected call of LastDiff. -func (mr *MockRepositoryMockRecorder) LastDiff(ptr, keyHash, skipRemoved any) *RepositoryLastDiffCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastDiff", reflect.TypeOf((*MockRepository)(nil).LastDiff), ptr, keyHash, skipRemoved) - return &RepositoryLastDiffCall{Call: call} -} - -// RepositoryLastDiffCall wrap *gomock.Call -type RepositoryLastDiffCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryLastDiffCall) Return(arg0 bigmapdiff.BigMapDiff, arg1 error) *RepositoryLastDiffCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryLastDiffCall) Do(f func(int64, string, bool) (bigmapdiff.BigMapDiff, error)) *RepositoryLastDiffCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryLastDiffCall) DoAndReturn(f func(int64, string, bool) (bigmapdiff.BigMapDiff, error)) *RepositoryLastDiffCall { +func (c *RepositoryKeysCall) DoAndReturn(f func(context.Context, bigmapdiff.GetContext) ([]bigmapdiff.BigMapState, error)) *RepositoryKeysCall { c.Call = c.Call.DoAndReturn(f) return c } // Previous mocks base method. -func (m *MockRepository) Previous(arg0 []bigmapdiff.BigMapDiff) ([]bigmapdiff.BigMapDiff, error) { +func (m *MockRepository) Previous(ctx context.Context, diffs []bigmapdiff.BigMapDiff) ([]bigmapdiff.BigMapDiff, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Previous", arg0) + ret := m.ctrl.Call(m, "Previous", ctx, diffs) ret0, _ := ret[0].([]bigmapdiff.BigMapDiff) ret1, _ := ret[1].(error) return ret0, ret1 } // Previous indicates an expected call of Previous. -func (mr *MockRepositoryMockRecorder) Previous(arg0 any) *RepositoryPreviousCall { +func (mr *MockRepositoryMockRecorder) Previous(ctx, diffs any) *RepositoryPreviousCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Previous", reflect.TypeOf((*MockRepository)(nil).Previous), arg0) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Previous", reflect.TypeOf((*MockRepository)(nil).Previous), ctx, diffs) return &RepositoryPreviousCall{Call: call} } @@ -574,52 +419,13 @@ func (c *RepositoryPreviousCall) Return(arg0 []bigmapdiff.BigMapDiff, arg1 error } // Do rewrite *gomock.Call.Do -func (c *RepositoryPreviousCall) Do(f func([]bigmapdiff.BigMapDiff) ([]bigmapdiff.BigMapDiff, error)) *RepositoryPreviousCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryPreviousCall) DoAndReturn(f func([]bigmapdiff.BigMapDiff) ([]bigmapdiff.BigMapDiff, error)) *RepositoryPreviousCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// StatesChangedAfter mocks base method. -func (m *MockRepository) StatesChangedAfter(level int64) ([]bigmapdiff.BigMapState, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "StatesChangedAfter", level) - ret0, _ := ret[0].([]bigmapdiff.BigMapState) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// StatesChangedAfter indicates an expected call of StatesChangedAfter. -func (mr *MockRepositoryMockRecorder) StatesChangedAfter(level any) *RepositoryStatesChangedAfterCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StatesChangedAfter", reflect.TypeOf((*MockRepository)(nil).StatesChangedAfter), level) - return &RepositoryStatesChangedAfterCall{Call: call} -} - -// RepositoryStatesChangedAfterCall wrap *gomock.Call -type RepositoryStatesChangedAfterCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryStatesChangedAfterCall) Return(arg0 []bigmapdiff.BigMapState, arg1 error) *RepositoryStatesChangedAfterCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryStatesChangedAfterCall) Do(f func(int64) ([]bigmapdiff.BigMapState, error)) *RepositoryStatesChangedAfterCall { +func (c *RepositoryPreviousCall) Do(f func(context.Context, []bigmapdiff.BigMapDiff) ([]bigmapdiff.BigMapDiff, error)) *RepositoryPreviousCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryStatesChangedAfterCall) DoAndReturn(f func(int64) ([]bigmapdiff.BigMapState, error)) *RepositoryStatesChangedAfterCall { +func (c *RepositoryPreviousCall) DoAndReturn(f func(context.Context, []bigmapdiff.BigMapDiff) ([]bigmapdiff.BigMapDiff, error)) *RepositoryPreviousCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/internal/models/mock/block/mock.go b/internal/models/mock/block/mock.go index 371dadd13..eac93b13b 100644 --- a/internal/models/mock/block/mock.go +++ b/internal/models/mock/block/mock.go @@ -9,6 +9,7 @@ package block import ( + context "context" reflect "reflect" block "github.com/baking-bad/bcdhub/internal/models/block" @@ -39,18 +40,18 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { } // Get mocks base method. -func (m *MockRepository) Get(level int64) (block.Block, error) { +func (m *MockRepository) Get(ctx context.Context, level int64) (block.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", level) + ret := m.ctrl.Call(m, "Get", ctx, level) ret0, _ := ret[0].(block.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get. -func (mr *MockRepositoryMockRecorder) Get(level any) *RepositoryGetCall { +func (mr *MockRepositoryMockRecorder) Get(ctx, level any) *RepositoryGetCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), level) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), ctx, level) return &RepositoryGetCall{Call: call} } @@ -66,30 +67,30 @@ func (c *RepositoryGetCall) Return(arg0 block.Block, arg1 error) *RepositoryGetC } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetCall) Do(f func(int64) (block.Block, error)) *RepositoryGetCall { +func (c *RepositoryGetCall) Do(f func(context.Context, int64) (block.Block, error)) *RepositoryGetCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetCall) DoAndReturn(f func(int64) (block.Block, error)) *RepositoryGetCall { +func (c *RepositoryGetCall) DoAndReturn(f func(context.Context, int64) (block.Block, error)) *RepositoryGetCall { c.Call = c.Call.DoAndReturn(f) return c } // Last mocks base method. -func (m *MockRepository) Last() (block.Block, error) { +func (m *MockRepository) Last(ctx context.Context) (block.Block, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Last") + ret := m.ctrl.Call(m, "Last", ctx) ret0, _ := ret[0].(block.Block) ret1, _ := ret[1].(error) return ret0, ret1 } // Last indicates an expected call of Last. -func (mr *MockRepositoryMockRecorder) Last() *RepositoryLastCall { +func (mr *MockRepositoryMockRecorder) Last(ctx any) *RepositoryLastCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Last", reflect.TypeOf((*MockRepository)(nil).Last)) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Last", reflect.TypeOf((*MockRepository)(nil).Last), ctx) return &RepositoryLastCall{Call: call} } @@ -105,13 +106,13 @@ func (c *RepositoryLastCall) Return(arg0 block.Block, arg1 error) *RepositoryLas } // Do rewrite *gomock.Call.Do -func (c *RepositoryLastCall) Do(f func() (block.Block, error)) *RepositoryLastCall { +func (c *RepositoryLastCall) Do(f func(context.Context) (block.Block, error)) *RepositoryLastCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryLastCall) DoAndReturn(f func() (block.Block, error)) *RepositoryLastCall { +func (c *RepositoryLastCall) DoAndReturn(f func(context.Context) (block.Block, error)) *RepositoryLastCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/internal/models/mock/contract/mock.go b/internal/models/mock/contract/mock.go index df1efa0d7..e743cdbdc 100644 --- a/internal/models/mock/contract/mock.go +++ b/internal/models/mock/contract/mock.go @@ -9,6 +9,7 @@ package contract import ( + context "context" reflect "reflect" contract "github.com/baking-bad/bcdhub/internal/models/contract" @@ -39,58 +40,58 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { return m.recorder } -// Count mocks base method. -func (m *MockRepository) Count() (int, error) { +// AllExceptDelegators mocks base method. +func (m *MockRepository) AllExceptDelegators(ctx context.Context) ([]contract.Contract, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Count") - ret0, _ := ret[0].(int) + ret := m.ctrl.Call(m, "AllExceptDelegators", ctx) + ret0, _ := ret[0].([]contract.Contract) ret1, _ := ret[1].(error) return ret0, ret1 } -// Count indicates an expected call of Count. -func (mr *MockRepositoryMockRecorder) Count() *RepositoryCountCall { +// AllExceptDelegators indicates an expected call of AllExceptDelegators. +func (mr *MockRepositoryMockRecorder) AllExceptDelegators(ctx any) *RepositoryAllExceptDelegatorsCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Count", reflect.TypeOf((*MockRepository)(nil).Count)) - return &RepositoryCountCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AllExceptDelegators", reflect.TypeOf((*MockRepository)(nil).AllExceptDelegators), ctx) + return &RepositoryAllExceptDelegatorsCall{Call: call} } -// RepositoryCountCall wrap *gomock.Call -type RepositoryCountCall struct { +// RepositoryAllExceptDelegatorsCall wrap *gomock.Call +type RepositoryAllExceptDelegatorsCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *RepositoryCountCall) Return(arg0 int, arg1 error) *RepositoryCountCall { +func (c *RepositoryAllExceptDelegatorsCall) Return(arg0 []contract.Contract, arg1 error) *RepositoryAllExceptDelegatorsCall { c.Call = c.Call.Return(arg0, arg1) return c } // Do rewrite *gomock.Call.Do -func (c *RepositoryCountCall) Do(f func() (int, error)) *RepositoryCountCall { +func (c *RepositoryAllExceptDelegatorsCall) Do(f func(context.Context) ([]contract.Contract, error)) *RepositoryAllExceptDelegatorsCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryCountCall) DoAndReturn(f func() (int, error)) *RepositoryCountCall { +func (c *RepositoryAllExceptDelegatorsCall) DoAndReturn(f func(context.Context) ([]contract.Contract, error)) *RepositoryAllExceptDelegatorsCall { c.Call = c.Call.DoAndReturn(f) return c } // FindOne mocks base method. -func (m *MockRepository) FindOne(tags types.Tags) (contract.Contract, error) { +func (m *MockRepository) FindOne(ctx context.Context, tags types.Tags) (contract.Contract, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "FindOne", tags) + ret := m.ctrl.Call(m, "FindOne", ctx, tags) ret0, _ := ret[0].(contract.Contract) ret1, _ := ret[1].(error) return ret0, ret1 } // FindOne indicates an expected call of FindOne. -func (mr *MockRepositoryMockRecorder) FindOne(tags any) *RepositoryFindOneCall { +func (mr *MockRepositoryMockRecorder) FindOne(ctx, tags any) *RepositoryFindOneCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockRepository)(nil).FindOne), tags) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "FindOne", reflect.TypeOf((*MockRepository)(nil).FindOne), ctx, tags) return &RepositoryFindOneCall{Call: call} } @@ -106,30 +107,30 @@ func (c *RepositoryFindOneCall) Return(arg0 contract.Contract, arg1 error) *Repo } // Do rewrite *gomock.Call.Do -func (c *RepositoryFindOneCall) Do(f func(types.Tags) (contract.Contract, error)) *RepositoryFindOneCall { +func (c *RepositoryFindOneCall) Do(f func(context.Context, types.Tags) (contract.Contract, error)) *RepositoryFindOneCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryFindOneCall) DoAndReturn(f func(types.Tags) (contract.Contract, error)) *RepositoryFindOneCall { +func (c *RepositoryFindOneCall) DoAndReturn(f func(context.Context, types.Tags) (contract.Contract, error)) *RepositoryFindOneCall { c.Call = c.Call.DoAndReturn(f) return c } // Get mocks base method. -func (m *MockRepository) Get(address string) (contract.Contract, error) { +func (m *MockRepository) Get(ctx context.Context, address string) (contract.Contract, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", address) + ret := m.ctrl.Call(m, "Get", ctx, address) ret0, _ := ret[0].(contract.Contract) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get. -func (mr *MockRepositoryMockRecorder) Get(address any) *RepositoryGetCall { +func (mr *MockRepositoryMockRecorder) Get(ctx, address any) *RepositoryGetCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), address) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), ctx, address) return &RepositoryGetCall{Call: call} } @@ -145,187 +146,30 @@ func (c *RepositoryGetCall) Return(arg0 contract.Contract, arg1 error) *Reposito } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetCall) Do(f func(string) (contract.Contract, error)) *RepositoryGetCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetCall) DoAndReturn(f func(string) (contract.Contract, error)) *RepositoryGetCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// GetAll mocks base method. -func (m *MockRepository) GetAll(filters map[string]any) ([]contract.Contract, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAll", filters) - ret0, _ := ret[0].([]contract.Contract) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAll indicates an expected call of GetAll. -func (mr *MockRepositoryMockRecorder) GetAll(filters any) *RepositoryGetAllCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAll", reflect.TypeOf((*MockRepository)(nil).GetAll), filters) - return &RepositoryGetAllCall{Call: call} -} - -// RepositoryGetAllCall wrap *gomock.Call -type RepositoryGetAllCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryGetAllCall) Return(arg0 []contract.Contract, arg1 error) *RepositoryGetAllCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryGetAllCall) Do(f func(map[string]any) ([]contract.Contract, error)) *RepositoryGetAllCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetAllCall) DoAndReturn(f func(map[string]any) ([]contract.Contract, error)) *RepositoryGetAllCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// GetRandom mocks base method. -func (m *MockRepository) GetRandom() (contract.Contract, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetRandom") - ret0, _ := ret[0].(contract.Contract) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetRandom indicates an expected call of GetRandom. -func (mr *MockRepositoryMockRecorder) GetRandom() *RepositoryGetRandomCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRandom", reflect.TypeOf((*MockRepository)(nil).GetRandom)) - return &RepositoryGetRandomCall{Call: call} -} - -// RepositoryGetRandomCall wrap *gomock.Call -type RepositoryGetRandomCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryGetRandomCall) Return(arg0 contract.Contract, arg1 error) *RepositoryGetRandomCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryGetRandomCall) Do(f func() (contract.Contract, error)) *RepositoryGetRandomCall { +func (c *RepositoryGetCall) Do(f func(context.Context, string) (contract.Contract, error)) *RepositoryGetCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetRandomCall) DoAndReturn(f func() (contract.Contract, error)) *RepositoryGetRandomCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// GetTokens mocks base method. -func (m *MockRepository) GetTokens(tokenInterface string, offset, size int64) ([]contract.Contract, int64, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetTokens", tokenInterface, offset, size) - ret0, _ := ret[0].([]contract.Contract) - ret1, _ := ret[1].(int64) - ret2, _ := ret[2].(error) - return ret0, ret1, ret2 -} - -// GetTokens indicates an expected call of GetTokens. -func (mr *MockRepositoryMockRecorder) GetTokens(tokenInterface, offset, size any) *RepositoryGetTokensCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTokens", reflect.TypeOf((*MockRepository)(nil).GetTokens), tokenInterface, offset, size) - return &RepositoryGetTokensCall{Call: call} -} - -// RepositoryGetTokensCall wrap *gomock.Call -type RepositoryGetTokensCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryGetTokensCall) Return(arg0 []contract.Contract, arg1 int64, arg2 error) *RepositoryGetTokensCall { - c.Call = c.Call.Return(arg0, arg1, arg2) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryGetTokensCall) Do(f func(string, int64, int64) ([]contract.Contract, int64, error)) *RepositoryGetTokensCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetTokensCall) DoAndReturn(f func(string, int64, int64) ([]contract.Contract, int64, error)) *RepositoryGetTokensCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// RecentlyCalled mocks base method. -func (m *MockRepository) RecentlyCalled(offset, size int64) ([]contract.Contract, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "RecentlyCalled", offset, size) - ret0, _ := ret[0].([]contract.Contract) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// RecentlyCalled indicates an expected call of RecentlyCalled. -func (mr *MockRepositoryMockRecorder) RecentlyCalled(offset, size any) *RepositoryRecentlyCalledCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "RecentlyCalled", reflect.TypeOf((*MockRepository)(nil).RecentlyCalled), offset, size) - return &RepositoryRecentlyCalledCall{Call: call} -} - -// RepositoryRecentlyCalledCall wrap *gomock.Call -type RepositoryRecentlyCalledCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryRecentlyCalledCall) Return(arg0 []contract.Contract, arg1 error) *RepositoryRecentlyCalledCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryRecentlyCalledCall) Do(f func(int64, int64) ([]contract.Contract, error)) *RepositoryRecentlyCalledCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryRecentlyCalledCall) DoAndReturn(f func(int64, int64) ([]contract.Contract, error)) *RepositoryRecentlyCalledCall { +func (c *RepositoryGetCall) DoAndReturn(f func(context.Context, string) (contract.Contract, error)) *RepositoryGetCall { c.Call = c.Call.DoAndReturn(f) return c } // Script mocks base method. -func (m *MockRepository) Script(address, symLink string) (contract.Script, error) { +func (m *MockRepository) Script(ctx context.Context, address, symLink string) (contract.Script, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Script", address, symLink) + ret := m.ctrl.Call(m, "Script", ctx, address, symLink) ret0, _ := ret[0].(contract.Script) ret1, _ := ret[1].(error) return ret0, ret1 } // Script indicates an expected call of Script. -func (mr *MockRepositoryMockRecorder) Script(address, symLink any) *RepositoryScriptCall { +func (mr *MockRepositoryMockRecorder) Script(ctx, address, symLink any) *RepositoryScriptCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Script", reflect.TypeOf((*MockRepository)(nil).Script), address, symLink) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Script", reflect.TypeOf((*MockRepository)(nil).Script), ctx, address, symLink) return &RepositoryScriptCall{Call: call} } @@ -341,30 +185,30 @@ func (c *RepositoryScriptCall) Return(arg0 contract.Script, arg1 error) *Reposit } // Do rewrite *gomock.Call.Do -func (c *RepositoryScriptCall) Do(f func(string, string) (contract.Script, error)) *RepositoryScriptCall { +func (c *RepositoryScriptCall) Do(f func(context.Context, string, string) (contract.Script, error)) *RepositoryScriptCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryScriptCall) DoAndReturn(f func(string, string) (contract.Script, error)) *RepositoryScriptCall { +func (c *RepositoryScriptCall) DoAndReturn(f func(context.Context, string, string) (contract.Script, error)) *RepositoryScriptCall { c.Call = c.Call.DoAndReturn(f) return c } // ScriptPart mocks base method. -func (m *MockRepository) ScriptPart(address, symLink, part string) ([]byte, error) { +func (m *MockRepository) ScriptPart(ctx context.Context, address, symLink, part string) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ScriptPart", address, symLink, part) + ret := m.ctrl.Call(m, "ScriptPart", ctx, address, symLink, part) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // ScriptPart indicates an expected call of ScriptPart. -func (mr *MockRepositoryMockRecorder) ScriptPart(address, symLink, part any) *RepositoryScriptPartCall { +func (mr *MockRepositoryMockRecorder) ScriptPart(ctx, address, symLink, part any) *RepositoryScriptPartCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScriptPart", reflect.TypeOf((*MockRepository)(nil).ScriptPart), address, symLink, part) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScriptPart", reflect.TypeOf((*MockRepository)(nil).ScriptPart), ctx, address, symLink, part) return &RepositoryScriptPartCall{Call: call} } @@ -380,13 +224,13 @@ func (c *RepositoryScriptPartCall) Return(arg0 []byte, arg1 error) *RepositorySc } // Do rewrite *gomock.Call.Do -func (c *RepositoryScriptPartCall) Do(f func(string, string, string) ([]byte, error)) *RepositoryScriptPartCall { +func (c *RepositoryScriptPartCall) Do(f func(context.Context, string, string, string) ([]byte, error)) *RepositoryScriptPartCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryScriptPartCall) DoAndReturn(f func(string, string, string) ([]byte, error)) *RepositoryScriptPartCall { +func (c *RepositoryScriptPartCall) DoAndReturn(f func(context.Context, string, string, string) ([]byte, error)) *RepositoryScriptPartCall { c.Call = c.Call.DoAndReturn(f) return c } @@ -415,18 +259,18 @@ func (m *MockScriptRepository) EXPECT() *MockScriptRepositoryMockRecorder { } // ByHash mocks base method. -func (m *MockScriptRepository) ByHash(hash string) (contract.Script, error) { +func (m *MockScriptRepository) ByHash(ctx context.Context, hash string) (contract.Script, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ByHash", hash) + ret := m.ctrl.Call(m, "ByHash", ctx, hash) ret0, _ := ret[0].(contract.Script) ret1, _ := ret[1].(error) return ret0, ret1 } // ByHash indicates an expected call of ByHash. -func (mr *MockScriptRepositoryMockRecorder) ByHash(hash any) *ScriptRepositoryByHashCall { +func (mr *MockScriptRepositoryMockRecorder) ByHash(ctx, hash any) *ScriptRepositoryByHashCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ByHash", reflect.TypeOf((*MockScriptRepository)(nil).ByHash), hash) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ByHash", reflect.TypeOf((*MockScriptRepository)(nil).ByHash), ctx, hash) return &ScriptRepositoryByHashCall{Call: call} } @@ -442,30 +286,30 @@ func (c *ScriptRepositoryByHashCall) Return(arg0 contract.Script, arg1 error) *S } // Do rewrite *gomock.Call.Do -func (c *ScriptRepositoryByHashCall) Do(f func(string) (contract.Script, error)) *ScriptRepositoryByHashCall { +func (c *ScriptRepositoryByHashCall) Do(f func(context.Context, string) (contract.Script, error)) *ScriptRepositoryByHashCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ScriptRepositoryByHashCall) DoAndReturn(f func(string) (contract.Script, error)) *ScriptRepositoryByHashCall { +func (c *ScriptRepositoryByHashCall) DoAndReturn(f func(context.Context, string) (contract.Script, error)) *ScriptRepositoryByHashCall { c.Call = c.Call.DoAndReturn(f) return c } // Code mocks base method. -func (m *MockScriptRepository) Code(id int64) ([]byte, error) { +func (m *MockScriptRepository) Code(ctx context.Context, id int64) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Code", id) + ret := m.ctrl.Call(m, "Code", ctx, id) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // Code indicates an expected call of Code. -func (mr *MockScriptRepositoryMockRecorder) Code(id any) *ScriptRepositoryCodeCall { +func (mr *MockScriptRepositoryMockRecorder) Code(ctx, id any) *ScriptRepositoryCodeCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Code", reflect.TypeOf((*MockScriptRepository)(nil).Code), id) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Code", reflect.TypeOf((*MockScriptRepository)(nil).Code), ctx, id) return &ScriptRepositoryCodeCall{Call: call} } @@ -481,69 +325,30 @@ func (c *ScriptRepositoryCodeCall) Return(arg0 []byte, arg1 error) *ScriptReposi } // Do rewrite *gomock.Call.Do -func (c *ScriptRepositoryCodeCall) Do(f func(int64) ([]byte, error)) *ScriptRepositoryCodeCall { +func (c *ScriptRepositoryCodeCall) Do(f func(context.Context, int64) ([]byte, error)) *ScriptRepositoryCodeCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ScriptRepositoryCodeCall) DoAndReturn(f func(int64) ([]byte, error)) *ScriptRepositoryCodeCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// GetScripts mocks base method. -func (m *MockScriptRepository) GetScripts(limit, offset int) ([]contract.Script, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetScripts", limit, offset) - ret0, _ := ret[0].([]contract.Script) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetScripts indicates an expected call of GetScripts. -func (mr *MockScriptRepositoryMockRecorder) GetScripts(limit, offset any) *ScriptRepositoryGetScriptsCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetScripts", reflect.TypeOf((*MockScriptRepository)(nil).GetScripts), limit, offset) - return &ScriptRepositoryGetScriptsCall{Call: call} -} - -// ScriptRepositoryGetScriptsCall wrap *gomock.Call -type ScriptRepositoryGetScriptsCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *ScriptRepositoryGetScriptsCall) Return(arg0 []contract.Script, arg1 error) *ScriptRepositoryGetScriptsCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *ScriptRepositoryGetScriptsCall) Do(f func(int, int) ([]contract.Script, error)) *ScriptRepositoryGetScriptsCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ScriptRepositoryGetScriptsCall) DoAndReturn(f func(int, int) ([]contract.Script, error)) *ScriptRepositoryGetScriptsCall { +func (c *ScriptRepositoryCodeCall) DoAndReturn(f func(context.Context, int64) ([]byte, error)) *ScriptRepositoryCodeCall { c.Call = c.Call.DoAndReturn(f) return c } // Parameter mocks base method. -func (m *MockScriptRepository) Parameter(id int64) ([]byte, error) { +func (m *MockScriptRepository) Parameter(ctx context.Context, id int64) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Parameter", id) + ret := m.ctrl.Call(m, "Parameter", ctx, id) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // Parameter indicates an expected call of Parameter. -func (mr *MockScriptRepositoryMockRecorder) Parameter(id any) *ScriptRepositoryParameterCall { +func (mr *MockScriptRepositoryMockRecorder) Parameter(ctx, id any) *ScriptRepositoryParameterCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Parameter", reflect.TypeOf((*MockScriptRepository)(nil).Parameter), id) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Parameter", reflect.TypeOf((*MockScriptRepository)(nil).Parameter), ctx, id) return &ScriptRepositoryParameterCall{Call: call} } @@ -559,30 +364,30 @@ func (c *ScriptRepositoryParameterCall) Return(arg0 []byte, arg1 error) *ScriptR } // Do rewrite *gomock.Call.Do -func (c *ScriptRepositoryParameterCall) Do(f func(int64) ([]byte, error)) *ScriptRepositoryParameterCall { +func (c *ScriptRepositoryParameterCall) Do(f func(context.Context, int64) ([]byte, error)) *ScriptRepositoryParameterCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ScriptRepositoryParameterCall) DoAndReturn(f func(int64) ([]byte, error)) *ScriptRepositoryParameterCall { +func (c *ScriptRepositoryParameterCall) DoAndReturn(f func(context.Context, int64) ([]byte, error)) *ScriptRepositoryParameterCall { c.Call = c.Call.DoAndReturn(f) return c } // Storage mocks base method. -func (m *MockScriptRepository) Storage(id int64) ([]byte, error) { +func (m *MockScriptRepository) Storage(ctx context.Context, id int64) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Storage", id) + ret := m.ctrl.Call(m, "Storage", ctx, id) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // Storage indicates an expected call of Storage. -func (mr *MockScriptRepositoryMockRecorder) Storage(id any) *ScriptRepositoryStorageCall { +func (mr *MockScriptRepositoryMockRecorder) Storage(ctx, id any) *ScriptRepositoryStorageCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Storage", reflect.TypeOf((*MockScriptRepository)(nil).Storage), id) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Storage", reflect.TypeOf((*MockScriptRepository)(nil).Storage), ctx, id) return &ScriptRepositoryStorageCall{Call: call} } @@ -598,68 +403,30 @@ func (c *ScriptRepositoryStorageCall) Return(arg0 []byte, arg1 error) *ScriptRep } // Do rewrite *gomock.Call.Do -func (c *ScriptRepositoryStorageCall) Do(f func(int64) ([]byte, error)) *ScriptRepositoryStorageCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ScriptRepositoryStorageCall) DoAndReturn(f func(int64) ([]byte, error)) *ScriptRepositoryStorageCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// UpdateProjectID mocks base method. -func (m *MockScriptRepository) UpdateProjectID(script []contract.Script) error { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateProjectID", script) - ret0, _ := ret[0].(error) - return ret0 -} - -// UpdateProjectID indicates an expected call of UpdateProjectID. -func (mr *MockScriptRepositoryMockRecorder) UpdateProjectID(script any) *ScriptRepositoryUpdateProjectIDCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateProjectID", reflect.TypeOf((*MockScriptRepository)(nil).UpdateProjectID), script) - return &ScriptRepositoryUpdateProjectIDCall{Call: call} -} - -// ScriptRepositoryUpdateProjectIDCall wrap *gomock.Call -type ScriptRepositoryUpdateProjectIDCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *ScriptRepositoryUpdateProjectIDCall) Return(arg0 error) *ScriptRepositoryUpdateProjectIDCall { - c.Call = c.Call.Return(arg0) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *ScriptRepositoryUpdateProjectIDCall) Do(f func([]contract.Script) error) *ScriptRepositoryUpdateProjectIDCall { +func (c *ScriptRepositoryStorageCall) Do(f func(context.Context, int64) ([]byte, error)) *ScriptRepositoryStorageCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ScriptRepositoryUpdateProjectIDCall) DoAndReturn(f func([]contract.Script) error) *ScriptRepositoryUpdateProjectIDCall { +func (c *ScriptRepositoryStorageCall) DoAndReturn(f func(context.Context, int64) ([]byte, error)) *ScriptRepositoryStorageCall { c.Call = c.Call.DoAndReturn(f) return c } // Views mocks base method. -func (m *MockScriptRepository) Views(id int64) ([]byte, error) { +func (m *MockScriptRepository) Views(ctx context.Context, id int64) ([]byte, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Views", id) + ret := m.ctrl.Call(m, "Views", ctx, id) ret0, _ := ret[0].([]byte) ret1, _ := ret[1].(error) return ret0, ret1 } // Views indicates an expected call of Views. -func (mr *MockScriptRepositoryMockRecorder) Views(id any) *ScriptRepositoryViewsCall { +func (mr *MockScriptRepositoryMockRecorder) Views(ctx, id any) *ScriptRepositoryViewsCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Views", reflect.TypeOf((*MockScriptRepository)(nil).Views), id) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Views", reflect.TypeOf((*MockScriptRepository)(nil).Views), ctx, id) return &ScriptRepositoryViewsCall{Call: call} } @@ -675,13 +442,13 @@ func (c *ScriptRepositoryViewsCall) Return(arg0 []byte, arg1 error) *ScriptRepos } // Do rewrite *gomock.Call.Do -func (c *ScriptRepositoryViewsCall) Do(f func(int64) ([]byte, error)) *ScriptRepositoryViewsCall { +func (c *ScriptRepositoryViewsCall) Do(f func(context.Context, int64) ([]byte, error)) *ScriptRepositoryViewsCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ScriptRepositoryViewsCall) DoAndReturn(f func(int64) ([]byte, error)) *ScriptRepositoryViewsCall { +func (c *ScriptRepositoryViewsCall) DoAndReturn(f func(context.Context, int64) ([]byte, error)) *ScriptRepositoryViewsCall { c.Call = c.Call.DoAndReturn(f) return c } @@ -710,9 +477,9 @@ func (m *MockConstantRepository) EXPECT() *MockConstantRepositoryMockRecorder { } // All mocks base method. -func (m *MockConstantRepository) All(addresses ...string) ([]contract.GlobalConstant, error) { +func (m *MockConstantRepository) All(ctx context.Context, addresses ...string) ([]contract.GlobalConstant, error) { m.ctrl.T.Helper() - varargs := []any{} + varargs := []any{ctx} for _, a := range addresses { varargs = append(varargs, a) } @@ -723,9 +490,10 @@ func (m *MockConstantRepository) All(addresses ...string) ([]contract.GlobalCons } // All indicates an expected call of All. -func (mr *MockConstantRepositoryMockRecorder) All(addresses ...any) *ConstantRepositoryAllCall { +func (mr *MockConstantRepositoryMockRecorder) All(ctx any, addresses ...any) *ConstantRepositoryAllCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "All", reflect.TypeOf((*MockConstantRepository)(nil).All), addresses...) + varargs := append([]any{ctx}, addresses...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "All", reflect.TypeOf((*MockConstantRepository)(nil).All), varargs...) return &ConstantRepositoryAllCall{Call: call} } @@ -741,30 +509,30 @@ func (c *ConstantRepositoryAllCall) Return(arg0 []contract.GlobalConstant, arg1 } // Do rewrite *gomock.Call.Do -func (c *ConstantRepositoryAllCall) Do(f func(...string) ([]contract.GlobalConstant, error)) *ConstantRepositoryAllCall { +func (c *ConstantRepositoryAllCall) Do(f func(context.Context, ...string) ([]contract.GlobalConstant, error)) *ConstantRepositoryAllCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ConstantRepositoryAllCall) DoAndReturn(f func(...string) ([]contract.GlobalConstant, error)) *ConstantRepositoryAllCall { +func (c *ConstantRepositoryAllCall) DoAndReturn(f func(context.Context, ...string) ([]contract.GlobalConstant, error)) *ConstantRepositoryAllCall { c.Call = c.Call.DoAndReturn(f) return c } // ContractList mocks base method. -func (m *MockConstantRepository) ContractList(address string, size, offset int64) ([]contract.Contract, error) { +func (m *MockConstantRepository) ContractList(ctx context.Context, address string, size, offset int64) ([]contract.Contract, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ContractList", address, size, offset) + ret := m.ctrl.Call(m, "ContractList", ctx, address, size, offset) ret0, _ := ret[0].([]contract.Contract) ret1, _ := ret[1].(error) return ret0, ret1 } // ContractList indicates an expected call of ContractList. -func (mr *MockConstantRepositoryMockRecorder) ContractList(address, size, offset any) *ConstantRepositoryContractListCall { +func (mr *MockConstantRepositoryMockRecorder) ContractList(ctx, address, size, offset any) *ConstantRepositoryContractListCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContractList", reflect.TypeOf((*MockConstantRepository)(nil).ContractList), address, size, offset) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContractList", reflect.TypeOf((*MockConstantRepository)(nil).ContractList), ctx, address, size, offset) return &ConstantRepositoryContractListCall{Call: call} } @@ -780,30 +548,30 @@ func (c *ConstantRepositoryContractListCall) Return(arg0 []contract.Contract, ar } // Do rewrite *gomock.Call.Do -func (c *ConstantRepositoryContractListCall) Do(f func(string, int64, int64) ([]contract.Contract, error)) *ConstantRepositoryContractListCall { +func (c *ConstantRepositoryContractListCall) Do(f func(context.Context, string, int64, int64) ([]contract.Contract, error)) *ConstantRepositoryContractListCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ConstantRepositoryContractListCall) DoAndReturn(f func(string, int64, int64) ([]contract.Contract, error)) *ConstantRepositoryContractListCall { +func (c *ConstantRepositoryContractListCall) DoAndReturn(f func(context.Context, string, int64, int64) ([]contract.Contract, error)) *ConstantRepositoryContractListCall { c.Call = c.Call.DoAndReturn(f) return c } // ForContract mocks base method. -func (m *MockConstantRepository) ForContract(address string, size, offset int64) ([]contract.GlobalConstant, error) { +func (m *MockConstantRepository) ForContract(ctx context.Context, address string, size, offset int64) ([]contract.GlobalConstant, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ForContract", address, size, offset) + ret := m.ctrl.Call(m, "ForContract", ctx, address, size, offset) ret0, _ := ret[0].([]contract.GlobalConstant) ret1, _ := ret[1].(error) return ret0, ret1 } // ForContract indicates an expected call of ForContract. -func (mr *MockConstantRepositoryMockRecorder) ForContract(address, size, offset any) *ConstantRepositoryForContractCall { +func (mr *MockConstantRepositoryMockRecorder) ForContract(ctx, address, size, offset any) *ConstantRepositoryForContractCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForContract", reflect.TypeOf((*MockConstantRepository)(nil).ForContract), address, size, offset) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForContract", reflect.TypeOf((*MockConstantRepository)(nil).ForContract), ctx, address, size, offset) return &ConstantRepositoryForContractCall{Call: call} } @@ -819,30 +587,30 @@ func (c *ConstantRepositoryForContractCall) Return(arg0 []contract.GlobalConstan } // Do rewrite *gomock.Call.Do -func (c *ConstantRepositoryForContractCall) Do(f func(string, int64, int64) ([]contract.GlobalConstant, error)) *ConstantRepositoryForContractCall { +func (c *ConstantRepositoryForContractCall) Do(f func(context.Context, string, int64, int64) ([]contract.GlobalConstant, error)) *ConstantRepositoryForContractCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ConstantRepositoryForContractCall) DoAndReturn(f func(string, int64, int64) ([]contract.GlobalConstant, error)) *ConstantRepositoryForContractCall { +func (c *ConstantRepositoryForContractCall) DoAndReturn(f func(context.Context, string, int64, int64) ([]contract.GlobalConstant, error)) *ConstantRepositoryForContractCall { c.Call = c.Call.DoAndReturn(f) return c } // Get mocks base method. -func (m *MockConstantRepository) Get(address string) (contract.GlobalConstant, error) { +func (m *MockConstantRepository) Get(ctx context.Context, address string) (contract.GlobalConstant, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", address) + ret := m.ctrl.Call(m, "Get", ctx, address) ret0, _ := ret[0].(contract.GlobalConstant) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get. -func (mr *MockConstantRepositoryMockRecorder) Get(address any) *ConstantRepositoryGetCall { +func (mr *MockConstantRepositoryMockRecorder) Get(ctx, address any) *ConstantRepositoryGetCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockConstantRepository)(nil).Get), address) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockConstantRepository)(nil).Get), ctx, address) return &ConstantRepositoryGetCall{Call: call} } @@ -858,30 +626,30 @@ func (c *ConstantRepositoryGetCall) Return(arg0 contract.GlobalConstant, arg1 er } // Do rewrite *gomock.Call.Do -func (c *ConstantRepositoryGetCall) Do(f func(string) (contract.GlobalConstant, error)) *ConstantRepositoryGetCall { +func (c *ConstantRepositoryGetCall) Do(f func(context.Context, string) (contract.GlobalConstant, error)) *ConstantRepositoryGetCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ConstantRepositoryGetCall) DoAndReturn(f func(string) (contract.GlobalConstant, error)) *ConstantRepositoryGetCall { +func (c *ConstantRepositoryGetCall) DoAndReturn(f func(context.Context, string) (contract.GlobalConstant, error)) *ConstantRepositoryGetCall { c.Call = c.Call.DoAndReturn(f) return c } // List mocks base method. -func (m *MockConstantRepository) List(size, offset int64, orderBy, sort string) ([]contract.ListGlobalConstantItem, error) { +func (m *MockConstantRepository) List(ctx context.Context, size, offset int64, orderBy, sort string) ([]contract.ListGlobalConstantItem, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "List", size, offset, orderBy, sort) + ret := m.ctrl.Call(m, "List", ctx, size, offset, orderBy, sort) ret0, _ := ret[0].([]contract.ListGlobalConstantItem) ret1, _ := ret[1].(error) return ret0, ret1 } // List indicates an expected call of List. -func (mr *MockConstantRepositoryMockRecorder) List(size, offset, orderBy, sort any) *ConstantRepositoryListCall { +func (mr *MockConstantRepositoryMockRecorder) List(ctx, size, offset, orderBy, sort any) *ConstantRepositoryListCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockConstantRepository)(nil).List), size, offset, orderBy, sort) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockConstantRepository)(nil).List), ctx, size, offset, orderBy, sort) return &ConstantRepositoryListCall{Call: call} } @@ -897,13 +665,13 @@ func (c *ConstantRepositoryListCall) Return(arg0 []contract.ListGlobalConstantIt } // Do rewrite *gomock.Call.Do -func (c *ConstantRepositoryListCall) Do(f func(int64, int64, string, string) ([]contract.ListGlobalConstantItem, error)) *ConstantRepositoryListCall { +func (c *ConstantRepositoryListCall) Do(f func(context.Context, int64, int64, string, string) ([]contract.ListGlobalConstantItem, error)) *ConstantRepositoryListCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *ConstantRepositoryListCall) DoAndReturn(f func(int64, int64, string, string) ([]contract.ListGlobalConstantItem, error)) *ConstantRepositoryListCall { +func (c *ConstantRepositoryListCall) DoAndReturn(f func(context.Context, int64, int64, string, string) ([]contract.ListGlobalConstantItem, error)) *ConstantRepositoryListCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/internal/models/mock/domains/mock.go b/internal/models/mock/domains/mock.go index fcaadfaf2..854b1a20a 100644 --- a/internal/models/mock/domains/mock.go +++ b/internal/models/mock/domains/mock.go @@ -9,6 +9,7 @@ package domains import ( + context "context" reflect "reflect" contract "github.com/baking-bad/bcdhub/internal/models/contract" @@ -39,49 +40,10 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { return m.recorder } -// BigMapDiffs mocks base method. -func (m *MockRepository) BigMapDiffs(lastID, size int64) ([]domains.BigMapDiff, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BigMapDiffs", lastID, size) - ret0, _ := ret[0].([]domains.BigMapDiff) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// BigMapDiffs indicates an expected call of BigMapDiffs. -func (mr *MockRepositoryMockRecorder) BigMapDiffs(lastID, size any) *RepositoryBigMapDiffsCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BigMapDiffs", reflect.TypeOf((*MockRepository)(nil).BigMapDiffs), lastID, size) - return &RepositoryBigMapDiffsCall{Call: call} -} - -// RepositoryBigMapDiffsCall wrap *gomock.Call -type RepositoryBigMapDiffsCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryBigMapDiffsCall) Return(arg0 []domains.BigMapDiff, arg1 error) *RepositoryBigMapDiffsCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryBigMapDiffsCall) Do(f func(int64, int64) ([]domains.BigMapDiff, error)) *RepositoryBigMapDiffsCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryBigMapDiffsCall) DoAndReturn(f func(int64, int64) ([]domains.BigMapDiff, error)) *RepositoryBigMapDiffsCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - // Same mocks base method. -func (m *MockRepository) Same(network string, c contract.Contract, limit, offset int, availiableNetworks ...string) ([]domains.Same, error) { +func (m *MockRepository) Same(ctx context.Context, network string, c contract.Contract, limit, offset int, availiableNetworks ...string) ([]domains.Same, error) { m.ctrl.T.Helper() - varargs := []any{network, c, limit, offset} + varargs := []any{ctx, network, c, limit, offset} for _, a := range availiableNetworks { varargs = append(varargs, a) } @@ -92,9 +54,9 @@ func (m *MockRepository) Same(network string, c contract.Contract, limit, offset } // Same indicates an expected call of Same. -func (mr *MockRepositoryMockRecorder) Same(network, c, limit, offset any, availiableNetworks ...any) *RepositorySameCall { +func (mr *MockRepositoryMockRecorder) Same(ctx, network, c, limit, offset any, availiableNetworks ...any) *RepositorySameCall { mr.mock.ctrl.T.Helper() - varargs := append([]any{network, c, limit, offset}, availiableNetworks...) + varargs := append([]any{ctx, network, c, limit, offset}, availiableNetworks...) call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Same", reflect.TypeOf((*MockRepository)(nil).Same), varargs...) return &RepositorySameCall{Call: call} } @@ -111,21 +73,21 @@ func (c_2 *RepositorySameCall) Return(arg0 []domains.Same, arg1 error) *Reposito } // Do rewrite *gomock.Call.Do -func (c_2 *RepositorySameCall) Do(f func(string, contract.Contract, int, int, ...string) ([]domains.Same, error)) *RepositorySameCall { +func (c_2 *RepositorySameCall) Do(f func(context.Context, string, contract.Contract, int, int, ...string) ([]domains.Same, error)) *RepositorySameCall { c_2.Call = c_2.Call.Do(f) return c_2 } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c_2 *RepositorySameCall) DoAndReturn(f func(string, contract.Contract, int, int, ...string) ([]domains.Same, error)) *RepositorySameCall { +func (c_2 *RepositorySameCall) DoAndReturn(f func(context.Context, string, contract.Contract, int, int, ...string) ([]domains.Same, error)) *RepositorySameCall { c_2.Call = c_2.Call.DoAndReturn(f) return c_2 } // SameCount mocks base method. -func (m *MockRepository) SameCount(c contract.Contract, availiableNetworks ...string) (int, error) { +func (m *MockRepository) SameCount(ctx context.Context, c contract.Contract, availiableNetworks ...string) (int, error) { m.ctrl.T.Helper() - varargs := []any{c} + varargs := []any{ctx, c} for _, a := range availiableNetworks { varargs = append(varargs, a) } @@ -136,9 +98,9 @@ func (m *MockRepository) SameCount(c contract.Contract, availiableNetworks ...st } // SameCount indicates an expected call of SameCount. -func (mr *MockRepositoryMockRecorder) SameCount(c any, availiableNetworks ...any) *RepositorySameCountCall { +func (mr *MockRepositoryMockRecorder) SameCount(ctx, c any, availiableNetworks ...any) *RepositorySameCountCall { mr.mock.ctrl.T.Helper() - varargs := append([]any{c}, availiableNetworks...) + varargs := append([]any{ctx, c}, availiableNetworks...) call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SameCount", reflect.TypeOf((*MockRepository)(nil).SameCount), varargs...) return &RepositorySameCountCall{Call: call} } @@ -155,13 +117,13 @@ func (c_2 *RepositorySameCountCall) Return(arg0 int, arg1 error) *RepositorySame } // Do rewrite *gomock.Call.Do -func (c_2 *RepositorySameCountCall) Do(f func(contract.Contract, ...string) (int, error)) *RepositorySameCountCall { +func (c_2 *RepositorySameCountCall) Do(f func(context.Context, contract.Contract, ...string) (int, error)) *RepositorySameCountCall { c_2.Call = c_2.Call.Do(f) return c_2 } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c_2 *RepositorySameCountCall) DoAndReturn(f func(contract.Contract, ...string) (int, error)) *RepositorySameCountCall { +func (c_2 *RepositorySameCountCall) DoAndReturn(f func(context.Context, contract.Contract, ...string) (int, error)) *RepositorySameCountCall { c_2.Call = c_2.Call.DoAndReturn(f) return c_2 } diff --git a/internal/models/mock/general.go b/internal/models/mock/general.go index 3b21f9d32..81d4efe5c 100644 --- a/internal/models/mock/general.go +++ b/internal/models/mock/general.go @@ -12,7 +12,17 @@ import ( context "context" reflect "reflect" - models "github.com/baking-bad/bcdhub/internal/models" + account "github.com/baking-bad/bcdhub/internal/models/account" + bigmapaction "github.com/baking-bad/bcdhub/internal/models/bigmapaction" + bigmapdiff "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + block "github.com/baking-bad/bcdhub/internal/models/block" + contract "github.com/baking-bad/bcdhub/internal/models/contract" + migration "github.com/baking-bad/bcdhub/internal/models/migration" + operation "github.com/baking-bad/bcdhub/internal/models/operation" + protocol "github.com/baking-bad/bcdhub/internal/models/protocol" + smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" + stats "github.com/baking-bad/bcdhub/internal/models/stats" + ticket "github.com/baking-bad/bcdhub/internal/models/ticket" gomock "go.uber.org/mock/gomock" ) @@ -39,383 +49,1313 @@ func (m *MockGeneralRepository) EXPECT() *MockGeneralRepositoryMockRecorder { return m.recorder } -// BulkDelete mocks base method. -func (m *MockGeneralRepository) BulkDelete(arg0 context.Context, arg1 []models.Model) error { +// CreateIndex mocks base method. +func (m *MockGeneralRepository) CreateIndex(ctx context.Context, name, columns string, model any) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "BulkDelete", arg0, arg1) + ret := m.ctrl.Call(m, "CreateIndex", ctx, name, columns, model) ret0, _ := ret[0].(error) return ret0 } -// BulkDelete indicates an expected call of BulkDelete. -func (mr *MockGeneralRepositoryMockRecorder) BulkDelete(arg0, arg1 any) *GeneralRepositoryBulkDeleteCall { +// CreateIndex indicates an expected call of CreateIndex. +func (mr *MockGeneralRepositoryMockRecorder) CreateIndex(ctx, name, columns, model any) *GeneralRepositoryCreateIndexCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BulkDelete", reflect.TypeOf((*MockGeneralRepository)(nil).BulkDelete), arg0, arg1) - return &GeneralRepositoryBulkDeleteCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateIndex", reflect.TypeOf((*MockGeneralRepository)(nil).CreateIndex), ctx, name, columns, model) + return &GeneralRepositoryCreateIndexCall{Call: call} } -// GeneralRepositoryBulkDeleteCall wrap *gomock.Call -type GeneralRepositoryBulkDeleteCall struct { +// GeneralRepositoryCreateIndexCall wrap *gomock.Call +type GeneralRepositoryCreateIndexCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *GeneralRepositoryBulkDeleteCall) Return(arg0 error) *GeneralRepositoryBulkDeleteCall { +func (c *GeneralRepositoryCreateIndexCall) Return(arg0 error) *GeneralRepositoryCreateIndexCall { c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *GeneralRepositoryBulkDeleteCall) Do(f func(context.Context, []models.Model) error) *GeneralRepositoryBulkDeleteCall { +func (c *GeneralRepositoryCreateIndexCall) Do(f func(context.Context, string, string, any) error) *GeneralRepositoryCreateIndexCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *GeneralRepositoryBulkDeleteCall) DoAndReturn(f func(context.Context, []models.Model) error) *GeneralRepositoryBulkDeleteCall { +func (c *GeneralRepositoryCreateIndexCall) DoAndReturn(f func(context.Context, string, string, any) error) *GeneralRepositoryCreateIndexCall { c.Call = c.Call.DoAndReturn(f) return c } -// CreateTables mocks base method. -func (m *MockGeneralRepository) CreateTables() error { +// Drop mocks base method. +func (m *MockGeneralRepository) Drop(ctx context.Context) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "CreateTables") + ret := m.ctrl.Call(m, "Drop", ctx) ret0, _ := ret[0].(error) return ret0 } -// CreateTables indicates an expected call of CreateTables. -func (mr *MockGeneralRepositoryMockRecorder) CreateTables() *GeneralRepositoryCreateTablesCall { +// Drop indicates an expected call of Drop. +func (mr *MockGeneralRepositoryMockRecorder) Drop(ctx any) *GeneralRepositoryDropCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateTables", reflect.TypeOf((*MockGeneralRepository)(nil).CreateTables)) - return &GeneralRepositoryCreateTablesCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Drop", reflect.TypeOf((*MockGeneralRepository)(nil).Drop), ctx) + return &GeneralRepositoryDropCall{Call: call} } -// GeneralRepositoryCreateTablesCall wrap *gomock.Call -type GeneralRepositoryCreateTablesCall struct { +// GeneralRepositoryDropCall wrap *gomock.Call +type GeneralRepositoryDropCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *GeneralRepositoryCreateTablesCall) Return(arg0 error) *GeneralRepositoryCreateTablesCall { +func (c *GeneralRepositoryDropCall) Return(arg0 error) *GeneralRepositoryDropCall { c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *GeneralRepositoryCreateTablesCall) Do(f func() error) *GeneralRepositoryCreateTablesCall { +func (c *GeneralRepositoryDropCall) Do(f func(context.Context) error) *GeneralRepositoryDropCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *GeneralRepositoryCreateTablesCall) DoAndReturn(f func() error) *GeneralRepositoryCreateTablesCall { +func (c *GeneralRepositoryDropCall) DoAndReturn(f func(context.Context) error) *GeneralRepositoryDropCall { c.Call = c.Call.DoAndReturn(f) return c } -// DeleteByContract mocks base method. -func (m *MockGeneralRepository) DeleteByContract(indices []string, address string) error { +// InitDatabase mocks base method. +func (m *MockGeneralRepository) InitDatabase(ctx context.Context) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteByContract", indices, address) + ret := m.ctrl.Call(m, "InitDatabase", ctx) ret0, _ := ret[0].(error) return ret0 } -// DeleteByContract indicates an expected call of DeleteByContract. -func (mr *MockGeneralRepositoryMockRecorder) DeleteByContract(indices, address any) *GeneralRepositoryDeleteByContractCall { +// InitDatabase indicates an expected call of InitDatabase. +func (mr *MockGeneralRepositoryMockRecorder) InitDatabase(ctx any) *GeneralRepositoryInitDatabaseCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteByContract", reflect.TypeOf((*MockGeneralRepository)(nil).DeleteByContract), indices, address) - return &GeneralRepositoryDeleteByContractCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "InitDatabase", reflect.TypeOf((*MockGeneralRepository)(nil).InitDatabase), ctx) + return &GeneralRepositoryInitDatabaseCall{Call: call} } -// GeneralRepositoryDeleteByContractCall wrap *gomock.Call -type GeneralRepositoryDeleteByContractCall struct { +// GeneralRepositoryInitDatabaseCall wrap *gomock.Call +type GeneralRepositoryInitDatabaseCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *GeneralRepositoryDeleteByContractCall) Return(arg0 error) *GeneralRepositoryDeleteByContractCall { +func (c *GeneralRepositoryInitDatabaseCall) Return(arg0 error) *GeneralRepositoryInitDatabaseCall { c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *GeneralRepositoryDeleteByContractCall) Do(f func([]string, string) error) *GeneralRepositoryDeleteByContractCall { +func (c *GeneralRepositoryInitDatabaseCall) Do(f func(context.Context) error) *GeneralRepositoryInitDatabaseCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *GeneralRepositoryDeleteByContractCall) DoAndReturn(f func([]string, string) error) *GeneralRepositoryDeleteByContractCall { +func (c *GeneralRepositoryInitDatabaseCall) DoAndReturn(f func(context.Context) error) *GeneralRepositoryInitDatabaseCall { c.Call = c.Call.DoAndReturn(f) return c } -// Drop mocks base method. -func (m *MockGeneralRepository) Drop(ctx context.Context) error { +// IsRecordNotFound mocks base method. +func (m *MockGeneralRepository) IsRecordNotFound(err error) bool { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Drop", ctx) + ret := m.ctrl.Call(m, "IsRecordNotFound", err) + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsRecordNotFound indicates an expected call of IsRecordNotFound. +func (mr *MockGeneralRepositoryMockRecorder) IsRecordNotFound(err any) *GeneralRepositoryIsRecordNotFoundCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsRecordNotFound", reflect.TypeOf((*MockGeneralRepository)(nil).IsRecordNotFound), err) + return &GeneralRepositoryIsRecordNotFoundCall{Call: call} +} + +// GeneralRepositoryIsRecordNotFoundCall wrap *gomock.Call +type GeneralRepositoryIsRecordNotFoundCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *GeneralRepositoryIsRecordNotFoundCall) Return(arg0 bool) *GeneralRepositoryIsRecordNotFoundCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *GeneralRepositoryIsRecordNotFoundCall) Do(f func(error) bool) *GeneralRepositoryIsRecordNotFoundCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *GeneralRepositoryIsRecordNotFoundCall) DoAndReturn(f func(error) bool) *GeneralRepositoryIsRecordNotFoundCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// TablesExist mocks base method. +func (m *MockGeneralRepository) TablesExist(ctx context.Context) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TablesExist", ctx) + ret0, _ := ret[0].(bool) + return ret0 +} + +// TablesExist indicates an expected call of TablesExist. +func (mr *MockGeneralRepositoryMockRecorder) TablesExist(ctx any) *GeneralRepositoryTablesExistCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TablesExist", reflect.TypeOf((*MockGeneralRepository)(nil).TablesExist), ctx) + return &GeneralRepositoryTablesExistCall{Call: call} +} + +// GeneralRepositoryTablesExistCall wrap *gomock.Call +type GeneralRepositoryTablesExistCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *GeneralRepositoryTablesExistCall) Return(arg0 bool) *GeneralRepositoryTablesExistCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *GeneralRepositoryTablesExistCall) Do(f func(context.Context) bool) *GeneralRepositoryTablesExistCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *GeneralRepositoryTablesExistCall) DoAndReturn(f func(context.Context) bool) *GeneralRepositoryTablesExistCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// MockTransaction is a mock of Transaction interface. +type MockTransaction struct { + ctrl *gomock.Controller + recorder *MockTransactionMockRecorder +} + +// MockTransactionMockRecorder is the mock recorder for MockTransaction. +type MockTransactionMockRecorder struct { + mock *MockTransaction +} + +// NewMockTransaction creates a new mock instance. +func NewMockTransaction(ctrl *gomock.Controller) *MockTransaction { + mock := &MockTransaction{ctrl: ctrl} + mock.recorder = &MockTransactionMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockTransaction) EXPECT() *MockTransactionMockRecorder { + return m.recorder +} + +// Accounts mocks base method. +func (m *MockTransaction) Accounts(ctx context.Context, accounts ...*account.Account) error { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range accounts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Accounts", varargs...) ret0, _ := ret[0].(error) return ret0 } -// Drop indicates an expected call of Drop. -func (mr *MockGeneralRepositoryMockRecorder) Drop(ctx any) *GeneralRepositoryDropCall { +// Accounts indicates an expected call of Accounts. +func (mr *MockTransactionMockRecorder) Accounts(ctx any, accounts ...any) *TransactionAccountsCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Drop", reflect.TypeOf((*MockGeneralRepository)(nil).Drop), ctx) - return &GeneralRepositoryDropCall{Call: call} + varargs := append([]any{ctx}, accounts...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Accounts", reflect.TypeOf((*MockTransaction)(nil).Accounts), varargs...) + return &TransactionAccountsCall{Call: call} } -// GeneralRepositoryDropCall wrap *gomock.Call -type GeneralRepositoryDropCall struct { +// TransactionAccountsCall wrap *gomock.Call +type TransactionAccountsCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *GeneralRepositoryDropCall) Return(arg0 error) *GeneralRepositoryDropCall { +func (c *TransactionAccountsCall) Return(arg0 error) *TransactionAccountsCall { c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *GeneralRepositoryDropCall) Do(f func(context.Context) error) *GeneralRepositoryDropCall { +func (c *TransactionAccountsCall) Do(f func(context.Context, ...*account.Account) error) *TransactionAccountsCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *GeneralRepositoryDropCall) DoAndReturn(f func(context.Context) error) *GeneralRepositoryDropCall { +func (c *TransactionAccountsCall) DoAndReturn(f func(context.Context, ...*account.Account) error) *TransactionAccountsCall { c.Call = c.Call.DoAndReturn(f) return c } -// GetAll mocks base method. -func (m *MockGeneralRepository) GetAll(index string) ([]models.Model, error) { +// BabylonUpdateBigMapDiffs mocks base method. +func (m *MockTransaction) BabylonUpdateBigMapDiffs(ctx context.Context, contract string, ptr int64) (int, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAll", index) - ret0, _ := ret[0].([]models.Model) + ret := m.ctrl.Call(m, "BabylonUpdateBigMapDiffs", ctx, contract, ptr) + ret0, _ := ret[0].(int) ret1, _ := ret[1].(error) return ret0, ret1 } -// GetAll indicates an expected call of GetAll. -func (mr *MockGeneralRepositoryMockRecorder) GetAll(index any) *GeneralRepositoryGetAllCall { +// BabylonUpdateBigMapDiffs indicates an expected call of BabylonUpdateBigMapDiffs. +func (mr *MockTransactionMockRecorder) BabylonUpdateBigMapDiffs(ctx, contract, ptr any) *TransactionBabylonUpdateBigMapDiffsCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAll", reflect.TypeOf((*MockGeneralRepository)(nil).GetAll), index) - return &GeneralRepositoryGetAllCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BabylonUpdateBigMapDiffs", reflect.TypeOf((*MockTransaction)(nil).BabylonUpdateBigMapDiffs), ctx, contract, ptr) + return &TransactionBabylonUpdateBigMapDiffsCall{Call: call} } -// GeneralRepositoryGetAllCall wrap *gomock.Call -type GeneralRepositoryGetAllCall struct { +// TransactionBabylonUpdateBigMapDiffsCall wrap *gomock.Call +type TransactionBabylonUpdateBigMapDiffsCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *GeneralRepositoryGetAllCall) Return(arg0 []models.Model, arg1 error) *GeneralRepositoryGetAllCall { +func (c *TransactionBabylonUpdateBigMapDiffsCall) Return(arg0 int, arg1 error) *TransactionBabylonUpdateBigMapDiffsCall { c.Call = c.Call.Return(arg0, arg1) return c } // Do rewrite *gomock.Call.Do -func (c *GeneralRepositoryGetAllCall) Do(f func(string) ([]models.Model, error)) *GeneralRepositoryGetAllCall { +func (c *TransactionBabylonUpdateBigMapDiffsCall) Do(f func(context.Context, string, int64) (int, error)) *TransactionBabylonUpdateBigMapDiffsCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *GeneralRepositoryGetAllCall) DoAndReturn(f func(string) ([]models.Model, error)) *GeneralRepositoryGetAllCall { +func (c *TransactionBabylonUpdateBigMapDiffsCall) DoAndReturn(f func(context.Context, string, int64) (int, error)) *TransactionBabylonUpdateBigMapDiffsCall { c.Call = c.Call.DoAndReturn(f) return c } -// GetByID mocks base method. -func (m *MockGeneralRepository) GetByID(output models.Model) error { +// BabylonUpdateNonDelegator mocks base method. +func (m *MockTransaction) BabylonUpdateNonDelegator(ctx context.Context, contract *contract.Contract) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByID", output) + ret := m.ctrl.Call(m, "BabylonUpdateNonDelegator", ctx, contract) ret0, _ := ret[0].(error) return ret0 } -// GetByID indicates an expected call of GetByID. -func (mr *MockGeneralRepositoryMockRecorder) GetByID(output any) *GeneralRepositoryGetByIDCall { +// BabylonUpdateNonDelegator indicates an expected call of BabylonUpdateNonDelegator. +func (mr *MockTransactionMockRecorder) BabylonUpdateNonDelegator(ctx, contract any) *TransactionBabylonUpdateNonDelegatorCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByID", reflect.TypeOf((*MockGeneralRepository)(nil).GetByID), output) - return &GeneralRepositoryGetByIDCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BabylonUpdateNonDelegator", reflect.TypeOf((*MockTransaction)(nil).BabylonUpdateNonDelegator), ctx, contract) + return &TransactionBabylonUpdateNonDelegatorCall{Call: call} } -// GeneralRepositoryGetByIDCall wrap *gomock.Call -type GeneralRepositoryGetByIDCall struct { +// TransactionBabylonUpdateNonDelegatorCall wrap *gomock.Call +type TransactionBabylonUpdateNonDelegatorCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *GeneralRepositoryGetByIDCall) Return(arg0 error) *GeneralRepositoryGetByIDCall { +func (c *TransactionBabylonUpdateNonDelegatorCall) Return(arg0 error) *TransactionBabylonUpdateNonDelegatorCall { c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *GeneralRepositoryGetByIDCall) Do(f func(models.Model) error) *GeneralRepositoryGetByIDCall { +func (c *TransactionBabylonUpdateNonDelegatorCall) Do(f func(context.Context, *contract.Contract) error) *TransactionBabylonUpdateNonDelegatorCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *GeneralRepositoryGetByIDCall) DoAndReturn(f func(models.Model) error) *GeneralRepositoryGetByIDCall { +func (c *TransactionBabylonUpdateNonDelegatorCall) DoAndReturn(f func(context.Context, *contract.Contract) error) *TransactionBabylonUpdateNonDelegatorCall { c.Call = c.Call.DoAndReturn(f) return c } -// IsRecordNotFound mocks base method. -func (m *MockGeneralRepository) IsRecordNotFound(err error) bool { +// BigMapActions mocks base method. +func (m *MockTransaction) BigMapActions(ctx context.Context, bigmapdiffs ...*bigmapaction.BigMapAction) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "IsRecordNotFound", err) - ret0, _ := ret[0].(bool) + varargs := []any{ctx} + for _, a := range bigmapdiffs { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "BigMapActions", varargs...) + ret0, _ := ret[0].(error) return ret0 } -// IsRecordNotFound indicates an expected call of IsRecordNotFound. -func (mr *MockGeneralRepositoryMockRecorder) IsRecordNotFound(err any) *GeneralRepositoryIsRecordNotFoundCall { +// BigMapActions indicates an expected call of BigMapActions. +func (mr *MockTransactionMockRecorder) BigMapActions(ctx any, bigmapdiffs ...any) *TransactionBigMapActionsCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsRecordNotFound", reflect.TypeOf((*MockGeneralRepository)(nil).IsRecordNotFound), err) - return &GeneralRepositoryIsRecordNotFoundCall{Call: call} + varargs := append([]any{ctx}, bigmapdiffs...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BigMapActions", reflect.TypeOf((*MockTransaction)(nil).BigMapActions), varargs...) + return &TransactionBigMapActionsCall{Call: call} } -// GeneralRepositoryIsRecordNotFoundCall wrap *gomock.Call -type GeneralRepositoryIsRecordNotFoundCall struct { +// TransactionBigMapActionsCall wrap *gomock.Call +type TransactionBigMapActionsCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *GeneralRepositoryIsRecordNotFoundCall) Return(arg0 bool) *GeneralRepositoryIsRecordNotFoundCall { +func (c *TransactionBigMapActionsCall) Return(arg0 error) *TransactionBigMapActionsCall { c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *GeneralRepositoryIsRecordNotFoundCall) Do(f func(error) bool) *GeneralRepositoryIsRecordNotFoundCall { +func (c *TransactionBigMapActionsCall) Do(f func(context.Context, ...*bigmapaction.BigMapAction) error) *TransactionBigMapActionsCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *GeneralRepositoryIsRecordNotFoundCall) DoAndReturn(f func(error) bool) *GeneralRepositoryIsRecordNotFoundCall { +func (c *TransactionBigMapActionsCall) DoAndReturn(f func(context.Context, ...*bigmapaction.BigMapAction) error) *TransactionBigMapActionsCall { c.Call = c.Call.DoAndReturn(f) return c } -// Save mocks base method. -func (m *MockGeneralRepository) Save(ctx context.Context, items []models.Model) error { +// BigMapDiffs mocks base method. +func (m *MockTransaction) BigMapDiffs(ctx context.Context, bigmapdiffs ...*bigmapdiff.BigMapDiff) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Save", ctx, items) + varargs := []any{ctx} + for _, a := range bigmapdiffs { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "BigMapDiffs", varargs...) ret0, _ := ret[0].(error) return ret0 } -// Save indicates an expected call of Save. -func (mr *MockGeneralRepositoryMockRecorder) Save(ctx, items any) *GeneralRepositorySaveCall { +// BigMapDiffs indicates an expected call of BigMapDiffs. +func (mr *MockTransactionMockRecorder) BigMapDiffs(ctx any, bigmapdiffs ...any) *TransactionBigMapDiffsCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Save", reflect.TypeOf((*MockGeneralRepository)(nil).Save), ctx, items) - return &GeneralRepositorySaveCall{Call: call} + varargs := append([]any{ctx}, bigmapdiffs...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BigMapDiffs", reflect.TypeOf((*MockTransaction)(nil).BigMapDiffs), varargs...) + return &TransactionBigMapDiffsCall{Call: call} } -// GeneralRepositorySaveCall wrap *gomock.Call -type GeneralRepositorySaveCall struct { +// TransactionBigMapDiffsCall wrap *gomock.Call +type TransactionBigMapDiffsCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *GeneralRepositorySaveCall) Return(arg0 error) *GeneralRepositorySaveCall { +func (c *TransactionBigMapDiffsCall) Return(arg0 error) *TransactionBigMapDiffsCall { c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *GeneralRepositorySaveCall) Do(f func(context.Context, []models.Model) error) *GeneralRepositorySaveCall { +func (c *TransactionBigMapDiffsCall) Do(f func(context.Context, ...*bigmapdiff.BigMapDiff) error) *TransactionBigMapDiffsCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *GeneralRepositorySaveCall) DoAndReturn(f func(context.Context, []models.Model) error) *GeneralRepositorySaveCall { +func (c *TransactionBigMapDiffsCall) DoAndReturn(f func(context.Context, ...*bigmapdiff.BigMapDiff) error) *TransactionBigMapDiffsCall { c.Call = c.Call.DoAndReturn(f) return c } -// TablesExist mocks base method. -func (m *MockGeneralRepository) TablesExist() bool { +// BigMapStates mocks base method. +func (m *MockTransaction) BigMapStates(ctx context.Context, states ...*bigmapdiff.BigMapState) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "TablesExist") - ret0, _ := ret[0].(bool) + varargs := []any{ctx} + for _, a := range states { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "BigMapStates", varargs...) + ret0, _ := ret[0].(error) return ret0 } -// TablesExist indicates an expected call of TablesExist. -func (mr *MockGeneralRepositoryMockRecorder) TablesExist() *GeneralRepositoryTablesExistCall { +// BigMapStates indicates an expected call of BigMapStates. +func (mr *MockTransactionMockRecorder) BigMapStates(ctx any, states ...any) *TransactionBigMapStatesCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TablesExist", reflect.TypeOf((*MockGeneralRepository)(nil).TablesExist)) - return &GeneralRepositoryTablesExistCall{Call: call} + varargs := append([]any{ctx}, states...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BigMapStates", reflect.TypeOf((*MockTransaction)(nil).BigMapStates), varargs...) + return &TransactionBigMapStatesCall{Call: call} } -// GeneralRepositoryTablesExistCall wrap *gomock.Call -type GeneralRepositoryTablesExistCall struct { +// TransactionBigMapStatesCall wrap *gomock.Call +type TransactionBigMapStatesCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *GeneralRepositoryTablesExistCall) Return(arg0 bool) *GeneralRepositoryTablesExistCall { +func (c *TransactionBigMapStatesCall) Return(arg0 error) *TransactionBigMapStatesCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionBigMapStatesCall) Do(f func(context.Context, ...*bigmapdiff.BigMapState) error) *TransactionBigMapStatesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionBigMapStatesCall) DoAndReturn(f func(context.Context, ...*bigmapdiff.BigMapState) error) *TransactionBigMapStatesCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Block mocks base method. +func (m *MockTransaction) Block(ctx context.Context, block *block.Block) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Block", ctx, block) + ret0, _ := ret[0].(error) + return ret0 +} + +// Block indicates an expected call of Block. +func (mr *MockTransactionMockRecorder) Block(ctx, block any) *TransactionBlockCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Block", reflect.TypeOf((*MockTransaction)(nil).Block), ctx, block) + return &TransactionBlockCall{Call: call} +} + +// TransactionBlockCall wrap *gomock.Call +type TransactionBlockCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionBlockCall) Return(arg0 error) *TransactionBlockCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionBlockCall) Do(f func(context.Context, *block.Block) error) *TransactionBlockCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionBlockCall) DoAndReturn(f func(context.Context, *block.Block) error) *TransactionBlockCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Commit mocks base method. +func (m *MockTransaction) Commit() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Commit") + ret0, _ := ret[0].(error) + return ret0 +} + +// Commit indicates an expected call of Commit. +func (mr *MockTransactionMockRecorder) Commit() *TransactionCommitCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockTransaction)(nil).Commit)) + return &TransactionCommitCall{Call: call} +} + +// TransactionCommitCall wrap *gomock.Call +type TransactionCommitCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionCommitCall) Return(arg0 error) *TransactionCommitCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionCommitCall) Do(f func() error) *TransactionCommitCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionCommitCall) DoAndReturn(f func() error) *TransactionCommitCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Contracts mocks base method. +func (m *MockTransaction) Contracts(ctx context.Context, contracts ...*contract.Contract) error { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range contracts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Contracts", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Contracts indicates an expected call of Contracts. +func (mr *MockTransactionMockRecorder) Contracts(ctx any, contracts ...any) *TransactionContractsCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, contracts...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Contracts", reflect.TypeOf((*MockTransaction)(nil).Contracts), varargs...) + return &TransactionContractsCall{Call: call} +} + +// TransactionContractsCall wrap *gomock.Call +type TransactionContractsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionContractsCall) Return(arg0 error) *TransactionContractsCall { c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *GeneralRepositoryTablesExistCall) Do(f func() bool) *GeneralRepositoryTablesExistCall { +func (c *TransactionContractsCall) Do(f func(context.Context, ...*contract.Contract) error) *TransactionContractsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionContractsCall) DoAndReturn(f func(context.Context, ...*contract.Contract) error) *TransactionContractsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// DeleteBigMapStatesByContract mocks base method. +func (m *MockTransaction) DeleteBigMapStatesByContract(ctx context.Context, contract string) ([]bigmapdiff.BigMapState, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBigMapStatesByContract", ctx, contract) + ret0, _ := ret[0].([]bigmapdiff.BigMapState) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteBigMapStatesByContract indicates an expected call of DeleteBigMapStatesByContract. +func (mr *MockTransactionMockRecorder) DeleteBigMapStatesByContract(ctx, contract any) *TransactionDeleteBigMapStatesByContractCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBigMapStatesByContract", reflect.TypeOf((*MockTransaction)(nil).DeleteBigMapStatesByContract), ctx, contract) + return &TransactionDeleteBigMapStatesByContractCall{Call: call} +} + +// TransactionDeleteBigMapStatesByContractCall wrap *gomock.Call +type TransactionDeleteBigMapStatesByContractCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionDeleteBigMapStatesByContractCall) Return(arg0 []bigmapdiff.BigMapState, arg1 error) *TransactionDeleteBigMapStatesByContractCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionDeleteBigMapStatesByContractCall) Do(f func(context.Context, string) ([]bigmapdiff.BigMapState, error)) *TransactionDeleteBigMapStatesByContractCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *GeneralRepositoryTablesExistCall) DoAndReturn(f func() bool) *GeneralRepositoryTablesExistCall { +func (c *TransactionDeleteBigMapStatesByContractCall) DoAndReturn(f func(context.Context, string) ([]bigmapdiff.BigMapState, error)) *TransactionDeleteBigMapStatesByContractCall { c.Call = c.Call.DoAndReturn(f) return c } -// UpdateDoc mocks base method. -func (m *MockGeneralRepository) UpdateDoc(model models.Model) error { +// GlobalConstants mocks base method. +func (m *MockTransaction) GlobalConstants(ctx context.Context, constants ...*contract.GlobalConstant) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "UpdateDoc", model) + varargs := []any{ctx} + for _, a := range constants { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GlobalConstants", varargs...) ret0, _ := ret[0].(error) return ret0 } -// UpdateDoc indicates an expected call of UpdateDoc. -func (mr *MockGeneralRepositoryMockRecorder) UpdateDoc(model any) *GeneralRepositoryUpdateDocCall { +// GlobalConstants indicates an expected call of GlobalConstants. +func (mr *MockTransactionMockRecorder) GlobalConstants(ctx any, constants ...any) *TransactionGlobalConstantsCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateDoc", reflect.TypeOf((*MockGeneralRepository)(nil).UpdateDoc), model) - return &GeneralRepositoryUpdateDocCall{Call: call} + varargs := append([]any{ctx}, constants...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GlobalConstants", reflect.TypeOf((*MockTransaction)(nil).GlobalConstants), varargs...) + return &TransactionGlobalConstantsCall{Call: call} } -// GeneralRepositoryUpdateDocCall wrap *gomock.Call -type GeneralRepositoryUpdateDocCall struct { +// TransactionGlobalConstantsCall wrap *gomock.Call +type TransactionGlobalConstantsCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *GeneralRepositoryUpdateDocCall) Return(err error) *GeneralRepositoryUpdateDocCall { - c.Call = c.Call.Return(err) +func (c *TransactionGlobalConstantsCall) Return(arg0 error) *TransactionGlobalConstantsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionGlobalConstantsCall) Do(f func(context.Context, ...*contract.GlobalConstant) error) *TransactionGlobalConstantsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionGlobalConstantsCall) DoAndReturn(f func(context.Context, ...*contract.GlobalConstant) error) *TransactionGlobalConstantsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// JakartaUpdateNonDelegator mocks base method. +func (m *MockTransaction) JakartaUpdateNonDelegator(ctx context.Context, contract *contract.Contract) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "JakartaUpdateNonDelegator", ctx, contract) + ret0, _ := ret[0].(error) + return ret0 +} + +// JakartaUpdateNonDelegator indicates an expected call of JakartaUpdateNonDelegator. +func (mr *MockTransactionMockRecorder) JakartaUpdateNonDelegator(ctx, contract any) *TransactionJakartaUpdateNonDelegatorCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "JakartaUpdateNonDelegator", reflect.TypeOf((*MockTransaction)(nil).JakartaUpdateNonDelegator), ctx, contract) + return &TransactionJakartaUpdateNonDelegatorCall{Call: call} +} + +// TransactionJakartaUpdateNonDelegatorCall wrap *gomock.Call +type TransactionJakartaUpdateNonDelegatorCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionJakartaUpdateNonDelegatorCall) Return(arg0 error) *TransactionJakartaUpdateNonDelegatorCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionJakartaUpdateNonDelegatorCall) Do(f func(context.Context, *contract.Contract) error) *TransactionJakartaUpdateNonDelegatorCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionJakartaUpdateNonDelegatorCall) DoAndReturn(f func(context.Context, *contract.Contract) error) *TransactionJakartaUpdateNonDelegatorCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// JakartaVesting mocks base method. +func (m *MockTransaction) JakartaVesting(ctx context.Context, contract *contract.Contract) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "JakartaVesting", ctx, contract) + ret0, _ := ret[0].(error) + return ret0 +} + +// JakartaVesting indicates an expected call of JakartaVesting. +func (mr *MockTransactionMockRecorder) JakartaVesting(ctx, contract any) *TransactionJakartaVestingCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "JakartaVesting", reflect.TypeOf((*MockTransaction)(nil).JakartaVesting), ctx, contract) + return &TransactionJakartaVestingCall{Call: call} +} + +// TransactionJakartaVestingCall wrap *gomock.Call +type TransactionJakartaVestingCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionJakartaVestingCall) Return(arg0 error) *TransactionJakartaVestingCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionJakartaVestingCall) Do(f func(context.Context, *contract.Contract) error) *TransactionJakartaVestingCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionJakartaVestingCall) DoAndReturn(f func(context.Context, *contract.Contract) error) *TransactionJakartaVestingCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Migrations mocks base method. +func (m *MockTransaction) Migrations(ctx context.Context, migrations ...*migration.Migration) error { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range migrations { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Migrations", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Migrations indicates an expected call of Migrations. +func (mr *MockTransactionMockRecorder) Migrations(ctx any, migrations ...any) *TransactionMigrationsCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, migrations...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Migrations", reflect.TypeOf((*MockTransaction)(nil).Migrations), varargs...) + return &TransactionMigrationsCall{Call: call} +} + +// TransactionMigrationsCall wrap *gomock.Call +type TransactionMigrationsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionMigrationsCall) Return(arg0 error) *TransactionMigrationsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionMigrationsCall) Do(f func(context.Context, ...*migration.Migration) error) *TransactionMigrationsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionMigrationsCall) DoAndReturn(f func(context.Context, ...*migration.Migration) error) *TransactionMigrationsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Operations mocks base method. +func (m *MockTransaction) Operations(ctx context.Context, operations ...*operation.Operation) error { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range operations { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Operations", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Operations indicates an expected call of Operations. +func (mr *MockTransactionMockRecorder) Operations(ctx any, operations ...any) *TransactionOperationsCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, operations...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Operations", reflect.TypeOf((*MockTransaction)(nil).Operations), varargs...) + return &TransactionOperationsCall{Call: call} +} + +// TransactionOperationsCall wrap *gomock.Call +type TransactionOperationsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionOperationsCall) Return(arg0 error) *TransactionOperationsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionOperationsCall) Do(f func(context.Context, ...*operation.Operation) error) *TransactionOperationsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionOperationsCall) DoAndReturn(f func(context.Context, ...*operation.Operation) error) *TransactionOperationsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Protocol mocks base method. +func (m *MockTransaction) Protocol(ctx context.Context, proto *protocol.Protocol) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Protocol", ctx, proto) + ret0, _ := ret[0].(error) + return ret0 +} + +// Protocol indicates an expected call of Protocol. +func (mr *MockTransactionMockRecorder) Protocol(ctx, proto any) *TransactionProtocolCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Protocol", reflect.TypeOf((*MockTransaction)(nil).Protocol), ctx, proto) + return &TransactionProtocolCall{Call: call} +} + +// TransactionProtocolCall wrap *gomock.Call +type TransactionProtocolCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionProtocolCall) Return(arg0 error) *TransactionProtocolCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionProtocolCall) Do(f func(context.Context, *protocol.Protocol) error) *TransactionProtocolCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionProtocolCall) DoAndReturn(f func(context.Context, *protocol.Protocol) error) *TransactionProtocolCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Rollback mocks base method. +func (m *MockTransaction) Rollback() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Rollback") + ret0, _ := ret[0].(error) + return ret0 +} + +// Rollback indicates an expected call of Rollback. +func (mr *MockTransactionMockRecorder) Rollback() *TransactionRollbackCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Rollback", reflect.TypeOf((*MockTransaction)(nil).Rollback)) + return &TransactionRollbackCall{Call: call} +} + +// TransactionRollbackCall wrap *gomock.Call +type TransactionRollbackCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionRollbackCall) Return(arg0 error) *TransactionRollbackCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionRollbackCall) Do(f func() error) *TransactionRollbackCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionRollbackCall) DoAndReturn(f func() error) *TransactionRollbackCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Save mocks base method. +func (m *MockTransaction) Save(ctx context.Context, data any) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Save", ctx, data) + ret0, _ := ret[0].(error) + return ret0 +} + +// Save indicates an expected call of Save. +func (mr *MockTransactionMockRecorder) Save(ctx, data any) *TransactionSaveCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Save", reflect.TypeOf((*MockTransaction)(nil).Save), ctx, data) + return &TransactionSaveCall{Call: call} +} + +// TransactionSaveCall wrap *gomock.Call +type TransactionSaveCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionSaveCall) Return(arg0 error) *TransactionSaveCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionSaveCall) Do(f func(context.Context, any) error) *TransactionSaveCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionSaveCall) DoAndReturn(f func(context.Context, any) error) *TransactionSaveCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// ScriptConstant mocks base method. +func (m *MockTransaction) ScriptConstant(ctx context.Context, data ...*contract.ScriptConstants) error { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range data { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "ScriptConstant", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// ScriptConstant indicates an expected call of ScriptConstant. +func (mr *MockTransactionMockRecorder) ScriptConstant(ctx any, data ...any) *TransactionScriptConstantCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, data...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ScriptConstant", reflect.TypeOf((*MockTransaction)(nil).ScriptConstant), varargs...) + return &TransactionScriptConstantCall{Call: call} +} + +// TransactionScriptConstantCall wrap *gomock.Call +type TransactionScriptConstantCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionScriptConstantCall) Return(arg0 error) *TransactionScriptConstantCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionScriptConstantCall) Do(f func(context.Context, ...*contract.ScriptConstants) error) *TransactionScriptConstantCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionScriptConstantCall) DoAndReturn(f func(context.Context, ...*contract.ScriptConstants) error) *TransactionScriptConstantCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Scripts mocks base method. +func (m *MockTransaction) Scripts(ctx context.Context, scripts ...*contract.Script) error { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range scripts { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Scripts", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Scripts indicates an expected call of Scripts. +func (mr *MockTransactionMockRecorder) Scripts(ctx any, scripts ...any) *TransactionScriptsCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, scripts...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Scripts", reflect.TypeOf((*MockTransaction)(nil).Scripts), varargs...) + return &TransactionScriptsCall{Call: call} +} + +// TransactionScriptsCall wrap *gomock.Call +type TransactionScriptsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionScriptsCall) Return(arg0 error) *TransactionScriptsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionScriptsCall) Do(f func(context.Context, ...*contract.Script) error) *TransactionScriptsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionScriptsCall) DoAndReturn(f func(context.Context, ...*contract.Script) error) *TransactionScriptsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SmartRollups mocks base method. +func (m *MockTransaction) SmartRollups(ctx context.Context, rollups ...*smartrollup.SmartRollup) error { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range rollups { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "SmartRollups", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// SmartRollups indicates an expected call of SmartRollups. +func (mr *MockTransactionMockRecorder) SmartRollups(ctx any, rollups ...any) *TransactionSmartRollupsCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, rollups...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SmartRollups", reflect.TypeOf((*MockTransaction)(nil).SmartRollups), varargs...) + return &TransactionSmartRollupsCall{Call: call} +} + +// TransactionSmartRollupsCall wrap *gomock.Call +type TransactionSmartRollupsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionSmartRollupsCall) Return(arg0 error) *TransactionSmartRollupsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionSmartRollupsCall) Do(f func(context.Context, ...*smartrollup.SmartRollup) error) *TransactionSmartRollupsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionSmartRollupsCall) DoAndReturn(f func(context.Context, ...*smartrollup.SmartRollup) error) *TransactionSmartRollupsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// TickerUpdates mocks base method. +func (m *MockTransaction) TickerUpdates(ctx context.Context, updates ...*ticket.TicketUpdate) error { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range updates { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "TickerUpdates", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// TickerUpdates indicates an expected call of TickerUpdates. +func (mr *MockTransactionMockRecorder) TickerUpdates(ctx any, updates ...any) *TransactionTickerUpdatesCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, updates...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TickerUpdates", reflect.TypeOf((*MockTransaction)(nil).TickerUpdates), varargs...) + return &TransactionTickerUpdatesCall{Call: call} +} + +// TransactionTickerUpdatesCall wrap *gomock.Call +type TransactionTickerUpdatesCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionTickerUpdatesCall) Return(arg0 error) *TransactionTickerUpdatesCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionTickerUpdatesCall) Do(f func(context.Context, ...*ticket.TicketUpdate) error) *TransactionTickerUpdatesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionTickerUpdatesCall) DoAndReturn(f func(context.Context, ...*ticket.TicketUpdate) error) *TransactionTickerUpdatesCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// TicketBalances mocks base method. +func (m *MockTransaction) TicketBalances(ctx context.Context, balances ...*ticket.Balance) error { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range balances { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "TicketBalances", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// TicketBalances indicates an expected call of TicketBalances. +func (mr *MockTransactionMockRecorder) TicketBalances(ctx any, balances ...any) *TransactionTicketBalancesCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, balances...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TicketBalances", reflect.TypeOf((*MockTransaction)(nil).TicketBalances), varargs...) + return &TransactionTicketBalancesCall{Call: call} +} + +// TransactionTicketBalancesCall wrap *gomock.Call +type TransactionTicketBalancesCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionTicketBalancesCall) Return(arg0 error) *TransactionTicketBalancesCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionTicketBalancesCall) Do(f func(context.Context, ...*ticket.Balance) error) *TransactionTicketBalancesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionTicketBalancesCall) DoAndReturn(f func(context.Context, ...*ticket.Balance) error) *TransactionTicketBalancesCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Tickets mocks base method. +func (m *MockTransaction) Tickets(ctx context.Context, tickets ...*ticket.Ticket) error { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range tickets { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "Tickets", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// Tickets indicates an expected call of Tickets. +func (mr *MockTransactionMockRecorder) Tickets(ctx any, tickets ...any) *TransactionTicketsCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, tickets...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Tickets", reflect.TypeOf((*MockTransaction)(nil).Tickets), varargs...) + return &TransactionTicketsCall{Call: call} +} + +// TransactionTicketsCall wrap *gomock.Call +type TransactionTicketsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionTicketsCall) Return(arg0 error) *TransactionTicketsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionTicketsCall) Do(f func(context.Context, ...*ticket.Ticket) error) *TransactionTicketsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionTicketsCall) DoAndReturn(f func(context.Context, ...*ticket.Ticket) error) *TransactionTicketsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// ToBabylon mocks base method. +func (m *MockTransaction) ToBabylon(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ToBabylon", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// ToBabylon indicates an expected call of ToBabylon. +func (mr *MockTransactionMockRecorder) ToBabylon(ctx any) *TransactionToBabylonCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ToBabylon", reflect.TypeOf((*MockTransaction)(nil).ToBabylon), ctx) + return &TransactionToBabylonCall{Call: call} +} + +// TransactionToBabylonCall wrap *gomock.Call +type TransactionToBabylonCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionToBabylonCall) Return(arg0 error) *TransactionToBabylonCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionToBabylonCall) Do(f func(context.Context) error) *TransactionToBabylonCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionToBabylonCall) DoAndReturn(f func(context.Context) error) *TransactionToBabylonCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// ToJakarta mocks base method. +func (m *MockTransaction) ToJakarta(ctx context.Context) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ToJakarta", ctx) + ret0, _ := ret[0].(error) + return ret0 +} + +// ToJakarta indicates an expected call of ToJakarta. +func (mr *MockTransactionMockRecorder) ToJakarta(ctx any) *TransactionToJakartaCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ToJakarta", reflect.TypeOf((*MockTransaction)(nil).ToJakarta), ctx) + return &TransactionToJakartaCall{Call: call} +} + +// TransactionToJakartaCall wrap *gomock.Call +type TransactionToJakartaCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionToJakartaCall) Return(arg0 error) *TransactionToJakartaCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *TransactionToJakartaCall) Do(f func(context.Context) error) *TransactionToJakartaCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *TransactionToJakartaCall) DoAndReturn(f func(context.Context) error) *TransactionToJakartaCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// UpdateStats mocks base method. +func (m *MockTransaction) UpdateStats(ctx context.Context, stats stats.Stats) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStats", ctx, stats) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateStats indicates an expected call of UpdateStats. +func (mr *MockTransactionMockRecorder) UpdateStats(ctx, stats any) *TransactionUpdateStatsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStats", reflect.TypeOf((*MockTransaction)(nil).UpdateStats), ctx, stats) + return &TransactionUpdateStatsCall{Call: call} +} + +// TransactionUpdateStatsCall wrap *gomock.Call +type TransactionUpdateStatsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *TransactionUpdateStatsCall) Return(arg0 error) *TransactionUpdateStatsCall { + c.Call = c.Call.Return(arg0) return c } // Do rewrite *gomock.Call.Do -func (c *GeneralRepositoryUpdateDocCall) Do(f func(models.Model) error) *GeneralRepositoryUpdateDocCall { +func (c *TransactionUpdateStatsCall) Do(f func(context.Context, stats.Stats) error) *TransactionUpdateStatsCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *GeneralRepositoryUpdateDocCall) DoAndReturn(f func(models.Model) error) *GeneralRepositoryUpdateDocCall { +func (c *TransactionUpdateStatsCall) DoAndReturn(f func(context.Context, stats.Stats) error) *TransactionUpdateStatsCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/internal/models/mock/migration/mock.go b/internal/models/mock/migration/mock.go index db076ccbd..199e9d615 100644 --- a/internal/models/mock/migration/mock.go +++ b/internal/models/mock/migration/mock.go @@ -9,6 +9,7 @@ package migration import ( + context "context" reflect "reflect" migration "github.com/baking-bad/bcdhub/internal/models/migration" @@ -39,18 +40,18 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { } // Get mocks base method. -func (m *MockRepository) Get(contractID int64) ([]migration.Migration, error) { +func (m *MockRepository) Get(ctx context.Context, contractID int64) ([]migration.Migration, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", contractID) + ret := m.ctrl.Call(m, "Get", ctx, contractID) ret0, _ := ret[0].([]migration.Migration) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get. -func (mr *MockRepositoryMockRecorder) Get(contractID any) *RepositoryGetCall { +func (mr *MockRepositoryMockRecorder) Get(ctx, contractID any) *RepositoryGetCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), contractID) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), ctx, contractID) return &RepositoryGetCall{Call: call} } @@ -66,13 +67,13 @@ func (c *RepositoryGetCall) Return(arg0 []migration.Migration, arg1 error) *Repo } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetCall) Do(f func(int64) ([]migration.Migration, error)) *RepositoryGetCall { +func (c *RepositoryGetCall) Do(f func(context.Context, int64) ([]migration.Migration, error)) *RepositoryGetCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetCall) DoAndReturn(f func(int64) ([]migration.Migration, error)) *RepositoryGetCall { +func (c *RepositoryGetCall) DoAndReturn(f func(context.Context, int64) ([]migration.Migration, error)) *RepositoryGetCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/internal/models/mock/model.go b/internal/models/mock/model.go new file mode 100644 index 000000000..46131bc15 --- /dev/null +++ b/internal/models/mock/model.go @@ -0,0 +1,114 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: model.go +// +// Generated by this command: +// +// mockgen -source=model.go -destination=mock/model.go -package=mock -typed +// +// Package mock is a generated GoMock package. +package mock + +import ( + reflect "reflect" + + gomock "go.uber.org/mock/gomock" +) + +// MockModel is a mock of Model interface. +type MockModel struct { + ctrl *gomock.Controller + recorder *MockModelMockRecorder +} + +// MockModelMockRecorder is the mock recorder for MockModel. +type MockModelMockRecorder struct { + mock *MockModel +} + +// NewMockModel creates a new mock instance. +func NewMockModel(ctrl *gomock.Controller) *MockModel { + mock := &MockModel{ctrl: ctrl} + mock.recorder = &MockModelMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockModel) EXPECT() *MockModelMockRecorder { + return m.recorder +} + +// GetID mocks base method. +func (m *MockModel) GetID() int64 { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetID") + ret0, _ := ret[0].(int64) + return ret0 +} + +// GetID indicates an expected call of GetID. +func (mr *MockModelMockRecorder) GetID() *ModelGetIDCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetID", reflect.TypeOf((*MockModel)(nil).GetID)) + return &ModelGetIDCall{Call: call} +} + +// ModelGetIDCall wrap *gomock.Call +type ModelGetIDCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ModelGetIDCall) Return(arg0 int64) *ModelGetIDCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ModelGetIDCall) Do(f func() int64) *ModelGetIDCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ModelGetIDCall) DoAndReturn(f func() int64) *ModelGetIDCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// TableName mocks base method. +func (m *MockModel) TableName() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "TableName") + ret0, _ := ret[0].(string) + return ret0 +} + +// TableName indicates an expected call of TableName. +func (mr *MockModelMockRecorder) TableName() *ModelTableNameCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TableName", reflect.TypeOf((*MockModel)(nil).TableName)) + return &ModelTableNameCall{Call: call} +} + +// ModelTableNameCall wrap *gomock.Call +type ModelTableNameCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *ModelTableNameCall) Return(arg0 string) *ModelTableNameCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *ModelTableNameCall) Do(f func() string) *ModelTableNameCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *ModelTableNameCall) DoAndReturn(f func() string) *ModelTableNameCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/internal/models/mock/operation/mock.go b/internal/models/mock/operation/mock.go index 72ebc59d4..8b86968de 100644 --- a/internal/models/mock/operation/mock.go +++ b/internal/models/mock/operation/mock.go @@ -9,9 +9,9 @@ package operation import ( + context "context" reflect "reflect" - account "github.com/baking-bad/bcdhub/internal/models/account" operation "github.com/baking-bad/bcdhub/internal/models/operation" gomock "go.uber.org/mock/gomock" ) @@ -39,175 +39,19 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { return m.recorder } -// ContractStats mocks base method. -func (m *MockRepository) ContractStats(address string) (operation.ContractStats, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ContractStats", address) - ret0, _ := ret[0].(operation.ContractStats) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// ContractStats indicates an expected call of ContractStats. -func (mr *MockRepositoryMockRecorder) ContractStats(address any) *RepositoryContractStatsCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ContractStats", reflect.TypeOf((*MockRepository)(nil).ContractStats), address) - return &RepositoryContractStatsCall{Call: call} -} - -// RepositoryContractStatsCall wrap *gomock.Call -type RepositoryContractStatsCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryContractStatsCall) Return(arg0 operation.ContractStats, arg1 error) *RepositoryContractStatsCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryContractStatsCall) Do(f func(string) (operation.ContractStats, error)) *RepositoryContractStatsCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryContractStatsCall) DoAndReturn(f func(string) (operation.ContractStats, error)) *RepositoryContractStatsCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// EventsCount mocks base method. -func (m *MockRepository) EventsCount(accountID int64) (int, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "EventsCount", accountID) - ret0, _ := ret[0].(int) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// EventsCount indicates an expected call of EventsCount. -func (mr *MockRepositoryMockRecorder) EventsCount(accountID any) *RepositoryEventsCountCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EventsCount", reflect.TypeOf((*MockRepository)(nil).EventsCount), accountID) - return &RepositoryEventsCountCall{Call: call} -} - -// RepositoryEventsCountCall wrap *gomock.Call -type RepositoryEventsCountCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryEventsCountCall) Return(arg0 int, arg1 error) *RepositoryEventsCountCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryEventsCountCall) Do(f func(int64) (int, error)) *RepositoryEventsCountCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryEventsCountCall) DoAndReturn(f func(int64) (int, error)) *RepositoryEventsCountCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// Get mocks base method. -func (m *MockRepository) Get(filter map[string]any, size int64, sort bool) ([]operation.Operation, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", filter, size, sort) - ret0, _ := ret[0].([]operation.Operation) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// Get indicates an expected call of Get. -func (mr *MockRepositoryMockRecorder) Get(filter, size, sort any) *RepositoryGetCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), filter, size, sort) - return &RepositoryGetCall{Call: call} -} - -// RepositoryGetCall wrap *gomock.Call -type RepositoryGetCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryGetCall) Return(arg0 []operation.Operation, arg1 error) *RepositoryGetCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryGetCall) Do(f func(map[string]any, int64, bool) ([]operation.Operation, error)) *RepositoryGetCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetCall) DoAndReturn(f func(map[string]any, int64, bool) ([]operation.Operation, error)) *RepositoryGetCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// GetByAccount mocks base method. -func (m *MockRepository) GetByAccount(acc account.Account, size uint64, filters map[string]any) (operation.Pageable, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByAccount", acc, size, filters) - ret0, _ := ret[0].(operation.Pageable) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetByAccount indicates an expected call of GetByAccount. -func (mr *MockRepositoryMockRecorder) GetByAccount(acc, size, filters any) *RepositoryGetByAccountCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByAccount", reflect.TypeOf((*MockRepository)(nil).GetByAccount), acc, size, filters) - return &RepositoryGetByAccountCall{Call: call} -} - -// RepositoryGetByAccountCall wrap *gomock.Call -type RepositoryGetByAccountCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryGetByAccountCall) Return(arg0 operation.Pageable, arg1 error) *RepositoryGetByAccountCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryGetByAccountCall) Do(f func(account.Account, uint64, map[string]any) (operation.Pageable, error)) *RepositoryGetByAccountCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetByAccountCall) DoAndReturn(f func(account.Account, uint64, map[string]any) (operation.Pageable, error)) *RepositoryGetByAccountCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - // GetByHash mocks base method. -func (m *MockRepository) GetByHash(hash []byte) ([]operation.Operation, error) { +func (m *MockRepository) GetByHash(ctx context.Context, hash []byte) ([]operation.Operation, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByHash", hash) + ret := m.ctrl.Call(m, "GetByHash", ctx, hash) ret0, _ := ret[0].([]operation.Operation) ret1, _ := ret[1].(error) return ret0, ret1 } // GetByHash indicates an expected call of GetByHash. -func (mr *MockRepositoryMockRecorder) GetByHash(hash any) *RepositoryGetByHashCall { +func (mr *MockRepositoryMockRecorder) GetByHash(ctx, hash any) *RepositoryGetByHashCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByHash", reflect.TypeOf((*MockRepository)(nil).GetByHash), hash) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByHash", reflect.TypeOf((*MockRepository)(nil).GetByHash), ctx, hash) return &RepositoryGetByHashCall{Call: call} } @@ -223,30 +67,30 @@ func (c *RepositoryGetByHashCall) Return(arg0 []operation.Operation, arg1 error) } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetByHashCall) Do(f func([]byte) ([]operation.Operation, error)) *RepositoryGetByHashCall { +func (c *RepositoryGetByHashCall) Do(f func(context.Context, []byte) ([]operation.Operation, error)) *RepositoryGetByHashCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetByHashCall) DoAndReturn(f func([]byte) ([]operation.Operation, error)) *RepositoryGetByHashCall { +func (c *RepositoryGetByHashCall) DoAndReturn(f func(context.Context, []byte) ([]operation.Operation, error)) *RepositoryGetByHashCall { c.Call = c.Call.DoAndReturn(f) return c } // GetByHashAndCounter mocks base method. -func (m *MockRepository) GetByHashAndCounter(hash []byte, counter int64) ([]operation.Operation, error) { +func (m *MockRepository) GetByHashAndCounter(ctx context.Context, hash []byte, counter int64) ([]operation.Operation, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByHashAndCounter", hash, counter) + ret := m.ctrl.Call(m, "GetByHashAndCounter", ctx, hash, counter) ret0, _ := ret[0].([]operation.Operation) ret1, _ := ret[1].(error) return ret0, ret1 } // GetByHashAndCounter indicates an expected call of GetByHashAndCounter. -func (mr *MockRepositoryMockRecorder) GetByHashAndCounter(hash, counter any) *RepositoryGetByHashAndCounterCall { +func (mr *MockRepositoryMockRecorder) GetByHashAndCounter(ctx, hash, counter any) *RepositoryGetByHashAndCounterCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByHashAndCounter", reflect.TypeOf((*MockRepository)(nil).GetByHashAndCounter), hash, counter) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByHashAndCounter", reflect.TypeOf((*MockRepository)(nil).GetByHashAndCounter), ctx, hash, counter) return &RepositoryGetByHashAndCounterCall{Call: call} } @@ -262,30 +106,30 @@ func (c *RepositoryGetByHashAndCounterCall) Return(arg0 []operation.Operation, a } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetByHashAndCounterCall) Do(f func([]byte, int64) ([]operation.Operation, error)) *RepositoryGetByHashAndCounterCall { +func (c *RepositoryGetByHashAndCounterCall) Do(f func(context.Context, []byte, int64) ([]operation.Operation, error)) *RepositoryGetByHashAndCounterCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetByHashAndCounterCall) DoAndReturn(f func([]byte, int64) ([]operation.Operation, error)) *RepositoryGetByHashAndCounterCall { +func (c *RepositoryGetByHashAndCounterCall) DoAndReturn(f func(context.Context, []byte, int64) ([]operation.Operation, error)) *RepositoryGetByHashAndCounterCall { c.Call = c.Call.DoAndReturn(f) return c } // GetByID mocks base method. -func (m *MockRepository) GetByID(id int64) (operation.Operation, error) { +func (m *MockRepository) GetByID(ctx context.Context, id int64) (operation.Operation, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByID", id) + ret := m.ctrl.Call(m, "GetByID", ctx, id) ret0, _ := ret[0].(operation.Operation) ret1, _ := ret[1].(error) return ret0, ret1 } // GetByID indicates an expected call of GetByID. -func (mr *MockRepositoryMockRecorder) GetByID(id any) *RepositoryGetByIDCall { +func (mr *MockRepositoryMockRecorder) GetByID(ctx, id any) *RepositoryGetByIDCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByID", reflect.TypeOf((*MockRepository)(nil).GetByID), id) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByID", reflect.TypeOf((*MockRepository)(nil).GetByID), ctx, id) return &RepositoryGetByIDCall{Call: call} } @@ -301,112 +145,30 @@ func (c *RepositoryGetByIDCall) Return(arg0 operation.Operation, arg1 error) *Re } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetByIDCall) Do(f func(int64) (operation.Operation, error)) *RepositoryGetByIDCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetByIDCall) DoAndReturn(f func(int64) (operation.Operation, error)) *RepositoryGetByIDCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// GetByIDs mocks base method. -func (m *MockRepository) GetByIDs(ids ...int64) ([]operation.Operation, error) { - m.ctrl.T.Helper() - varargs := []any{} - for _, a := range ids { - varargs = append(varargs, a) - } - ret := m.ctrl.Call(m, "GetByIDs", varargs...) - ret0, _ := ret[0].([]operation.Operation) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetByIDs indicates an expected call of GetByIDs. -func (mr *MockRepositoryMockRecorder) GetByIDs(ids ...any) *RepositoryGetByIDsCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByIDs", reflect.TypeOf((*MockRepository)(nil).GetByIDs), ids...) - return &RepositoryGetByIDsCall{Call: call} -} - -// RepositoryGetByIDsCall wrap *gomock.Call -type RepositoryGetByIDsCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryGetByIDsCall) Return(arg0 []operation.Operation, arg1 error) *RepositoryGetByIDsCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryGetByIDsCall) Do(f func(...int64) ([]operation.Operation, error)) *RepositoryGetByIDsCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetByIDsCall) DoAndReturn(f func(...int64) ([]operation.Operation, error)) *RepositoryGetByIDsCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// GetImplicitOperation mocks base method. -func (m *MockRepository) GetImplicitOperation(counter int64) (operation.Operation, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetImplicitOperation", counter) - ret0, _ := ret[0].(operation.Operation) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetImplicitOperation indicates an expected call of GetImplicitOperation. -func (mr *MockRepositoryMockRecorder) GetImplicitOperation(counter any) *RepositoryGetImplicitOperationCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImplicitOperation", reflect.TypeOf((*MockRepository)(nil).GetImplicitOperation), counter) - return &RepositoryGetImplicitOperationCall{Call: call} -} - -// RepositoryGetImplicitOperationCall wrap *gomock.Call -type RepositoryGetImplicitOperationCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryGetImplicitOperationCall) Return(arg0 operation.Operation, arg1 error) *RepositoryGetImplicitOperationCall { - c.Call = c.Call.Return(arg0, arg1) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryGetImplicitOperationCall) Do(f func(int64) (operation.Operation, error)) *RepositoryGetImplicitOperationCall { +func (c *RepositoryGetByIDCall) Do(f func(context.Context, int64) (operation.Operation, error)) *RepositoryGetByIDCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetImplicitOperationCall) DoAndReturn(f func(int64) (operation.Operation, error)) *RepositoryGetImplicitOperationCall { +func (c *RepositoryGetByIDCall) DoAndReturn(f func(context.Context, int64) (operation.Operation, error)) *RepositoryGetByIDCall { c.Call = c.Call.DoAndReturn(f) return c } // Last mocks base method. -func (m *MockRepository) Last(filter map[string]any, lastID int64) (operation.Operation, error) { +func (m *MockRepository) Last(ctx context.Context, filter map[string]any, lastID int64) (operation.Operation, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Last", filter, lastID) + ret := m.ctrl.Call(m, "Last", ctx, filter, lastID) ret0, _ := ret[0].(operation.Operation) ret1, _ := ret[1].(error) return ret0, ret1 } // Last indicates an expected call of Last. -func (mr *MockRepositoryMockRecorder) Last(filter, lastID any) *RepositoryLastCall { +func (mr *MockRepositoryMockRecorder) Last(ctx, filter, lastID any) *RepositoryLastCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Last", reflect.TypeOf((*MockRepository)(nil).Last), filter, lastID) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Last", reflect.TypeOf((*MockRepository)(nil).Last), ctx, filter, lastID) return &RepositoryLastCall{Call: call} } @@ -422,30 +184,30 @@ func (c *RepositoryLastCall) Return(arg0 operation.Operation, arg1 error) *Repos } // Do rewrite *gomock.Call.Do -func (c *RepositoryLastCall) Do(f func(map[string]any, int64) (operation.Operation, error)) *RepositoryLastCall { +func (c *RepositoryLastCall) Do(f func(context.Context, map[string]any, int64) (operation.Operation, error)) *RepositoryLastCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryLastCall) DoAndReturn(f func(map[string]any, int64) (operation.Operation, error)) *RepositoryLastCall { +func (c *RepositoryLastCall) DoAndReturn(f func(context.Context, map[string]any, int64) (operation.Operation, error)) *RepositoryLastCall { c.Call = c.Call.DoAndReturn(f) return c } // ListEvents mocks base method. -func (m *MockRepository) ListEvents(accountID, size, offset int64) ([]operation.Operation, error) { +func (m *MockRepository) ListEvents(ctx context.Context, accountID, size, offset int64) ([]operation.Operation, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ListEvents", accountID, size, offset) + ret := m.ctrl.Call(m, "ListEvents", ctx, accountID, size, offset) ret0, _ := ret[0].([]operation.Operation) ret1, _ := ret[1].(error) return ret0, ret1 } // ListEvents indicates an expected call of ListEvents. -func (mr *MockRepositoryMockRecorder) ListEvents(accountID, size, offset any) *RepositoryListEventsCall { +func (mr *MockRepositoryMockRecorder) ListEvents(ctx, accountID, size, offset any) *RepositoryListEventsCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListEvents", reflect.TypeOf((*MockRepository)(nil).ListEvents), accountID, size, offset) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListEvents", reflect.TypeOf((*MockRepository)(nil).ListEvents), ctx, accountID, size, offset) return &RepositoryListEventsCall{Call: call} } @@ -461,30 +223,30 @@ func (c *RepositoryListEventsCall) Return(arg0 []operation.Operation, arg1 error } // Do rewrite *gomock.Call.Do -func (c *RepositoryListEventsCall) Do(f func(int64, int64, int64) ([]operation.Operation, error)) *RepositoryListEventsCall { +func (c *RepositoryListEventsCall) Do(f func(context.Context, int64, int64, int64) ([]operation.Operation, error)) *RepositoryListEventsCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryListEventsCall) DoAndReturn(f func(int64, int64, int64) ([]operation.Operation, error)) *RepositoryListEventsCall { +func (c *RepositoryListEventsCall) DoAndReturn(f func(context.Context, int64, int64, int64) ([]operation.Operation, error)) *RepositoryListEventsCall { c.Call = c.Call.DoAndReturn(f) return c } // OPG mocks base method. -func (m *MockRepository) OPG(address string, size, lastID int64) ([]operation.OPG, error) { +func (m *MockRepository) OPG(ctx context.Context, address string, size, lastID int64) ([]operation.OPG, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "OPG", address, size, lastID) + ret := m.ctrl.Call(m, "OPG", ctx, address, size, lastID) ret0, _ := ret[0].([]operation.OPG) ret1, _ := ret[1].(error) return ret0, ret1 } // OPG indicates an expected call of OPG. -func (mr *MockRepositoryMockRecorder) OPG(address, size, lastID any) *RepositoryOPGCall { +func (mr *MockRepositoryMockRecorder) OPG(ctx, address, size, lastID any) *RepositoryOPGCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OPG", reflect.TypeOf((*MockRepository)(nil).OPG), address, size, lastID) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "OPG", reflect.TypeOf((*MockRepository)(nil).OPG), ctx, address, size, lastID) return &RepositoryOPGCall{Call: call} } @@ -500,30 +262,30 @@ func (c *RepositoryOPGCall) Return(arg0 []operation.OPG, arg1 error) *Repository } // Do rewrite *gomock.Call.Do -func (c *RepositoryOPGCall) Do(f func(string, int64, int64) ([]operation.OPG, error)) *RepositoryOPGCall { +func (c *RepositoryOPGCall) Do(f func(context.Context, string, int64, int64) ([]operation.OPG, error)) *RepositoryOPGCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryOPGCall) DoAndReturn(f func(string, int64, int64) ([]operation.OPG, error)) *RepositoryOPGCall { +func (c *RepositoryOPGCall) DoAndReturn(f func(context.Context, string, int64, int64) ([]operation.OPG, error)) *RepositoryOPGCall { c.Call = c.Call.DoAndReturn(f) return c } // Origination mocks base method. -func (m *MockRepository) Origination(accountID int64) (operation.Operation, error) { +func (m *MockRepository) Origination(ctx context.Context, accountID int64) (operation.Operation, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Origination", accountID) + ret := m.ctrl.Call(m, "Origination", ctx, accountID) ret0, _ := ret[0].(operation.Operation) ret1, _ := ret[1].(error) return ret0, ret1 } // Origination indicates an expected call of Origination. -func (mr *MockRepositoryMockRecorder) Origination(accountID any) *RepositoryOriginationCall { +func (mr *MockRepositoryMockRecorder) Origination(ctx, accountID any) *RepositoryOriginationCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Origination", reflect.TypeOf((*MockRepository)(nil).Origination), accountID) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Origination", reflect.TypeOf((*MockRepository)(nil).Origination), ctx, accountID) return &RepositoryOriginationCall{Call: call} } @@ -539,13 +301,13 @@ func (c *RepositoryOriginationCall) Return(arg0 operation.Operation, arg1 error) } // Do rewrite *gomock.Call.Do -func (c *RepositoryOriginationCall) Do(f func(int64) (operation.Operation, error)) *RepositoryOriginationCall { +func (c *RepositoryOriginationCall) Do(f func(context.Context, int64) (operation.Operation, error)) *RepositoryOriginationCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryOriginationCall) DoAndReturn(f func(int64) (operation.Operation, error)) *RepositoryOriginationCall { +func (c *RepositoryOriginationCall) DoAndReturn(f func(context.Context, int64) (operation.Operation, error)) *RepositoryOriginationCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/internal/models/mock/protocol/mock.go b/internal/models/mock/protocol/mock.go index ce05605ac..55deca6e5 100644 --- a/internal/models/mock/protocol/mock.go +++ b/internal/models/mock/protocol/mock.go @@ -9,6 +9,7 @@ package protocol import ( + context "context" reflect "reflect" protocol "github.com/baking-bad/bcdhub/internal/models/protocol" @@ -39,18 +40,18 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { } // Get mocks base method. -func (m *MockRepository) Get(hash string, level int64) (protocol.Protocol, error) { +func (m *MockRepository) Get(ctx context.Context, hash string, level int64) (protocol.Protocol, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", hash, level) + ret := m.ctrl.Call(m, "Get", ctx, hash, level) ret0, _ := ret[0].(protocol.Protocol) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get. -func (mr *MockRepositoryMockRecorder) Get(hash, level any) *RepositoryGetCall { +func (mr *MockRepositoryMockRecorder) Get(ctx, hash, level any) *RepositoryGetCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), hash, level) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), ctx, hash, level) return &RepositoryGetCall{Call: call} } @@ -66,69 +67,30 @@ func (c *RepositoryGetCall) Return(arg0 protocol.Protocol, arg1 error) *Reposito } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetCall) Do(f func(string, int64) (protocol.Protocol, error)) *RepositoryGetCall { +func (c *RepositoryGetCall) Do(f func(context.Context, string, int64) (protocol.Protocol, error)) *RepositoryGetCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetCall) DoAndReturn(f func(string, int64) (protocol.Protocol, error)) *RepositoryGetCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// GetAll mocks base method. -func (m *MockRepository) GetAll() ([]protocol.Protocol, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetAll") - ret0, _ := ret[0].([]protocol.Protocol) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetAll indicates an expected call of GetAll. -func (mr *MockRepositoryMockRecorder) GetAll() *RepositoryGetAllCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAll", reflect.TypeOf((*MockRepository)(nil).GetAll)) - return &RepositoryGetAllCall{Call: call} -} - -// RepositoryGetAllCall wrap *gomock.Call -type RepositoryGetAllCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryGetAllCall) Return(response []protocol.Protocol, err error) *RepositoryGetAllCall { - c.Call = c.Call.Return(response, err) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryGetAllCall) Do(f func() ([]protocol.Protocol, error)) *RepositoryGetAllCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetAllCall) DoAndReturn(f func() ([]protocol.Protocol, error)) *RepositoryGetAllCall { +func (c *RepositoryGetCall) DoAndReturn(f func(context.Context, string, int64) (protocol.Protocol, error)) *RepositoryGetCall { c.Call = c.Call.DoAndReturn(f) return c } // GetByID mocks base method. -func (m *MockRepository) GetByID(id int64) (protocol.Protocol, error) { +func (m *MockRepository) GetByID(ctx context.Context, id int64) (protocol.Protocol, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByID", id) + ret := m.ctrl.Call(m, "GetByID", ctx, id) ret0, _ := ret[0].(protocol.Protocol) ret1, _ := ret[1].(error) return ret0, ret1 } // GetByID indicates an expected call of GetByID. -func (mr *MockRepositoryMockRecorder) GetByID(id any) *RepositoryGetByIDCall { +func (mr *MockRepositoryMockRecorder) GetByID(ctx, id any) *RepositoryGetByIDCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByID", reflect.TypeOf((*MockRepository)(nil).GetByID), id) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByID", reflect.TypeOf((*MockRepository)(nil).GetByID), ctx, id) return &RepositoryGetByIDCall{Call: call} } @@ -144,52 +106,13 @@ func (c *RepositoryGetByIDCall) Return(response protocol.Protocol, err error) *R } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetByIDCall) Do(f func(int64) (protocol.Protocol, error)) *RepositoryGetByIDCall { - c.Call = c.Call.Do(f) - return c -} - -// DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetByIDCall) DoAndReturn(f func(int64) (protocol.Protocol, error)) *RepositoryGetByIDCall { - c.Call = c.Call.DoAndReturn(f) - return c -} - -// GetByNetworkWithSort mocks base method. -func (m *MockRepository) GetByNetworkWithSort(sortField, order string) ([]protocol.Protocol, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetByNetworkWithSort", sortField, order) - ret0, _ := ret[0].([]protocol.Protocol) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetByNetworkWithSort indicates an expected call of GetByNetworkWithSort. -func (mr *MockRepositoryMockRecorder) GetByNetworkWithSort(sortField, order any) *RepositoryGetByNetworkWithSortCall { - mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetByNetworkWithSort", reflect.TypeOf((*MockRepository)(nil).GetByNetworkWithSort), sortField, order) - return &RepositoryGetByNetworkWithSortCall{Call: call} -} - -// RepositoryGetByNetworkWithSortCall wrap *gomock.Call -type RepositoryGetByNetworkWithSortCall struct { - *gomock.Call -} - -// Return rewrite *gomock.Call.Return -func (c *RepositoryGetByNetworkWithSortCall) Return(response []protocol.Protocol, err error) *RepositoryGetByNetworkWithSortCall { - c.Call = c.Call.Return(response, err) - return c -} - -// Do rewrite *gomock.Call.Do -func (c *RepositoryGetByNetworkWithSortCall) Do(f func(string, string) ([]protocol.Protocol, error)) *RepositoryGetByNetworkWithSortCall { +func (c *RepositoryGetByIDCall) Do(f func(context.Context, int64) (protocol.Protocol, error)) *RepositoryGetByIDCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetByNetworkWithSortCall) DoAndReturn(f func(string, string) ([]protocol.Protocol, error)) *RepositoryGetByNetworkWithSortCall { +func (c *RepositoryGetByIDCall) DoAndReturn(f func(context.Context, int64) (protocol.Protocol, error)) *RepositoryGetByIDCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/internal/models/mock/rollback.go b/internal/models/mock/rollback.go new file mode 100644 index 000000000..f949c5b94 --- /dev/null +++ b/internal/models/mock/rollback.go @@ -0,0 +1,865 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: rollback.go +// +// Generated by this command: +// +// mockgen -source=rollback.go -destination=mock/rollback.go -package=mock -typed +// +// Package mock is a generated GoMock package. +package mock + +import ( + context "context" + reflect "reflect" + + models "github.com/baking-bad/bcdhub/internal/models" + account "github.com/baking-bad/bcdhub/internal/models/account" + bigmapdiff "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + contract "github.com/baking-bad/bcdhub/internal/models/contract" + migration "github.com/baking-bad/bcdhub/internal/models/migration" + operation "github.com/baking-bad/bcdhub/internal/models/operation" + stats "github.com/baking-bad/bcdhub/internal/models/stats" + ticket "github.com/baking-bad/bcdhub/internal/models/ticket" + gomock "go.uber.org/mock/gomock" +) + +// MockRollback is a mock of Rollback interface. +type MockRollback struct { + ctrl *gomock.Controller + recorder *MockRollbackMockRecorder +} + +// MockRollbackMockRecorder is the mock recorder for MockRollback. +type MockRollbackMockRecorder struct { + mock *MockRollback +} + +// NewMockRollback creates a new mock instance. +func NewMockRollback(ctrl *gomock.Controller) *MockRollback { + mock := &MockRollback{ctrl: ctrl} + mock.recorder = &MockRollbackMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockRollback) EXPECT() *MockRollbackMockRecorder { + return m.recorder +} + +// Commit mocks base method. +func (m *MockRollback) Commit() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Commit") + ret0, _ := ret[0].(error) + return ret0 +} + +// Commit indicates an expected call of Commit. +func (mr *MockRollbackMockRecorder) Commit() *RollbackCommitCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockRollback)(nil).Commit)) + return &RollbackCommitCall{Call: call} +} + +// RollbackCommitCall wrap *gomock.Call +type RollbackCommitCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackCommitCall) Return(arg0 error) *RollbackCommitCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackCommitCall) Do(f func() error) *RollbackCommitCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackCommitCall) DoAndReturn(f func() error) *RollbackCommitCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// DeleteAll mocks base method. +func (m *MockRollback) DeleteAll(ctx context.Context, model any, level int64) (int, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteAll", ctx, model, level) + ret0, _ := ret[0].(int) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteAll indicates an expected call of DeleteAll. +func (mr *MockRollbackMockRecorder) DeleteAll(ctx, model, level any) *RollbackDeleteAllCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAll", reflect.TypeOf((*MockRollback)(nil).DeleteAll), ctx, model, level) + return &RollbackDeleteAllCall{Call: call} +} + +// RollbackDeleteAllCall wrap *gomock.Call +type RollbackDeleteAllCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackDeleteAllCall) Return(arg0 int, arg1 error) *RollbackDeleteAllCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackDeleteAllCall) Do(f func(context.Context, any, int64) (int, error)) *RollbackDeleteAllCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackDeleteAllCall) DoAndReturn(f func(context.Context, any, int64) (int, error)) *RollbackDeleteAllCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// DeleteBigMapState mocks base method. +func (m *MockRollback) DeleteBigMapState(ctx context.Context, state bigmapdiff.BigMapState) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBigMapState", ctx, state) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteBigMapState indicates an expected call of DeleteBigMapState. +func (mr *MockRollbackMockRecorder) DeleteBigMapState(ctx, state any) *RollbackDeleteBigMapStateCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBigMapState", reflect.TypeOf((*MockRollback)(nil).DeleteBigMapState), ctx, state) + return &RollbackDeleteBigMapStateCall{Call: call} +} + +// RollbackDeleteBigMapStateCall wrap *gomock.Call +type RollbackDeleteBigMapStateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackDeleteBigMapStateCall) Return(arg0 error) *RollbackDeleteBigMapStateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackDeleteBigMapStateCall) Do(f func(context.Context, bigmapdiff.BigMapState) error) *RollbackDeleteBigMapStateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackDeleteBigMapStateCall) DoAndReturn(f func(context.Context, bigmapdiff.BigMapState) error) *RollbackDeleteBigMapStateCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// DeleteScriptsConstants mocks base method. +func (m *MockRollback) DeleteScriptsConstants(ctx context.Context, scriptIds, constantsIds []int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteScriptsConstants", ctx, scriptIds, constantsIds) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteScriptsConstants indicates an expected call of DeleteScriptsConstants. +func (mr *MockRollbackMockRecorder) DeleteScriptsConstants(ctx, scriptIds, constantsIds any) *RollbackDeleteScriptsConstantsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteScriptsConstants", reflect.TypeOf((*MockRollback)(nil).DeleteScriptsConstants), ctx, scriptIds, constantsIds) + return &RollbackDeleteScriptsConstantsCall{Call: call} +} + +// RollbackDeleteScriptsConstantsCall wrap *gomock.Call +type RollbackDeleteScriptsConstantsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackDeleteScriptsConstantsCall) Return(arg0 error) *RollbackDeleteScriptsConstantsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackDeleteScriptsConstantsCall) Do(f func(context.Context, []int64, []int64) error) *RollbackDeleteScriptsConstantsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackDeleteScriptsConstantsCall) DoAndReturn(f func(context.Context, []int64, []int64) error) *RollbackDeleteScriptsConstantsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// DeleteTicketBalances mocks base method. +func (m *MockRollback) DeleteTicketBalances(ctx context.Context, ticketIds []int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteTicketBalances", ctx, ticketIds) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteTicketBalances indicates an expected call of DeleteTicketBalances. +func (mr *MockRollbackMockRecorder) DeleteTicketBalances(ctx, ticketIds any) *RollbackDeleteTicketBalancesCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTicketBalances", reflect.TypeOf((*MockRollback)(nil).DeleteTicketBalances), ctx, ticketIds) + return &RollbackDeleteTicketBalancesCall{Call: call} +} + +// RollbackDeleteTicketBalancesCall wrap *gomock.Call +type RollbackDeleteTicketBalancesCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackDeleteTicketBalancesCall) Return(err error) *RollbackDeleteTicketBalancesCall { + c.Call = c.Call.Return(err) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackDeleteTicketBalancesCall) Do(f func(context.Context, []int64) error) *RollbackDeleteTicketBalancesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackDeleteTicketBalancesCall) DoAndReturn(f func(context.Context, []int64) error) *RollbackDeleteTicketBalancesCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// DeleteTickets mocks base method. +func (m *MockRollback) DeleteTickets(ctx context.Context, level int64) ([]int64, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteTickets", ctx, level) + ret0, _ := ret[0].([]int64) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// DeleteTickets indicates an expected call of DeleteTickets. +func (mr *MockRollbackMockRecorder) DeleteTickets(ctx, level any) *RollbackDeleteTicketsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteTickets", reflect.TypeOf((*MockRollback)(nil).DeleteTickets), ctx, level) + return &RollbackDeleteTicketsCall{Call: call} +} + +// RollbackDeleteTicketsCall wrap *gomock.Call +type RollbackDeleteTicketsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackDeleteTicketsCall) Return(ids []int64, err error) *RollbackDeleteTicketsCall { + c.Call = c.Call.Return(ids, err) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackDeleteTicketsCall) Do(f func(context.Context, int64) ([]int64, error)) *RollbackDeleteTicketsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackDeleteTicketsCall) DoAndReturn(f func(context.Context, int64) ([]int64, error)) *RollbackDeleteTicketsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// GetLastAction mocks base method. +func (m *MockRollback) GetLastAction(ctx context.Context, addressIds ...int64) ([]models.LastAction, error) { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range addressIds { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetLastAction", varargs...) + ret0, _ := ret[0].([]models.LastAction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetLastAction indicates an expected call of GetLastAction. +func (mr *MockRollbackMockRecorder) GetLastAction(ctx any, addressIds ...any) *RollbackGetLastActionCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, addressIds...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastAction", reflect.TypeOf((*MockRollback)(nil).GetLastAction), varargs...) + return &RollbackGetLastActionCall{Call: call} +} + +// RollbackGetLastActionCall wrap *gomock.Call +type RollbackGetLastActionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackGetLastActionCall) Return(arg0 []models.LastAction, arg1 error) *RollbackGetLastActionCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackGetLastActionCall) Do(f func(context.Context, ...int64) ([]models.LastAction, error)) *RollbackGetLastActionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackGetLastActionCall) DoAndReturn(f func(context.Context, ...int64) ([]models.LastAction, error)) *RollbackGetLastActionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// GetMigrations mocks base method. +func (m *MockRollback) GetMigrations(ctx context.Context, level int64) ([]migration.Migration, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetMigrations", ctx, level) + ret0, _ := ret[0].([]migration.Migration) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetMigrations indicates an expected call of GetMigrations. +func (mr *MockRollbackMockRecorder) GetMigrations(ctx, level any) *RollbackGetMigrationsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetMigrations", reflect.TypeOf((*MockRollback)(nil).GetMigrations), ctx, level) + return &RollbackGetMigrationsCall{Call: call} +} + +// RollbackGetMigrationsCall wrap *gomock.Call +type RollbackGetMigrationsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackGetMigrationsCall) Return(arg0 []migration.Migration, arg1 error) *RollbackGetMigrationsCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackGetMigrationsCall) Do(f func(context.Context, int64) ([]migration.Migration, error)) *RollbackGetMigrationsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackGetMigrationsCall) DoAndReturn(f func(context.Context, int64) ([]migration.Migration, error)) *RollbackGetMigrationsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// GetOperations mocks base method. +func (m *MockRollback) GetOperations(ctx context.Context, level int64) ([]operation.Operation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOperations", ctx, level) + ret0, _ := ret[0].([]operation.Operation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetOperations indicates an expected call of GetOperations. +func (mr *MockRollbackMockRecorder) GetOperations(ctx, level any) *RollbackGetOperationsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperations", reflect.TypeOf((*MockRollback)(nil).GetOperations), ctx, level) + return &RollbackGetOperationsCall{Call: call} +} + +// RollbackGetOperationsCall wrap *gomock.Call +type RollbackGetOperationsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackGetOperationsCall) Return(arg0 []operation.Operation, arg1 error) *RollbackGetOperationsCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackGetOperationsCall) Do(f func(context.Context, int64) ([]operation.Operation, error)) *RollbackGetOperationsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackGetOperationsCall) DoAndReturn(f func(context.Context, int64) ([]operation.Operation, error)) *RollbackGetOperationsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// GetTicketUpdates mocks base method. +func (m *MockRollback) GetTicketUpdates(ctx context.Context, level int64) ([]ticket.TicketUpdate, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetTicketUpdates", ctx, level) + ret0, _ := ret[0].([]ticket.TicketUpdate) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetTicketUpdates indicates an expected call of GetTicketUpdates. +func (mr *MockRollbackMockRecorder) GetTicketUpdates(ctx, level any) *RollbackGetTicketUpdatesCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTicketUpdates", reflect.TypeOf((*MockRollback)(nil).GetTicketUpdates), ctx, level) + return &RollbackGetTicketUpdatesCall{Call: call} +} + +// RollbackGetTicketUpdatesCall wrap *gomock.Call +type RollbackGetTicketUpdatesCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackGetTicketUpdatesCall) Return(arg0 []ticket.TicketUpdate, arg1 error) *RollbackGetTicketUpdatesCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackGetTicketUpdatesCall) Do(f func(context.Context, int64) ([]ticket.TicketUpdate, error)) *RollbackGetTicketUpdatesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackGetTicketUpdatesCall) DoAndReturn(f func(context.Context, int64) ([]ticket.TicketUpdate, error)) *RollbackGetTicketUpdatesCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// GlobalConstants mocks base method. +func (m *MockRollback) GlobalConstants(ctx context.Context, level int64) ([]contract.GlobalConstant, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GlobalConstants", ctx, level) + ret0, _ := ret[0].([]contract.GlobalConstant) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GlobalConstants indicates an expected call of GlobalConstants. +func (mr *MockRollbackMockRecorder) GlobalConstants(ctx, level any) *RollbackGlobalConstantsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GlobalConstants", reflect.TypeOf((*MockRollback)(nil).GlobalConstants), ctx, level) + return &RollbackGlobalConstantsCall{Call: call} +} + +// RollbackGlobalConstantsCall wrap *gomock.Call +type RollbackGlobalConstantsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackGlobalConstantsCall) Return(arg0 []contract.GlobalConstant, arg1 error) *RollbackGlobalConstantsCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackGlobalConstantsCall) Do(f func(context.Context, int64) ([]contract.GlobalConstant, error)) *RollbackGlobalConstantsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackGlobalConstantsCall) DoAndReturn(f func(context.Context, int64) ([]contract.GlobalConstant, error)) *RollbackGlobalConstantsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// LastDiff mocks base method. +func (m *MockRollback) LastDiff(ctx context.Context, ptr int64, keyHash string, skipRemoved bool) (bigmapdiff.BigMapDiff, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LastDiff", ctx, ptr, keyHash, skipRemoved) + ret0, _ := ret[0].(bigmapdiff.BigMapDiff) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// LastDiff indicates an expected call of LastDiff. +func (mr *MockRollbackMockRecorder) LastDiff(ctx, ptr, keyHash, skipRemoved any) *RollbackLastDiffCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastDiff", reflect.TypeOf((*MockRollback)(nil).LastDiff), ctx, ptr, keyHash, skipRemoved) + return &RollbackLastDiffCall{Call: call} +} + +// RollbackLastDiffCall wrap *gomock.Call +type RollbackLastDiffCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackLastDiffCall) Return(arg0 bigmapdiff.BigMapDiff, arg1 error) *RollbackLastDiffCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackLastDiffCall) Do(f func(context.Context, int64, string, bool) (bigmapdiff.BigMapDiff, error)) *RollbackLastDiffCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackLastDiffCall) DoAndReturn(f func(context.Context, int64, string, bool) (bigmapdiff.BigMapDiff, error)) *RollbackLastDiffCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Protocols mocks base method. +func (m *MockRollback) Protocols(ctx context.Context, level int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Protocols", ctx, level) + ret0, _ := ret[0].(error) + return ret0 +} + +// Protocols indicates an expected call of Protocols. +func (mr *MockRollbackMockRecorder) Protocols(ctx, level any) *RollbackProtocolsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Protocols", reflect.TypeOf((*MockRollback)(nil).Protocols), ctx, level) + return &RollbackProtocolsCall{Call: call} +} + +// RollbackProtocolsCall wrap *gomock.Call +type RollbackProtocolsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackProtocolsCall) Return(arg0 error) *RollbackProtocolsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackProtocolsCall) Do(f func(context.Context, int64) error) *RollbackProtocolsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackProtocolsCall) DoAndReturn(f func(context.Context, int64) error) *RollbackProtocolsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Rollback mocks base method. +func (m *MockRollback) Rollback() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Rollback") + ret0, _ := ret[0].(error) + return ret0 +} + +// Rollback indicates an expected call of Rollback. +func (mr *MockRollbackMockRecorder) Rollback() *RollbackRollbackCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Rollback", reflect.TypeOf((*MockRollback)(nil).Rollback)) + return &RollbackRollbackCall{Call: call} +} + +// RollbackRollbackCall wrap *gomock.Call +type RollbackRollbackCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackRollbackCall) Return(arg0 error) *RollbackRollbackCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackRollbackCall) Do(f func() error) *RollbackRollbackCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackRollbackCall) DoAndReturn(f func() error) *RollbackRollbackCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SaveBigMapState mocks base method. +func (m *MockRollback) SaveBigMapState(ctx context.Context, state bigmapdiff.BigMapState) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SaveBigMapState", ctx, state) + ret0, _ := ret[0].(error) + return ret0 +} + +// SaveBigMapState indicates an expected call of SaveBigMapState. +func (mr *MockRollbackMockRecorder) SaveBigMapState(ctx, state any) *RollbackSaveBigMapStateCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveBigMapState", reflect.TypeOf((*MockRollback)(nil).SaveBigMapState), ctx, state) + return &RollbackSaveBigMapStateCall{Call: call} +} + +// RollbackSaveBigMapStateCall wrap *gomock.Call +type RollbackSaveBigMapStateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackSaveBigMapStateCall) Return(arg0 error) *RollbackSaveBigMapStateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackSaveBigMapStateCall) Do(f func(context.Context, bigmapdiff.BigMapState) error) *RollbackSaveBigMapStateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackSaveBigMapStateCall) DoAndReturn(f func(context.Context, bigmapdiff.BigMapState) error) *RollbackSaveBigMapStateCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Scripts mocks base method. +func (m *MockRollback) Scripts(ctx context.Context, level int64) ([]contract.Script, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Scripts", ctx, level) + ret0, _ := ret[0].([]contract.Script) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Scripts indicates an expected call of Scripts. +func (mr *MockRollbackMockRecorder) Scripts(ctx, level any) *RollbackScriptsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Scripts", reflect.TypeOf((*MockRollback)(nil).Scripts), ctx, level) + return &RollbackScriptsCall{Call: call} +} + +// RollbackScriptsCall wrap *gomock.Call +type RollbackScriptsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackScriptsCall) Return(arg0 []contract.Script, arg1 error) *RollbackScriptsCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackScriptsCall) Do(f func(context.Context, int64) ([]contract.Script, error)) *RollbackScriptsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackScriptsCall) DoAndReturn(f func(context.Context, int64) ([]contract.Script, error)) *RollbackScriptsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// StatesChangedAtLevel mocks base method. +func (m *MockRollback) StatesChangedAtLevel(ctx context.Context, level int64) ([]bigmapdiff.BigMapState, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StatesChangedAtLevel", ctx, level) + ret0, _ := ret[0].([]bigmapdiff.BigMapState) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StatesChangedAtLevel indicates an expected call of StatesChangedAtLevel. +func (mr *MockRollbackMockRecorder) StatesChangedAtLevel(ctx, level any) *RollbackStatesChangedAtLevelCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StatesChangedAtLevel", reflect.TypeOf((*MockRollback)(nil).StatesChangedAtLevel), ctx, level) + return &RollbackStatesChangedAtLevelCall{Call: call} +} + +// RollbackStatesChangedAtLevelCall wrap *gomock.Call +type RollbackStatesChangedAtLevelCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackStatesChangedAtLevelCall) Return(arg0 []bigmapdiff.BigMapState, arg1 error) *RollbackStatesChangedAtLevelCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackStatesChangedAtLevelCall) Do(f func(context.Context, int64) ([]bigmapdiff.BigMapState, error)) *RollbackStatesChangedAtLevelCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackStatesChangedAtLevelCall) DoAndReturn(f func(context.Context, int64) ([]bigmapdiff.BigMapState, error)) *RollbackStatesChangedAtLevelCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// TicketBalances mocks base method. +func (m *MockRollback) TicketBalances(ctx context.Context, balances ...*ticket.Balance) error { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range balances { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "TicketBalances", varargs...) + ret0, _ := ret[0].(error) + return ret0 +} + +// TicketBalances indicates an expected call of TicketBalances. +func (mr *MockRollbackMockRecorder) TicketBalances(ctx any, balances ...any) *RollbackTicketBalancesCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, balances...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TicketBalances", reflect.TypeOf((*MockRollback)(nil).TicketBalances), varargs...) + return &RollbackTicketBalancesCall{Call: call} +} + +// RollbackTicketBalancesCall wrap *gomock.Call +type RollbackTicketBalancesCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackTicketBalancesCall) Return(arg0 error) *RollbackTicketBalancesCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackTicketBalancesCall) Do(f func(context.Context, ...*ticket.Balance) error) *RollbackTicketBalancesCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackTicketBalancesCall) DoAndReturn(f func(context.Context, ...*ticket.Balance) error) *RollbackTicketBalancesCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// UpdateAccountStats mocks base method. +func (m *MockRollback) UpdateAccountStats(ctx context.Context, account account.Account) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateAccountStats", ctx, account) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateAccountStats indicates an expected call of UpdateAccountStats. +func (mr *MockRollbackMockRecorder) UpdateAccountStats(ctx, account any) *RollbackUpdateAccountStatsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateAccountStats", reflect.TypeOf((*MockRollback)(nil).UpdateAccountStats), ctx, account) + return &RollbackUpdateAccountStatsCall{Call: call} +} + +// RollbackUpdateAccountStatsCall wrap *gomock.Call +type RollbackUpdateAccountStatsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackUpdateAccountStatsCall) Return(arg0 error) *RollbackUpdateAccountStatsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackUpdateAccountStatsCall) Do(f func(context.Context, account.Account) error) *RollbackUpdateAccountStatsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackUpdateAccountStatsCall) DoAndReturn(f func(context.Context, account.Account) error) *RollbackUpdateAccountStatsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// UpdateStats mocks base method. +func (m *MockRollback) UpdateStats(ctx context.Context, stats stats.Stats) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateStats", ctx, stats) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateStats indicates an expected call of UpdateStats. +func (mr *MockRollbackMockRecorder) UpdateStats(ctx, stats any) *RollbackUpdateStatsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateStats", reflect.TypeOf((*MockRollback)(nil).UpdateStats), ctx, stats) + return &RollbackUpdateStatsCall{Call: call} +} + +// RollbackUpdateStatsCall wrap *gomock.Call +type RollbackUpdateStatsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackUpdateStatsCall) Return(arg0 error) *RollbackUpdateStatsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackUpdateStatsCall) Do(f func(context.Context, stats.Stats) error) *RollbackUpdateStatsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackUpdateStatsCall) DoAndReturn(f func(context.Context, stats.Stats) error) *RollbackUpdateStatsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// UpdateTicket mocks base method. +func (m *MockRollback) UpdateTicket(ctx context.Context, ticket ticket.Ticket) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateTicket", ctx, ticket) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateTicket indicates an expected call of UpdateTicket. +func (mr *MockRollbackMockRecorder) UpdateTicket(ctx, ticket any) *RollbackUpdateTicketCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateTicket", reflect.TypeOf((*MockRollback)(nil).UpdateTicket), ctx, ticket) + return &RollbackUpdateTicketCall{Call: call} +} + +// RollbackUpdateTicketCall wrap *gomock.Call +type RollbackUpdateTicketCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RollbackUpdateTicketCall) Return(arg0 error) *RollbackUpdateTicketCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RollbackUpdateTicketCall) Do(f func(context.Context, ticket.Ticket) error) *RollbackUpdateTicketCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RollbackUpdateTicketCall) DoAndReturn(f func(context.Context, ticket.Ticket) error) *RollbackUpdateTicketCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/internal/models/mock/saver.go b/internal/models/mock/saver.go new file mode 100644 index 000000000..7d5d482b7 --- /dev/null +++ b/internal/models/mock/saver.go @@ -0,0 +1,432 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: saver.go +// +// Generated by this command: +// +// mockgen -source=saver.go -destination=mock/saver.go -package=mock -typed +// +// Package mock is a generated GoMock package. +package mock + +import ( + context "context" + reflect "reflect" + time "time" + + models "github.com/baking-bad/bcdhub/internal/models" + bigmapdiff "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + operation "github.com/baking-bad/bcdhub/internal/models/operation" + gomock "go.uber.org/mock/gomock" +) + +// MockSaver is a mock of Saver interface. +type MockSaver struct { + ctrl *gomock.Controller + recorder *MockSaverMockRecorder +} + +// MockSaverMockRecorder is the mock recorder for MockSaver. +type MockSaverMockRecorder struct { + mock *MockSaver +} + +// NewMockSaver creates a new mock instance. +func NewMockSaver(ctrl *gomock.Controller) *MockSaver { + mock := &MockSaver{ctrl: ctrl} + mock.recorder = &MockSaverMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockSaver) EXPECT() *MockSaverMockRecorder { + return m.recorder +} + +// Commit mocks base method. +func (m *MockSaver) Commit() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Commit") + ret0, _ := ret[0].(error) + return ret0 +} + +// Commit indicates an expected call of Commit. +func (mr *MockSaverMockRecorder) Commit() *SaverCommitCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Commit", reflect.TypeOf((*MockSaver)(nil).Commit)) + return &SaverCommitCall{Call: call} +} + +// SaverCommitCall wrap *gomock.Call +type SaverCommitCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SaverCommitCall) Return(arg0 error) *SaverCommitCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SaverCommitCall) Do(f func() error) *SaverCommitCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SaverCommitCall) DoAndReturn(f func() error) *SaverCommitCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// DeleteAll mocks base method. +func (m *MockSaver) DeleteAll(ctx context.Context, model any, level int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteAll", ctx, model, level) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteAll indicates an expected call of DeleteAll. +func (mr *MockSaverMockRecorder) DeleteAll(ctx, model, level any) *SaverDeleteAllCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAll", reflect.TypeOf((*MockSaver)(nil).DeleteAll), ctx, model, level) + return &SaverDeleteAllCall{Call: call} +} + +// SaverDeleteAllCall wrap *gomock.Call +type SaverDeleteAllCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SaverDeleteAllCall) Return(arg0 error) *SaverDeleteAllCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SaverDeleteAllCall) Do(f func(context.Context, any, int64) error) *SaverDeleteAllCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SaverDeleteAllCall) DoAndReturn(f func(context.Context, any, int64) error) *SaverDeleteAllCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// DeleteBigMapState mocks base method. +func (m *MockSaver) DeleteBigMapState(ctx context.Context, state bigmapdiff.BigMapState) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteBigMapState", ctx, state) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteBigMapState indicates an expected call of DeleteBigMapState. +func (mr *MockSaverMockRecorder) DeleteBigMapState(ctx, state any) *SaverDeleteBigMapStateCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteBigMapState", reflect.TypeOf((*MockSaver)(nil).DeleteBigMapState), ctx, state) + return &SaverDeleteBigMapStateCall{Call: call} +} + +// SaverDeleteBigMapStateCall wrap *gomock.Call +type SaverDeleteBigMapStateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SaverDeleteBigMapStateCall) Return(arg0 error) *SaverDeleteBigMapStateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SaverDeleteBigMapStateCall) Do(f func(context.Context, bigmapdiff.BigMapState) error) *SaverDeleteBigMapStateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SaverDeleteBigMapStateCall) DoAndReturn(f func(context.Context, bigmapdiff.BigMapState) error) *SaverDeleteBigMapStateCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// GetContractsLastAction mocks base method. +func (m *MockSaver) GetContractsLastAction(ctx context.Context, addressIds ...int64) ([]models.LastAction, error) { + m.ctrl.T.Helper() + varargs := []any{ctx} + for _, a := range addressIds { + varargs = append(varargs, a) + } + ret := m.ctrl.Call(m, "GetContractsLastAction", varargs...) + ret0, _ := ret[0].([]models.LastAction) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetContractsLastAction indicates an expected call of GetContractsLastAction. +func (mr *MockSaverMockRecorder) GetContractsLastAction(ctx any, addressIds ...any) *SaverGetContractsLastActionCall { + mr.mock.ctrl.T.Helper() + varargs := append([]any{ctx}, addressIds...) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContractsLastAction", reflect.TypeOf((*MockSaver)(nil).GetContractsLastAction), varargs...) + return &SaverGetContractsLastActionCall{Call: call} +} + +// SaverGetContractsLastActionCall wrap *gomock.Call +type SaverGetContractsLastActionCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SaverGetContractsLastActionCall) Return(arg0 []models.LastAction, arg1 error) *SaverGetContractsLastActionCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SaverGetContractsLastActionCall) Do(f func(context.Context, ...int64) ([]models.LastAction, error)) *SaverGetContractsLastActionCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SaverGetContractsLastActionCall) DoAndReturn(f func(context.Context, ...int64) ([]models.LastAction, error)) *SaverGetContractsLastActionCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// GetOperations mocks base method. +func (m *MockSaver) GetOperations(ctx context.Context, level int64) ([]operation.Operation, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetOperations", ctx, level) + ret0, _ := ret[0].([]operation.Operation) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetOperations indicates an expected call of GetOperations. +func (mr *MockSaverMockRecorder) GetOperations(ctx, level any) *SaverGetOperationsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetOperations", reflect.TypeOf((*MockSaver)(nil).GetOperations), ctx, level) + return &SaverGetOperationsCall{Call: call} +} + +// SaverGetOperationsCall wrap *gomock.Call +type SaverGetOperationsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SaverGetOperationsCall) Return(arg0 []operation.Operation, arg1 error) *SaverGetOperationsCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SaverGetOperationsCall) Do(f func(context.Context, int64) ([]operation.Operation, error)) *SaverGetOperationsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SaverGetOperationsCall) DoAndReturn(f func(context.Context, int64) ([]operation.Operation, error)) *SaverGetOperationsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// LastDiff mocks base method. +func (m *MockSaver) LastDiff(ctx context.Context, ptr int64, keyHash string, skipRemoved bool) (bigmapdiff.BigMapDiff, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "LastDiff", ctx, ptr, keyHash, skipRemoved) + ret0, _ := ret[0].(bigmapdiff.BigMapDiff) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// LastDiff indicates an expected call of LastDiff. +func (mr *MockSaverMockRecorder) LastDiff(ctx, ptr, keyHash, skipRemoved any) *SaverLastDiffCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "LastDiff", reflect.TypeOf((*MockSaver)(nil).LastDiff), ctx, ptr, keyHash, skipRemoved) + return &SaverLastDiffCall{Call: call} +} + +// SaverLastDiffCall wrap *gomock.Call +type SaverLastDiffCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SaverLastDiffCall) Return(arg0 bigmapdiff.BigMapDiff, arg1 error) *SaverLastDiffCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SaverLastDiffCall) Do(f func(context.Context, int64, string, bool) (bigmapdiff.BigMapDiff, error)) *SaverLastDiffCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SaverLastDiffCall) DoAndReturn(f func(context.Context, int64, string, bool) (bigmapdiff.BigMapDiff, error)) *SaverLastDiffCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// Rollback mocks base method. +func (m *MockSaver) Rollback() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Rollback") + ret0, _ := ret[0].(error) + return ret0 +} + +// Rollback indicates an expected call of Rollback. +func (mr *MockSaverMockRecorder) Rollback() *SaverRollbackCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Rollback", reflect.TypeOf((*MockSaver)(nil).Rollback)) + return &SaverRollbackCall{Call: call} +} + +// SaverRollbackCall wrap *gomock.Call +type SaverRollbackCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SaverRollbackCall) Return(arg0 error) *SaverRollbackCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SaverRollbackCall) Do(f func() error) *SaverRollbackCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SaverRollbackCall) DoAndReturn(f func() error) *SaverRollbackCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// SaveBigMapState mocks base method. +func (m *MockSaver) SaveBigMapState(ctx context.Context, state bigmapdiff.BigMapState) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SaveBigMapState", ctx, state) + ret0, _ := ret[0].(error) + return ret0 +} + +// SaveBigMapState indicates an expected call of SaveBigMapState. +func (mr *MockSaverMockRecorder) SaveBigMapState(ctx, state any) *SaverSaveBigMapStateCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SaveBigMapState", reflect.TypeOf((*MockSaver)(nil).SaveBigMapState), ctx, state) + return &SaverSaveBigMapStateCall{Call: call} +} + +// SaverSaveBigMapStateCall wrap *gomock.Call +type SaverSaveBigMapStateCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SaverSaveBigMapStateCall) Return(arg0 error) *SaverSaveBigMapStateCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SaverSaveBigMapStateCall) Do(f func(context.Context, bigmapdiff.BigMapState) error) *SaverSaveBigMapStateCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SaverSaveBigMapStateCall) DoAndReturn(f func(context.Context, bigmapdiff.BigMapState) error) *SaverSaveBigMapStateCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// StatesChangedAtLevel mocks base method. +func (m *MockSaver) StatesChangedAtLevel(ctx context.Context, level int64) ([]bigmapdiff.BigMapState, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "StatesChangedAtLevel", ctx, level) + ret0, _ := ret[0].([]bigmapdiff.BigMapState) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// StatesChangedAtLevel indicates an expected call of StatesChangedAtLevel. +func (mr *MockSaverMockRecorder) StatesChangedAtLevel(ctx, level any) *SaverStatesChangedAtLevelCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StatesChangedAtLevel", reflect.TypeOf((*MockSaver)(nil).StatesChangedAtLevel), ctx, level) + return &SaverStatesChangedAtLevelCall{Call: call} +} + +// SaverStatesChangedAtLevelCall wrap *gomock.Call +type SaverStatesChangedAtLevelCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SaverStatesChangedAtLevelCall) Return(arg0 []bigmapdiff.BigMapState, arg1 error) *SaverStatesChangedAtLevelCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SaverStatesChangedAtLevelCall) Do(f func(context.Context, int64) ([]bigmapdiff.BigMapState, error)) *SaverStatesChangedAtLevelCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SaverStatesChangedAtLevelCall) DoAndReturn(f func(context.Context, int64) ([]bigmapdiff.BigMapState, error)) *SaverStatesChangedAtLevelCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// UpdateContractStats mocks base method. +func (m *MockSaver) UpdateContractStats(ctx context.Context, accountId int64, lastAction time.Time, txCount int64) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateContractStats", ctx, accountId, lastAction, txCount) + ret0, _ := ret[0].(error) + return ret0 +} + +// UpdateContractStats indicates an expected call of UpdateContractStats. +func (mr *MockSaverMockRecorder) UpdateContractStats(ctx, accountId, lastAction, txCount any) *SaverUpdateContractStatsCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateContractStats", reflect.TypeOf((*MockSaver)(nil).UpdateContractStats), ctx, accountId, lastAction, txCount) + return &SaverUpdateContractStatsCall{Call: call} +} + +// SaverUpdateContractStatsCall wrap *gomock.Call +type SaverUpdateContractStatsCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *SaverUpdateContractStatsCall) Return(arg0 error) *SaverUpdateContractStatsCall { + c.Call = c.Call.Return(arg0) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *SaverUpdateContractStatsCall) Do(f func(context.Context, int64, time.Time, int64) error) *SaverUpdateContractStatsCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *SaverUpdateContractStatsCall) DoAndReturn(f func(context.Context, int64, time.Time, int64) error) *SaverUpdateContractStatsCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/internal/models/mock/smart_rollup/mock.go b/internal/models/mock/smart_rollup/mock.go index 0372bb762..62e0012f8 100644 --- a/internal/models/mock/smart_rollup/mock.go +++ b/internal/models/mock/smart_rollup/mock.go @@ -9,6 +9,7 @@ package smart_rollup import ( + context "context" reflect "reflect" smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" @@ -39,18 +40,18 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { } // Get mocks base method. -func (m *MockRepository) Get(address string) (smartrollup.SmartRollup, error) { +func (m *MockRepository) Get(ctx context.Context, address string) (smartrollup.SmartRollup, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", address) + ret := m.ctrl.Call(m, "Get", ctx, address) ret0, _ := ret[0].(smartrollup.SmartRollup) ret1, _ := ret[1].(error) return ret0, ret1 } // Get indicates an expected call of Get. -func (mr *MockRepositoryMockRecorder) Get(address any) *RepositoryGetCall { +func (mr *MockRepositoryMockRecorder) Get(ctx, address any) *RepositoryGetCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), address) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), ctx, address) return &RepositoryGetCall{Call: call} } @@ -66,30 +67,30 @@ func (c *RepositoryGetCall) Return(arg0 smartrollup.SmartRollup, arg1 error) *Re } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetCall) Do(f func(string) (smartrollup.SmartRollup, error)) *RepositoryGetCall { +func (c *RepositoryGetCall) Do(f func(context.Context, string) (smartrollup.SmartRollup, error)) *RepositoryGetCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetCall) DoAndReturn(f func(string) (smartrollup.SmartRollup, error)) *RepositoryGetCall { +func (c *RepositoryGetCall) DoAndReturn(f func(context.Context, string) (smartrollup.SmartRollup, error)) *RepositoryGetCall { c.Call = c.Call.DoAndReturn(f) return c } // List mocks base method. -func (m *MockRepository) List(limit, offset int64, sort string) ([]smartrollup.SmartRollup, error) { +func (m *MockRepository) List(ctx context.Context, limit, offset int64, sort string) ([]smartrollup.SmartRollup, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "List", limit, offset, sort) + ret := m.ctrl.Call(m, "List", ctx, limit, offset, sort) ret0, _ := ret[0].([]smartrollup.SmartRollup) ret1, _ := ret[1].(error) return ret0, ret1 } // List indicates an expected call of List. -func (mr *MockRepositoryMockRecorder) List(limit, offset, sort any) *RepositoryListCall { +func (mr *MockRepositoryMockRecorder) List(ctx, limit, offset, sort any) *RepositoryListCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockRepository)(nil).List), limit, offset, sort) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockRepository)(nil).List), ctx, limit, offset, sort) return &RepositoryListCall{Call: call} } @@ -105,13 +106,13 @@ func (c *RepositoryListCall) Return(arg0 []smartrollup.SmartRollup, arg1 error) } // Do rewrite *gomock.Call.Do -func (c *RepositoryListCall) Do(f func(int64, int64, string) ([]smartrollup.SmartRollup, error)) *RepositoryListCall { +func (c *RepositoryListCall) Do(f func(context.Context, int64, int64, string) ([]smartrollup.SmartRollup, error)) *RepositoryListCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryListCall) DoAndReturn(f func(int64, int64, string) ([]smartrollup.SmartRollup, error)) *RepositoryListCall { +func (c *RepositoryListCall) DoAndReturn(f func(context.Context, int64, int64, string) ([]smartrollup.SmartRollup, error)) *RepositoryListCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/internal/models/mock/stats/mock.go b/internal/models/mock/stats/mock.go new file mode 100644 index 000000000..2f3a940e4 --- /dev/null +++ b/internal/models/mock/stats/mock.go @@ -0,0 +1,79 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: repository.go +// +// Generated by this command: +// +// mockgen -source=repository.go -destination=../mock/stats/mock.go -package=stats -typed +// +// Package stats is a generated GoMock package. +package stats + +import ( + context "context" + reflect "reflect" + + stats "github.com/baking-bad/bcdhub/internal/models/stats" + gomock "go.uber.org/mock/gomock" +) + +// MockRepository is a mock of Repository interface. +type MockRepository struct { + ctrl *gomock.Controller + recorder *MockRepositoryMockRecorder +} + +// MockRepositoryMockRecorder is the mock recorder for MockRepository. +type MockRepositoryMockRecorder struct { + mock *MockRepository +} + +// NewMockRepository creates a new mock instance. +func NewMockRepository(ctrl *gomock.Controller) *MockRepository { + mock := &MockRepository{ctrl: ctrl} + mock.recorder = &MockRepositoryMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { + return m.recorder +} + +// Get mocks base method. +func (m *MockRepository) Get(ctx context.Context) (stats.Stats, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", ctx) + ret0, _ := ret[0].(stats.Stats) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get. +func (mr *MockRepositoryMockRecorder) Get(ctx any) *RepositoryGetCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), ctx) + return &RepositoryGetCall{Call: call} +} + +// RepositoryGetCall wrap *gomock.Call +type RepositoryGetCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RepositoryGetCall) Return(arg0 stats.Stats, arg1 error) *RepositoryGetCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RepositoryGetCall) Do(f func(context.Context) (stats.Stats, error)) *RepositoryGetCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RepositoryGetCall) DoAndReturn(f func(context.Context) (stats.Stats, error)) *RepositoryGetCall { + c.Call = c.Call.DoAndReturn(f) + return c +} diff --git a/internal/models/mock/ticket/mock.go b/internal/models/mock/ticket/mock.go index 52eaebc26..61be6d115 100644 --- a/internal/models/mock/ticket/mock.go +++ b/internal/models/mock/ticket/mock.go @@ -9,6 +9,7 @@ package ticket import ( + context "context" reflect "reflect" ticket "github.com/baking-bad/bcdhub/internal/models/ticket" @@ -38,119 +39,158 @@ func (m *MockRepository) EXPECT() *MockRepositoryMockRecorder { return m.recorder } -// ForOperation mocks base method. -func (m *MockRepository) ForOperation(operationId int64) ([]ticket.TicketUpdate, error) { +// BalancesForAccount mocks base method. +func (m *MockRepository) BalancesForAccount(ctx context.Context, accountId int64, req ticket.BalanceRequest) ([]ticket.Balance, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "ForOperation", operationId) - ret0, _ := ret[0].([]ticket.TicketUpdate) + ret := m.ctrl.Call(m, "BalancesForAccount", ctx, accountId, req) + ret0, _ := ret[0].([]ticket.Balance) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// BalancesForAccount indicates an expected call of BalancesForAccount. +func (mr *MockRepositoryMockRecorder) BalancesForAccount(ctx, accountId, req any) *RepositoryBalancesForAccountCall { + mr.mock.ctrl.T.Helper() + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BalancesForAccount", reflect.TypeOf((*MockRepository)(nil).BalancesForAccount), ctx, accountId, req) + return &RepositoryBalancesForAccountCall{Call: call} +} + +// RepositoryBalancesForAccountCall wrap *gomock.Call +type RepositoryBalancesForAccountCall struct { + *gomock.Call +} + +// Return rewrite *gomock.Call.Return +func (c *RepositoryBalancesForAccountCall) Return(arg0 []ticket.Balance, arg1 error) *RepositoryBalancesForAccountCall { + c.Call = c.Call.Return(arg0, arg1) + return c +} + +// Do rewrite *gomock.Call.Do +func (c *RepositoryBalancesForAccountCall) Do(f func(context.Context, int64, ticket.BalanceRequest) ([]ticket.Balance, error)) *RepositoryBalancesForAccountCall { + c.Call = c.Call.Do(f) + return c +} + +// DoAndReturn rewrite *gomock.Call.DoAndReturn +func (c *RepositoryBalancesForAccountCall) DoAndReturn(f func(context.Context, int64, ticket.BalanceRequest) ([]ticket.Balance, error)) *RepositoryBalancesForAccountCall { + c.Call = c.Call.DoAndReturn(f) + return c +} + +// List mocks base method. +func (m *MockRepository) List(ctx context.Context, ticketer string, limit, offset int64) ([]ticket.Ticket, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "List", ctx, ticketer, limit, offset) + ret0, _ := ret[0].([]ticket.Ticket) ret1, _ := ret[1].(error) return ret0, ret1 } -// ForOperation indicates an expected call of ForOperation. -func (mr *MockRepositoryMockRecorder) ForOperation(operationId any) *RepositoryForOperationCall { +// List indicates an expected call of List. +func (mr *MockRepositoryMockRecorder) List(ctx, ticketer, limit, offset any) *RepositoryListCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ForOperation", reflect.TypeOf((*MockRepository)(nil).ForOperation), operationId) - return &RepositoryForOperationCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "List", reflect.TypeOf((*MockRepository)(nil).List), ctx, ticketer, limit, offset) + return &RepositoryListCall{Call: call} } -// RepositoryForOperationCall wrap *gomock.Call -type RepositoryForOperationCall struct { +// RepositoryListCall wrap *gomock.Call +type RepositoryListCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *RepositoryForOperationCall) Return(arg0 []ticket.TicketUpdate, arg1 error) *RepositoryForOperationCall { +func (c *RepositoryListCall) Return(arg0 []ticket.Ticket, arg1 error) *RepositoryListCall { c.Call = c.Call.Return(arg0, arg1) return c } // Do rewrite *gomock.Call.Do -func (c *RepositoryForOperationCall) Do(f func(int64) ([]ticket.TicketUpdate, error)) *RepositoryForOperationCall { +func (c *RepositoryListCall) Do(f func(context.Context, string, int64, int64) ([]ticket.Ticket, error)) *RepositoryListCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryForOperationCall) DoAndReturn(f func(int64) ([]ticket.TicketUpdate, error)) *RepositoryForOperationCall { +func (c *RepositoryListCall) DoAndReturn(f func(context.Context, string, int64, int64) ([]ticket.Ticket, error)) *RepositoryListCall { c.Call = c.Call.DoAndReturn(f) return c } -// Get mocks base method. -func (m *MockRepository) Get(ticketer string, limit, offset int64) ([]ticket.TicketUpdate, error) { +// Updates mocks base method. +func (m *MockRepository) Updates(ctx context.Context, req ticket.UpdatesRequest) ([]ticket.TicketUpdate, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Get", ticketer, limit, offset) + ret := m.ctrl.Call(m, "Updates", ctx, req) ret0, _ := ret[0].([]ticket.TicketUpdate) ret1, _ := ret[1].(error) return ret0, ret1 } -// Get indicates an expected call of Get. -func (mr *MockRepositoryMockRecorder) Get(ticketer, limit, offset any) *RepositoryGetCall { +// Updates indicates an expected call of Updates. +func (mr *MockRepositoryMockRecorder) Updates(ctx, req any) *RepositoryUpdatesCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockRepository)(nil).Get), ticketer, limit, offset) - return &RepositoryGetCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Updates", reflect.TypeOf((*MockRepository)(nil).Updates), ctx, req) + return &RepositoryUpdatesCall{Call: call} } -// RepositoryGetCall wrap *gomock.Call -type RepositoryGetCall struct { +// RepositoryUpdatesCall wrap *gomock.Call +type RepositoryUpdatesCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *RepositoryGetCall) Return(arg0 []ticket.TicketUpdate, arg1 error) *RepositoryGetCall { +func (c *RepositoryUpdatesCall) Return(arg0 []ticket.TicketUpdate, arg1 error) *RepositoryUpdatesCall { c.Call = c.Call.Return(arg0, arg1) return c } // Do rewrite *gomock.Call.Do -func (c *RepositoryGetCall) Do(f func(string, int64, int64) ([]ticket.TicketUpdate, error)) *RepositoryGetCall { +func (c *RepositoryUpdatesCall) Do(f func(context.Context, ticket.UpdatesRequest) ([]ticket.TicketUpdate, error)) *RepositoryUpdatesCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryGetCall) DoAndReturn(f func(string, int64, int64) ([]ticket.TicketUpdate, error)) *RepositoryGetCall { +func (c *RepositoryUpdatesCall) DoAndReturn(f func(context.Context, ticket.UpdatesRequest) ([]ticket.TicketUpdate, error)) *RepositoryUpdatesCall { c.Call = c.Call.DoAndReturn(f) return c } -// Has mocks base method. -func (m *MockRepository) Has(contractID int64) (bool, error) { +// UpdatesForOperation mocks base method. +func (m *MockRepository) UpdatesForOperation(ctx context.Context, operationId int64) ([]ticket.TicketUpdate, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Has", contractID) - ret0, _ := ret[0].(bool) + ret := m.ctrl.Call(m, "UpdatesForOperation", ctx, operationId) + ret0, _ := ret[0].([]ticket.TicketUpdate) ret1, _ := ret[1].(error) return ret0, ret1 } -// Has indicates an expected call of Has. -func (mr *MockRepositoryMockRecorder) Has(contractID any) *RepositoryHasCall { +// UpdatesForOperation indicates an expected call of UpdatesForOperation. +func (mr *MockRepositoryMockRecorder) UpdatesForOperation(ctx, operationId any) *RepositoryUpdatesForOperationCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockRepository)(nil).Has), contractID) - return &RepositoryHasCall{Call: call} + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdatesForOperation", reflect.TypeOf((*MockRepository)(nil).UpdatesForOperation), ctx, operationId) + return &RepositoryUpdatesForOperationCall{Call: call} } -// RepositoryHasCall wrap *gomock.Call -type RepositoryHasCall struct { +// RepositoryUpdatesForOperationCall wrap *gomock.Call +type RepositoryUpdatesForOperationCall struct { *gomock.Call } // Return rewrite *gomock.Call.Return -func (c *RepositoryHasCall) Return(arg0 bool, arg1 error) *RepositoryHasCall { +func (c *RepositoryUpdatesForOperationCall) Return(arg0 []ticket.TicketUpdate, arg1 error) *RepositoryUpdatesForOperationCall { c.Call = c.Call.Return(arg0, arg1) return c } // Do rewrite *gomock.Call.Do -func (c *RepositoryHasCall) Do(f func(int64) (bool, error)) *RepositoryHasCall { +func (c *RepositoryUpdatesForOperationCall) Do(f func(context.Context, int64) ([]ticket.TicketUpdate, error)) *RepositoryUpdatesForOperationCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *RepositoryHasCall) DoAndReturn(f func(int64) (bool, error)) *RepositoryHasCall { +func (c *RepositoryUpdatesForOperationCall) DoAndReturn(f func(context.Context, int64) ([]ticket.TicketUpdate, error)) *RepositoryUpdatesForOperationCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/internal/models/model.go b/internal/models/model.go index f767855c6..12e37a1a3 100644 --- a/internal/models/model.go +++ b/internal/models/model.go @@ -1,33 +1,7 @@ package models -import ( - "github.com/baking-bad/bcdhub/internal/models/account" - "github.com/baking-bad/bcdhub/internal/models/bigmapaction" - "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" - "github.com/baking-bad/bcdhub/internal/models/block" - "github.com/baking-bad/bcdhub/internal/models/contract" - "github.com/baking-bad/bcdhub/internal/models/domains" - "github.com/baking-bad/bcdhub/internal/models/migration" - "github.com/baking-bad/bcdhub/internal/models/operation" - "github.com/baking-bad/bcdhub/internal/models/protocol" - smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" - "github.com/baking-bad/bcdhub/internal/models/ticket" - "github.com/go-pg/pg/v10" -) - -// Model - +//go:generate mockgen -source=$GOFILE -destination=mock/model.go -package=mock -typed type Model interface { GetID() int64 - GetIndex() string - Save(tx pg.DBI) error -} - -// Constraint - -type Constraint interface { - *account.Account | *bigmapaction.BigMapAction | *bigmapdiff.BigMapDiff | *bigmapdiff.BigMapState | - *block.Block | *contract.Contract | *contract.Script | *contract.GlobalConstant | *contract.ScriptConstants | - *migration.Migration | *operation.Operation | *protocol.Protocol | domains.BigMapDiff | - *ticket.TicketUpdate | *smartrollup.SmartRollup - - Model + TableName() string } diff --git a/internal/models/operation/model.go b/internal/models/operation/model.go index 7b53acc15..1285dad3a 100644 --- a/internal/models/operation/model.go +++ b/internal/models/operation/model.go @@ -13,65 +13,64 @@ import ( "github.com/baking-bad/bcdhub/internal/models/protocol" "github.com/baking-bad/bcdhub/internal/models/ticket" "github.com/baking-bad/bcdhub/internal/models/types" - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // Operation - type Operation struct { - // nolint - tableName struct{} `pg:"operations,partition_by:RANGE(timestamp)"` - - ID int64 `pg:",pk"` - ContentIndex int64 `pg:",use_zero"` - Level int64 `pg:",use_zero"` - Counter int64 `pg:",use_zero"` - Fee int64 `pg:",use_zero"` - GasLimit int64 `pg:",use_zero"` - StorageLimit int64 `pg:",use_zero"` - Amount int64 `pg:",use_zero"` - ConsumedGas int64 `pg:",use_zero"` - StorageSize int64 `pg:",use_zero"` - PaidStorageSizeDiff int64 `pg:",use_zero"` - Burned int64 `pg:",use_zero"` - AllocatedDestinationContractBurned int64 `pg:",use_zero"` - ProtocolID int64 `pg:",type:SMALLINT"` - TicketUpdatesCount int `pg:",use_zero"` - BigMapDiffsCount int `pg:",use_zero"` - Tags types.Tags `pg:",use_zero"` - Nonce *int64 + bun.BaseModel `bun:"operations"` + + ID int64 `bun:"id,pk,notnull,autoincrement"` + ContentIndex int64 + Level int64 + Counter int64 + Fee int64 + GasLimit int64 + StorageLimit int64 + Amount int64 + ConsumedGas int64 + StorageSize int64 + PaidStorageSizeDiff int64 + Burned int64 + AllocatedDestinationContractBurned int64 + ProtocolID int64 `bun:"protocol_id,type:SMALLINT"` + TicketUpdatesCount int + BigMapDiffsCount int + Tags types.Tags + Nonce *int64 `bun:"nonce,nullzero"` InitiatorID int64 - Initiator account.Account `pg:",rel:has-one"` + Initiator account.Account `bun:"rel:belongs-to"` SourceID int64 - Source account.Account `pg:",rel:has-one"` + Source account.Account `bun:"rel:belongs-to"` DestinationID int64 - Destination account.Account `pg:",rel:has-one"` + Destination account.Account `bun:"rel:belongs-to"` DelegateID int64 - Delegate account.Account `pg:",rel:has-one"` + Delegate account.Account `bun:"rel:belongs-to"` - Timestamp time.Time `pg:",pk,notnull"` - Status types.OperationStatus `pg:",type:SMALLINT"` - Kind types.OperationKind `pg:",type:SMALLINT"` + Timestamp time.Time `bun:"timestamp,pk,notnull"` + Status types.OperationStatus `bun:"status,type:SMALLINT"` + Kind types.OperationKind `bun:"kind,type:SMALLINT"` - Entrypoint types.NullString `pg:",type:text"` - Tag types.NullString `pg:",type:text"` + Entrypoint types.NullString `bun:"entrypoint,type:text"` + Tag types.NullString `bun:"tag,type:text"` Hash []byte Parameters []byte DeffatedStorage []byte Payload []byte PayloadType []byte - Script []byte `pg:"-"` + Script []byte `bun:"-"` - Errors tezerrors.Errors `pg:",type:bytea"` + Errors tezerrors.Errors `bun:"errors,type:bytea"` - AST *ast.Script `pg:"-"` + AST *ast.Script `bun:"-"` - BigMapDiffs []*bigmapdiff.BigMapDiff `pg:"rel:has-many"` - BigMapActions []*bigmapaction.BigMapAction `pg:"rel:has-many"` - TickerUpdates []*ticket.TicketUpdate `pg:"rel:has-many"` + BigMapDiffs []*bigmapdiff.BigMapDiff `bun:"rel:has-many"` + BigMapActions []*bigmapaction.BigMapAction `bun:"rel:has-many"` + TicketUpdates []*ticket.TicketUpdate `bun:"rel:has-many"` - AllocatedDestinationContract bool `pg:",use_zero"` - Internal bool `pg:",use_zero"` + AllocatedDestinationContract bool + Internal bool } // GetID - @@ -79,17 +78,10 @@ func (o *Operation) GetID() int64 { return o.ID } -// GetIndex - -func (o *Operation) GetIndex() string { +func (o *Operation) TableName() string { return "operations" } -// Save - -func (o *Operation) Save(tx pg.DBI) error { - _, err := tx.Model(o).Returning("id").Insert() - return err -} - // LogFields - func (o *Operation) LogFields() map[string]interface{} { return map[string]interface{}{ @@ -152,6 +144,12 @@ func (o *Operation) IsCall() bool { return (bcd.IsContract(o.Destination.Address) || bcd.IsSmartRollupHash(o.Destination.Address)) && len(o.Parameters) > 0 } +func (o *Operation) CanHasStorageDiff() bool { + return o.IsApplied() && + len(o.DeffatedStorage) > 0 && + (o.IsCall() || o.IsOrigination() || o.IsImplicit()) +} + // Result - type Result struct { Status string diff --git a/internal/models/operation/repository.go b/internal/models/operation/repository.go index e3c68567e..86436b10e 100644 --- a/internal/models/operation/repository.go +++ b/internal/models/operation/repository.go @@ -1,28 +1,16 @@ package operation import ( - "github.com/baking-bad/bcdhub/internal/models/account" + "context" ) //go:generate mockgen -source=$GOFILE -destination=../mock/operation/mock.go -package=operation -typed type Repository interface { - GetByAccount(acc account.Account, size uint64, filters map[string]interface{}) (Pageable, error) - // Last - get last operation by `filters` with not empty deffated_storage. - Last(filter map[string]interface{}, lastID int64) (Operation, error) - GetByHash(hash []byte) ([]Operation, error) - GetByHashAndCounter(hash []byte, counter int64) ([]Operation, error) - GetImplicitOperation(counter int64) (Operation, error) - OPG(address string, size, lastID int64) ([]OPG, error) - Origination(accountID int64) (Operation, error) - - // GetOperations - get operation by `filter`. `Size` - if 0 - return all, else certain `size` operations. - // `Sort` - sort by time and content index by desc - Get(filter map[string]interface{}, size int64, sort bool) ([]Operation, error) - - GetByIDs(ids ...int64) ([]Operation, error) - GetByID(id int64) (Operation, error) - - ListEvents(accountID int64, size, offset int64) ([]Operation, error) - EventsCount(accountID int64) (int, error) - ContractStats(address string) (ContractStats, error) + Last(ctx context.Context, filter map[string]interface{}, lastID int64) (Operation, error) + GetByHash(ctx context.Context, hash []byte) ([]Operation, error) + GetByHashAndCounter(ctx context.Context, hash []byte, counter int64) ([]Operation, error) + OPG(ctx context.Context, address string, size, lastID int64) ([]OPG, error) + Origination(ctx context.Context, accountID int64) (Operation, error) + GetByID(ctx context.Context, id int64) (Operation, error) + ListEvents(ctx context.Context, accountID int64, size, offset int64) ([]Operation, error) } diff --git a/internal/models/protocol/model.go b/internal/models/protocol/model.go index baa670afd..41fc35993 100644 --- a/internal/models/protocol/model.go +++ b/internal/models/protocol/model.go @@ -1,31 +1,30 @@ package protocol import ( - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // Protocol - type Protocol struct { - // nolint - tableName struct{} `pg:"protocols"` + bun.BaseModel `bun:"protocols"` - ID int64 + ID int64 `bun:"id,pk,notnull,autoincrement"` - Hash string `pg:",unique:protocol"` - StartLevel int64 `pg:",use_zero"` - EndLevel int64 `pg:",use_zero"` - SymLink string - Alias string - ChainID string + Hash string `bun:"hash,type:text,unique:protocol_hash_idx"` + StartLevel int64 + EndLevel int64 + SymLink string `bun:"sym_link,type:text"` + Alias string `bun:"alias,type:text"` + ChainID string `bun:"chain_id,type:text"` *Constants } // Constants - type Constants struct { - CostPerByte int64 `pg:",use_zero"` - HardGasLimitPerOperation int64 `pg:",use_zero"` - HardStorageLimitPerOperation int64 `pg:",use_zero"` - TimeBetweenBlocks int64 `pg:",use_zero"` + CostPerByte int64 + HardGasLimitPerOperation int64 + HardStorageLimitPerOperation int64 + TimeBetweenBlocks int64 } // GetID - @@ -33,20 +32,10 @@ func (p *Protocol) GetID() int64 { return p.ID } -// GetIndex - -func (p *Protocol) GetIndex() string { +func (Protocol) TableName() string { return "protocols" } -// Save - -func (p *Protocol) Save(tx pg.DBI) error { - _, err := tx.Model(p). - OnConflict("(hash) DO UPDATE"). - Set("end_level = ?", p.EndLevel). - Returning("id").Insert() - return err -} - // ValidateChainID - func (p *Protocol) ValidateChainID(chainID string) bool { if p.ChainID == "" { diff --git a/internal/models/protocol/repository.go b/internal/models/protocol/repository.go index 20bb3fa0d..93c8b6bc9 100644 --- a/internal/models/protocol/repository.go +++ b/internal/models/protocol/repository.go @@ -1,9 +1,9 @@ package protocol +import "context" + //go:generate mockgen -source=$GOFILE -destination=../mock/protocol/mock.go -package=protocol -typed type Repository interface { - Get(hash string, level int64) (Protocol, error) - GetAll() (response []Protocol, err error) - GetByNetworkWithSort(sortField, order string) (response []Protocol, err error) - GetByID(id int64) (response Protocol, err error) + Get(ctx context.Context, hash string, level int64) (Protocol, error) + GetByID(ctx context.Context, id int64) (response Protocol, err error) } diff --git a/internal/models/rollback.go b/internal/models/rollback.go new file mode 100644 index 000000000..536e3b869 --- /dev/null +++ b/internal/models/rollback.go @@ -0,0 +1,45 @@ +package models + +import ( + "context" + "time" + + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/contract" + "github.com/baking-bad/bcdhub/internal/models/migration" + "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/stats" + "github.com/baking-bad/bcdhub/internal/models/ticket" +) + +type LastAction struct { + AccountId int64 `bun:"address"` + Time time.Time `bun:"time"` +} + +//go:generate mockgen -source=$GOFILE -destination=mock/rollback.go -package=mock -typed +type Rollback interface { + DeleteAll(ctx context.Context, model any, level int64) (int, error) + StatesChangedAtLevel(ctx context.Context, level int64) ([]bigmapdiff.BigMapState, error) + DeleteBigMapState(ctx context.Context, state bigmapdiff.BigMapState) error + LastDiff(ctx context.Context, ptr int64, keyHash string, skipRemoved bool) (bigmapdiff.BigMapDiff, error) + SaveBigMapState(ctx context.Context, state bigmapdiff.BigMapState) error + GetOperations(ctx context.Context, level int64) ([]operation.Operation, error) + GetMigrations(ctx context.Context, level int64) ([]migration.Migration, error) + GetTicketUpdates(ctx context.Context, level int64) ([]ticket.TicketUpdate, error) + GetLastAction(ctx context.Context, addressIds ...int64) ([]LastAction, error) + UpdateAccountStats(ctx context.Context, account account.Account) error + UpdateTicket(ctx context.Context, ticket ticket.Ticket) error + GlobalConstants(ctx context.Context, level int64) ([]contract.GlobalConstant, error) + Scripts(ctx context.Context, level int64) ([]contract.Script, error) + DeleteScriptsConstants(ctx context.Context, scriptIds []int64, constantsIds []int64) error + Protocols(ctx context.Context, level int64) error + UpdateStats(ctx context.Context, stats stats.Stats) error + TicketBalances(ctx context.Context, balances ...*ticket.Balance) error + DeleteTickets(ctx context.Context, level int64) (ids []int64, err error) + DeleteTicketBalances(ctx context.Context, ticketIds []int64) (err error) + + Commit() error + Rollback() error +} diff --git a/internal/models/smart_rollup/model.go b/internal/models/smart_rollup/model.go index 951764298..61023a6be 100644 --- a/internal/models/smart_rollup/model.go +++ b/internal/models/smart_rollup/model.go @@ -4,26 +4,25 @@ import ( "time" "github.com/baking-bad/bcdhub/internal/models/account" - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // SmartRollup - entity for smart rollup type SmartRollup struct { - // nolint - tableName struct{} `pg:"smart_rollup"` + bun.BaseModel `bun:"smart_rollup"` - ID int64 + ID int64 `bun:"id,pk,notnull,autoincrement"` Level int64 Timestamp time.Time - Size uint64 `pg:",use_zero"` + Size uint64 AddressId int64 - Address account.Account `pg:",rel:has-one"` + Address account.Account `bun:",rel:belongs-to"` - GenesisCommitmentHash string - PvmKind string - Kernel []byte `pg:",type:bytea"` - Type []byte `pg:",type:bytea"` + GenesisCommitmentHash string `bun:"genesis_commitment_hash,type:text"` + PvmKind string `bun:"pvm_kind,type:text"` + Kernel []byte `bun:",type:bytea"` + Type []byte `bun:",type:bytea"` } // GetID - @@ -31,17 +30,10 @@ func (sr *SmartRollup) GetID() int64 { return sr.ID } -// GetIndex - -func (SmartRollup) GetIndex() string { +func (SmartRollup) TableName() string { return "smart_rollup" } -// Save - -func (sr *SmartRollup) Save(tx pg.DBI) error { - _, err := tx.Model(sr).OnConflict("DO NOTHING").Returning("id").Insert() - return err -} - // LogFields - func (sr *SmartRollup) LogFields() map[string]interface{} { return map[string]interface{}{ diff --git a/internal/models/smart_rollup/repository.go b/internal/models/smart_rollup/repository.go index 280b09f41..7573aed02 100644 --- a/internal/models/smart_rollup/repository.go +++ b/internal/models/smart_rollup/repository.go @@ -1,7 +1,9 @@ package smartrollup +import "context" + //go:generate mockgen -source=$GOFILE -destination=../mock/smart_rollup/mock.go -package=smart_rollup -typed type Repository interface { - Get(address string) (SmartRollup, error) - List(limit, offset int64, sort string) ([]SmartRollup, error) + Get(ctx context.Context, address string) (SmartRollup, error) + List(ctx context.Context, limit, offset int64, sort string) ([]SmartRollup, error) } diff --git a/internal/models/stats/model.go b/internal/models/stats/model.go new file mode 100644 index 000000000..5c2a76f9c --- /dev/null +++ b/internal/models/stats/model.go @@ -0,0 +1,32 @@ +package stats + +import ( + "github.com/uptrace/bun" +) + +// Stats - entity for blockchain general stats +type Stats struct { + bun.BaseModel `bun:"stats"` + + ID int64 `bun:"id,pk,notnull,autoincrement"` + ContractsCount int `bun:"contracts_count"` + SmartRollupsCount int `bun:"smart_rollups_count"` + GlobalConstantsCount int `bun:"global_constants_count"` + OperationsCount int `bun:"operations_count"` + EventsCount int `bun:"events_count"` + TransactionsCount int `bun:"tx_count"` + OriginationsCount int `bun:"originations_count"` + SrOriginationsCount int `bun:"sr_originations_count"` + SrExecutesCount int `bun:"sr_executes_count"` + RegisterGlobalConstantCount int `bun:"register_global_constants_count"` + TransferTicketsCount int `bun:"transfer_tickets_count"` +} + +// GetID - +func (sr *Stats) GetID() int64 { + return sr.ID +} + +func (Stats) TableName() string { + return "stats" +} diff --git a/internal/models/stats/repository.go b/internal/models/stats/repository.go new file mode 100644 index 000000000..425a76ebe --- /dev/null +++ b/internal/models/stats/repository.go @@ -0,0 +1,8 @@ +package stats + +import "context" + +//go:generate mockgen -source=$GOFILE -destination=../mock/stats/mock.go -package=stats -typed +type Repository interface { + Get(ctx context.Context) (Stats, error) +} diff --git a/internal/models/ticket/balance.go b/internal/models/ticket/balance.go new file mode 100644 index 000000000..aea09ae98 --- /dev/null +++ b/internal/models/ticket/balance.go @@ -0,0 +1,41 @@ +package ticket + +import ( + "fmt" + + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/shopspring/decimal" + "github.com/uptrace/bun" +) + +type Balance struct { + bun.BaseModel `bun:"ticket_balances"` + + TicketId int64 `bun:"ticket_id,pk,notnull"` + AccountId int64 `bun:"account_id,pk,notnull"` + Amount decimal.Decimal `bun:"amount,type:numeric(200,0)"` + + Ticket Ticket `bun:"rel:belongs-to"` + Account account.Account `bun:"rel:belongs-to"` +} + +func (Balance) GetID() int64 { + return 0 +} + +func (Balance) TableName() string { + return "ticket_balances" +} + +// LogFields - +func (b Balance) LogFields() map[string]interface{} { + return map[string]interface{}{ + "ticket_id": b.TicketId, + "account_id": b.AccountId, + "amount": b.Amount.String(), + } +} + +func (b Balance) String() string { + return fmt.Sprintf("%d_%d", b.TicketId, b.AccountId) +} diff --git a/internal/models/ticket/model.go b/internal/models/ticket/model.go deleted file mode 100644 index 6dbed4c87..000000000 --- a/internal/models/ticket/model.go +++ /dev/null @@ -1,52 +0,0 @@ -package ticket - -import ( - "time" - - "github.com/baking-bad/bcdhub/internal/models/account" - "github.com/go-pg/pg/v10" - "github.com/shopspring/decimal" -) - -// TicketUpdate - -type TicketUpdate struct { - // nolint - tableName struct{} `pg:"ticket_updates"` - - ID int64 - OperationID int64 - Level int64 `pg:",use_zero"` - Timestamp time.Time - TicketerID int64 - Ticketer account.Account `pg:",rel:has-one"` - ContentType []byte - Content []byte - AccountID int64 - Account account.Account `pg:",rel:has-one"` - Amount decimal.Decimal `pg:",type:numeric(200,0),use_zero"` -} - -// GetID - -func (t *TicketUpdate) GetID() int64 { - return t.ID -} - -// GetIndex - -func (t *TicketUpdate) GetIndex() string { - return "ticket_updates" -} - -// Save - -func (t *TicketUpdate) Save(tx pg.DBI) error { - _, err := tx.Model(t).Returning("id").Insert() - return err -} - -// LogFields - -func (t *TicketUpdate) LogFields() map[string]interface{} { - return map[string]interface{}{ - "id": t.ID, - "block": t.Level, - "ticketer_id": t.TicketerID, - } -} diff --git a/internal/models/ticket/repository.go b/internal/models/ticket/repository.go index 1630f68f0..a3372e4e9 100644 --- a/internal/models/ticket/repository.go +++ b/internal/models/ticket/repository.go @@ -1,8 +1,25 @@ package ticket +import "context" + +type BalanceRequest struct { + Limit int64 + Offset int64 + WithoutZeroBalances bool +} + +type UpdatesRequest struct { + Account string + Ticketer string + TicketId *uint64 + Limit int64 + Offset int64 +} + //go:generate mockgen -source=$GOFILE -destination=../mock/ticket/mock.go -package=ticket -typed type Repository interface { - Get(ticketer string, limit, offset int64) ([]TicketUpdate, error) - Has(contractID int64) (bool, error) - ForOperation(operationId int64) ([]TicketUpdate, error) + List(ctx context.Context, ticketer string, limit, offset int64) ([]Ticket, error) + Updates(ctx context.Context, req UpdatesRequest) ([]TicketUpdate, error) + UpdatesForOperation(ctx context.Context, operationId int64) ([]TicketUpdate, error) + BalancesForAccount(ctx context.Context, accountId int64, req BalanceRequest) ([]Balance, error) } diff --git a/internal/models/ticket/ticket.go b/internal/models/ticket/ticket.go new file mode 100644 index 000000000..9c56cb885 --- /dev/null +++ b/internal/models/ticket/ticket.go @@ -0,0 +1,49 @@ +package ticket + +import ( + "crypto/sha256" + "encoding/hex" + + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/uptrace/bun" +) + +type Ticket struct { + bun.BaseModel `bun:"tickets"` + + ID int64 `bun:"id,pk,notnull,autoincrement"` + Level int64 `bun:"level"` + TicketerID int64 `bun:"ticketer_id,unique:ticket_key"` + ContentType []byte `bun:"content_type,type:bytea,unique:ticket_key"` + Content []byte `bun:"content,type:bytea,unique:ticket_key"` + UpdatesCount int `bun:"updates_count"` + + Ticketer account.Account `bun:"rel:belongs-to"` +} + +func (t Ticket) GetID() int64 { + return t.ID +} + +func (Ticket) TableName() string { + return "tickets" +} + +func (t Ticket) Hash() string { + data := make([]byte, len(t.ContentType)) + copy(data, t.ContentType) + data = append(data, t.Content...) + data = append(data, []byte(t.Ticketer.Address)...) + h := sha256.New() + _, _ = h.Write(data) + return hex.EncodeToString(h.Sum(nil)) +} + +// LogFields - +func (t Ticket) LogFields() map[string]interface{} { + return map[string]interface{}{ + "ticketer_id": t.TicketerID, + "content": string(t.Content), + "content_type": string(t.ContentType), + } +} diff --git a/internal/models/ticket/ticket_test.go b/internal/models/ticket/ticket_test.go new file mode 100644 index 000000000..28b036ade --- /dev/null +++ b/internal/models/ticket/ticket_test.go @@ -0,0 +1,46 @@ +package ticket + +import ( + "testing" + + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/stretchr/testify/require" +) + +func TestTicket_Hash(t *testing.T) { + tests := []struct { + name string + t Ticket + want string + }{ + { + name: "test 1", + t: Ticket{ + TicketerID: 1, + Ticketer: account.Account{ + Address: "address1", + }, + ContentType: []byte(`{}`), + Content: []byte(`{}`), + }, + want: "49e3556aeeb72ede783c3a975bb10d8d19e14f0ab6b9d481de9f5ebeb0861a54", + }, { + name: "test 2", + t: Ticket{ + TicketerID: 2, + Ticketer: account.Account{ + Address: "address2", + }, + ContentType: []byte(`{}`), + Content: []byte(`{}`), + }, + want: "bcb6d6dc0d03d874520f0948f127a421eafe27a97950e39a118a03179dfce460", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := tt.t.Hash() + require.Equal(t, tt.want, got) + }) + } +} diff --git a/internal/models/ticket/update.go b/internal/models/ticket/update.go new file mode 100644 index 000000000..4d67add16 --- /dev/null +++ b/internal/models/ticket/update.go @@ -0,0 +1,43 @@ +package ticket + +import ( + "time" + + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/shopspring/decimal" + "github.com/uptrace/bun" +) + +// TicketUpdate - +type TicketUpdate struct { + bun.BaseModel `bun:"ticket_updates"` + + ID int64 `bun:"id,pk,notnull,autoincrement"` + Timestamp time.Time `bun:"timestamp,pk,notnull"` + OperationId int64 `bun:"operation_id"` + Level int64 `bun:"level"` + TicketId int64 `bun:"ticket_id"` + AccountId int64 `bun:"account_id"` + Amount decimal.Decimal `bun:"amount,type:numeric(200,0)"` + + Account account.Account `bun:"rel:belongs-to"` + Ticket Ticket `bun:"rel:belongs-to"` +} + +// GetID - +func (t *TicketUpdate) GetID() int64 { + return t.ID +} + +func (TicketUpdate) TableName() string { + return "ticket_updates" +} + +// LogFields - +func (t *TicketUpdate) LogFields() map[string]interface{} { + return map[string]interface{}{ + "id": t.ID, + "block": t.Level, + "ticket_id": t.TicketId, + } +} diff --git a/internal/models/types/null.go b/internal/models/types/null.go index e6f12ddd9..342879a1f 100644 --- a/internal/models/types/null.go +++ b/internal/models/types/null.go @@ -1,6 +1,8 @@ package types -import "database/sql/driver" +import ( + "database/sql/driver" +) // NullString represents a string that may be null. // NullString implements the Scanner interface so @@ -47,9 +49,13 @@ func (ns *NullString) Scan(value interface{}) error { return nil } - if val, ok := value.([]byte); ok { + switch val := value.(type) { + case string: + ns.Str, ns.Valid = val, true + case []byte: ns.Str, ns.Valid = string(val), true } + return nil } diff --git a/internal/noderpc/rpc.go b/internal/noderpc/rpc.go index 9150b3716..8fa8acbc8 100644 --- a/internal/noderpc/rpc.go +++ b/internal/noderpc/rpc.go @@ -12,9 +12,9 @@ import ( "time" "github.com/baking-bad/bcdhub/internal/helpers" - "github.com/baking-bad/bcdhub/internal/logger" jsoniter "github.com/json-iterator/go" "github.com/pkg/errors" + "github.com/rs/zerolog/log" "golang.org/x/time/rate" ) @@ -80,7 +80,7 @@ func NewWaitNodeRPC(baseURL string, opts ...NodeOption) *NodeRPC { break } - logger.Warning().Msgf("Waiting node %s up 30 second...", baseURL) + log.Warn().Msgf("Waiting node %s up 30 second...", baseURL) time.Sleep(time.Second * 30) } return node @@ -99,9 +99,7 @@ func (rpc *NodeRPC) checkStatusCode(r io.Reader, statusCode int, checkStatusCode return err } invalidResponseErr.Raw = data - if err := json.Unmarshal(data, &invalidResponseErr.Errors); err != nil { - return errors.Wrap(invalidResponseErr, err.Error()) - } + _ = json.Unmarshal(data, &invalidResponseErr.Errors) return invalidResponseErr default: return nil @@ -155,7 +153,7 @@ func (rpc *NodeRPC) get(ctx context.Context, uri string, response interface{}) e start := time.Now() defer func() { if rpc.needLog { - logger.Info().Str("method", "get").Int64("ms", time.Since(start).Milliseconds()).Msg(uri) + log.Info().Str("method", "get").Int64("ms", time.Since(start).Milliseconds()).Msg(uri) } }() @@ -183,7 +181,7 @@ func (rpc *NodeRPC) getRaw(ctx context.Context, uri string) ([]byte, error) { start := time.Now() defer func() { if rpc.needLog { - logger.Info().Str("method", "get").Int64("ms", time.Since(start).Milliseconds()).Msg(uri) + log.Info().Str("method", "get").Int64("ms", time.Since(start).Milliseconds()).Msg(uri) } }() @@ -209,7 +207,7 @@ func (rpc *NodeRPC) post(ctx context.Context, uri string, data interface{}, chec start := time.Now() defer func() { if rpc.needLog { - logger.Info().Str("method", "post").Int64("ms", time.Since(start).Milliseconds()).Msg(uri) + log.Info().Str("method", "post").Int64("ms", time.Since(start).Milliseconds()).Msg(uri) } }() diff --git a/internal/noderpc/rpc_test.go b/internal/noderpc/rpc_test.go new file mode 100644 index 000000000..f8898f3b0 --- /dev/null +++ b/internal/noderpc/rpc_test.go @@ -0,0 +1,66 @@ +package noderpc + +import ( + "io" + "strings" + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNodeRPC_checkStatusCode(t *testing.T) { + tests := []struct { + name string + r io.Reader + statusCode int + checkStatusCode bool + wantErr bool + errString string + }{ + { + name: "404 error", + r: strings.NewReader("404 page not found"), + statusCode: 400, + checkStatusCode: true, + wantErr: true, + errString: "404 page not found", + }, { + name: "200", + r: strings.NewReader(""), + statusCode: 200, + checkStatusCode: true, + wantErr: false, + }, { + name: "501", + r: strings.NewReader("node unavailiable"), + statusCode: 501, + checkStatusCode: true, + wantErr: true, + errString: "is unavailiable: 501", + }, { + name: "no checking", + r: strings.NewReader("node unavailiable"), + statusCode: 400, + checkStatusCode: false, + wantErr: false, + errString: "", + }, { + name: "501 with no checking", + r: strings.NewReader("node unavailiable"), + statusCode: 501, + checkStatusCode: false, + wantErr: true, + errString: "is unavailiable: 501", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + rpc := new(NodeRPC) + err := rpc.checkStatusCode(tt.r, tt.statusCode, tt.checkStatusCode) + require.Equal(t, tt.wantErr, err != nil) + if err != nil { + require.ErrorContains(t, err, tt.errString) + } + }) + } +} diff --git a/internal/parsers/contract/alpha.go b/internal/parsers/contract/alpha.go index d47e49310..fdddf4029 100644 --- a/internal/parsers/contract/alpha.go +++ b/internal/parsers/contract/alpha.go @@ -1,6 +1,7 @@ package contract import ( + "context" "encoding/json" "github.com/baking-bad/bcdhub/internal/bcd" @@ -24,21 +25,20 @@ func NewAlpha(ctx *config.Context) *Alpha { } // Parse - -func (p *Alpha) Parse(operation *operation.Operation, store parsers.Store) error { +func (p *Alpha) Parse(ctx context.Context, operation *operation.Operation, store parsers.Store) error { if !operation.IsOrigination() { - return errors.Errorf("invalid operation kind in computeContractMetrics: %s", operation.Kind) + return errors.Errorf("invalid operation kind in alpha.parse: %s", operation.Kind) } contract := contract.Contract{ - Level: operation.Level, - Timestamp: operation.Timestamp, - Manager: operation.Source, - Account: operation.Destination, - Delegate: operation.Delegate, - LastAction: operation.Timestamp, + Level: operation.Level, + Timestamp: operation.Timestamp, + Manager: operation.Source, + Account: operation.Destination, + Delegate: operation.Delegate, } - if err := p.computeMetrics(operation, &contract); err != nil { + if err := p.computeMetrics(ctx, operation, &contract); err != nil { return err } @@ -46,14 +46,14 @@ func (p *Alpha) Parse(operation *operation.Operation, store parsers.Store) error return nil } -func (p *Alpha) computeMetrics(operation *operation.Operation, c *contract.Contract) error { +func (p *Alpha) computeMetrics(ctx context.Context, operation *operation.Operation, c *contract.Contract) error { script, err := astContract.NewParser(operation.Script) if err != nil { return errors.Wrap(err, "astContract.NewParser") } operation.AST = script.Code - contractScript, err := p.ctx.Scripts.ByHash(script.Hash) + contractScript, err := p.ctx.Scripts.ByHash(ctx, script.Hash) if err != nil { if !p.ctx.Storage.IsRecordNotFound(err) { return err @@ -83,6 +83,7 @@ func (p *Alpha) computeMetrics(operation *operation.Operation, c *contract.Contr contractScript.Tags = types.NewTags(script.Tags.Values()) contractScript.Hardcoded = script.HardcodedAddresses.Values() contractScript.Entrypoints = params.GetEntrypoints() + contractScript.Level = operation.Level c.Alpha = contractScript } else { diff --git a/internal/parsers/contract/babylon.go b/internal/parsers/contract/babylon.go index b052fa3e7..278e3c97c 100644 --- a/internal/parsers/contract/babylon.go +++ b/internal/parsers/contract/babylon.go @@ -1,6 +1,7 @@ package contract import ( + "context" "encoding/json" "github.com/baking-bad/bcdhub/internal/bcd" @@ -24,21 +25,20 @@ func NewBabylon(ctx *config.Context) *Babylon { } // Parse - -func (p *Babylon) Parse(operation *operation.Operation, store parsers.Store) error { +func (p *Babylon) Parse(ctx context.Context, operation *operation.Operation, store parsers.Store) error { if !operation.IsOrigination() { - return errors.Errorf("invalid operation kind in computeContractMetrics: %s", operation.Kind) + return errors.Errorf("invalid operation kind in babylon.parse: %s", operation.Kind) } contract := contract.Contract{ - Level: operation.Level, - Timestamp: operation.Timestamp, - Manager: operation.Source, - Account: operation.Destination, - Delegate: operation.Delegate, - LastAction: operation.Timestamp, + Level: operation.Level, + Timestamp: operation.Timestamp, + Manager: operation.Source, + Account: operation.Destination, + Delegate: operation.Delegate, } - if err := p.computeMetrics(operation, &contract); err != nil { + if err := p.computeMetrics(ctx, operation, &contract); err != nil { return err } @@ -46,14 +46,14 @@ func (p *Babylon) Parse(operation *operation.Operation, store parsers.Store) err return nil } -func (p *Babylon) computeMetrics(operation *operation.Operation, c *contract.Contract) error { +func (p *Babylon) computeMetrics(ctx context.Context, operation *operation.Operation, c *contract.Contract) error { script, err := astContract.NewParser(operation.Script) if err != nil { return errors.Wrap(err, "astContract.NewParser") } operation.AST = script.Code - contractScript, err := p.ctx.Scripts.ByHash(script.Hash) + contractScript, err := p.ctx.Scripts.ByHash(ctx, script.Hash) if err != nil { if !p.ctx.Storage.IsRecordNotFound(err) { return err @@ -83,6 +83,7 @@ func (p *Babylon) computeMetrics(operation *operation.Operation, c *contract.Con contractScript.Tags = types.NewTags(script.Tags.Values()) contractScript.Hardcoded = script.HardcodedAddresses.Values() contractScript.Entrypoints = params.GetEntrypoints() + contractScript.Level = operation.Level c.Babylon = contractScript } else { diff --git a/internal/parsers/contract/hangzhou.go b/internal/parsers/contract/hangzhou.go index 4339c1f94..73336c8ee 100644 --- a/internal/parsers/contract/hangzhou.go +++ b/internal/parsers/contract/hangzhou.go @@ -1,6 +1,7 @@ package contract import ( + "context" "encoding/json" "github.com/baking-bad/bcdhub/internal/bcd" @@ -24,21 +25,20 @@ func NewHangzhou(ctx *config.Context) *Hangzhou { } // Parse - -func (p *Hangzhou) Parse(operation *operation.Operation, store parsers.Store) error { +func (p *Hangzhou) Parse(ctx context.Context, operation *operation.Operation, store parsers.Store) error { if !operation.IsOrigination() { - return errors.Errorf("invalid operation kind in computeContractMetrics: %s", operation.Kind) + return errors.Errorf("invalid operation kind in hangzhou.parse: %s", operation.Kind) } contract := contract.Contract{ - Level: operation.Level, - Timestamp: operation.Timestamp, - Manager: operation.Source, - Account: operation.Destination, - Delegate: operation.Delegate, - LastAction: operation.Timestamp, + Level: operation.Level, + Timestamp: operation.Timestamp, + Manager: operation.Source, + Account: operation.Destination, + Delegate: operation.Delegate, } - if err := p.computeMetrics(operation, &contract); err != nil { + if err := p.computeMetrics(ctx, operation, &contract); err != nil { return err } @@ -46,8 +46,8 @@ func (p *Hangzhou) Parse(operation *operation.Operation, store parsers.Store) er return nil } -func (p *Hangzhou) computeMetrics(operation *operation.Operation, c *contract.Contract) error { - constants, err := getGlobalConstants(p.ctx.GlobalConstants, operation) +func (p *Hangzhou) computeMetrics(ctx context.Context, operation *operation.Operation, c *contract.Contract) error { + constants, err := getGlobalConstants(ctx, p.ctx.GlobalConstants, operation) if err != nil { return errors.Wrap(err, "getGlobalConstants") } @@ -58,7 +58,7 @@ func (p *Hangzhou) computeMetrics(operation *operation.Operation, c *contract.Co } operation.AST = script.Code - contractScript, err := p.ctx.Scripts.ByHash(script.Hash) + contractScript, err := p.ctx.Scripts.ByHash(ctx, script.Hash) if err != nil { if !p.ctx.Storage.IsRecordNotFound(err) { return err @@ -89,6 +89,7 @@ func (p *Hangzhou) computeMetrics(operation *operation.Operation, c *contract.Co contractScript.Hardcoded = script.HardcodedAddresses.Values() contractScript.Entrypoints = params.GetEntrypoints() contractScript.Constants = constants + contractScript.Level = operation.Level c.Babylon = contractScript } else { diff --git a/internal/parsers/contract/jakarta.go b/internal/parsers/contract/jakarta.go index 1703e9dc9..3c09d1fd2 100644 --- a/internal/parsers/contract/jakarta.go +++ b/internal/parsers/contract/jakarta.go @@ -2,6 +2,7 @@ package contract import ( "bytes" + "context" "encoding/json" "fmt" @@ -28,21 +29,20 @@ func NewJakarta(ctx *config.Context) *Jakarta { } // Parse - -func (p *Jakarta) Parse(operation *operation.Operation, store parsers.Store) error { +func (p *Jakarta) Parse(ctx context.Context, operation *operation.Operation, store parsers.Store) error { if !operation.IsOrigination() { - return errors.Errorf("invalid operation kind in computeContractMetrics: %s", operation.Kind) + return errors.Errorf("invalid operation kind in jakarta.parse: %s", operation.Kind) } contract := contract.Contract{ - Level: operation.Level, - Timestamp: operation.Timestamp, - Manager: operation.Source, - Account: operation.Destination, - Delegate: operation.Delegate, - LastAction: operation.Timestamp, + Level: operation.Level, + Timestamp: operation.Timestamp, + Manager: operation.Source, + Account: operation.Destination, + Delegate: operation.Delegate, } - if err := p.computeMetrics(operation, &contract); err != nil { + if err := p.computeMetrics(ctx, operation, &contract); err != nil { return err } @@ -50,8 +50,8 @@ func (p *Jakarta) Parse(operation *operation.Operation, store parsers.Store) err return nil } -func (p *Jakarta) computeMetrics(operation *operation.Operation, c *contract.Contract) error { - constants, err := getGlobalConstants(p.ctx.GlobalConstants, operation) +func (p *Jakarta) computeMetrics(ctx context.Context, operation *operation.Operation, c *contract.Contract) error { + constants, err := getGlobalConstants(ctx, p.ctx.GlobalConstants, operation) if err != nil { return errors.Wrap(err, "getGlobalConstants") } @@ -62,7 +62,7 @@ func (p *Jakarta) computeMetrics(operation *operation.Operation, c *contract.Con } operation.AST = script.Code - contractScript, err := p.ctx.Scripts.ByHash(script.Hash) + contractScript, err := p.ctx.Scripts.ByHash(ctx, script.Hash) if err != nil { if !p.ctx.Storage.IsRecordNotFound(err) { return err @@ -93,6 +93,7 @@ func (p *Jakarta) computeMetrics(operation *operation.Operation, c *contract.Con contractScript.Hardcoded = script.HardcodedAddresses.Values() contractScript.Entrypoints = params.GetEntrypoints() contractScript.Constants = constants + contractScript.Level = operation.Level c.Jakarta = contractScript } else { @@ -116,7 +117,7 @@ func replaceConstants(constants []contract.GlobalConstant, operation *operation. } } -func getGlobalConstants(repo contract.ConstantRepository, operation *operation.Operation) ([]contract.GlobalConstant, error) { +func getGlobalConstants(ctx context.Context, repo contract.ConstantRepository, operation *operation.Operation) ([]contract.GlobalConstant, error) { var cd astContract.ContractData if err := json.Unmarshal(operation.Script, &cd); err != nil { return nil, err @@ -144,7 +145,7 @@ func getGlobalConstants(repo contract.ConstantRepository, operation *operation.O } } - entities, err := repo.All(addresses...) + entities, err := repo.All(ctx, addresses...) if err != nil { return nil, err } diff --git a/internal/parsers/contract/parser.go b/internal/parsers/contract/parser.go index ebb12b003..24ce399e7 100644 --- a/internal/parsers/contract/parser.go +++ b/internal/parsers/contract/parser.go @@ -1,11 +1,13 @@ package contract import ( + "context" + "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/parsers" ) // Parser - type Parser interface { - Parse(operation *operation.Operation, store parsers.Store) error + Parse(ctx context.Context, operation *operation.Operation, store parsers.Store) error } diff --git a/internal/parsers/migrations/alpha.go b/internal/parsers/migrations/alpha.go index cfe4d7a21..672801108 100644 --- a/internal/parsers/migrations/alpha.go +++ b/internal/parsers/migrations/alpha.go @@ -2,17 +2,18 @@ package migrations import ( "bytes" + "context" "encoding/json" "time" "github.com/baking-bad/bcdhub/internal/bcd" "github.com/baking-bad/bcdhub/internal/bcd/contract" + "github.com/baking-bad/bcdhub/internal/models" modelsContract "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/migration" "github.com/baking-bad/bcdhub/internal/models/protocol" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" - "github.com/go-pg/pg/v10" ) // Alpha - @@ -24,7 +25,7 @@ func NewAlpha() *Alpha { } // Parse - -func (p *Alpha) Parse(script noderpc.Script, old *modelsContract.Contract, previous, next protocol.Protocol, timestamp time.Time, tx pg.DBI) error { +func (p *Alpha) Parse(ctx context.Context, script noderpc.Script, old *modelsContract.Contract, previous, next protocol.Protocol, timestamp time.Time, tx models.Transaction) error { codeBytes, err := json.Marshal(script.Code) if err != nil { return err @@ -46,6 +47,7 @@ func (p *Alpha) Parse(script noderpc.Script, old *modelsContract.Contract, previ } contractScript := modelsContract.Script{ + Level: next.StartLevel, Hash: newHash, Code: s.Code, Storage: s.Storage, @@ -53,7 +55,7 @@ func (p *Alpha) Parse(script noderpc.Script, old *modelsContract.Contract, previ Views: s.Views, } - if err := contractScript.Save(tx); err != nil { + if err := tx.Scripts(ctx, &contractScript); err != nil { return err } @@ -61,14 +63,15 @@ func (p *Alpha) Parse(script noderpc.Script, old *modelsContract.Contract, previ m := &migration.Migration{ ContractID: old.ID, - Level: previous.EndLevel, + Contract: *old, + Level: next.StartLevel, ProtocolID: next.ID, PrevProtocolID: previous.ID, Timestamp: timestamp, Kind: types.MigrationKindUpdate, } - return m.Save(tx) + return tx.Migrations(ctx, m) } // IsMigratable - diff --git a/internal/parsers/migrations/babylon.go b/internal/parsers/migrations/babylon.go index ac2098db7..92f00677c 100644 --- a/internal/parsers/migrations/babylon.go +++ b/internal/parsers/migrations/babylon.go @@ -2,35 +2,31 @@ package migrations import ( "bytes" + "context" "encoding/json" "time" "github.com/baking-bad/bcdhub/internal/bcd" "github.com/baking-bad/bcdhub/internal/bcd/contract" - "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models" modelsContract "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/migration" "github.com/baking-bad/bcdhub/internal/models/protocol" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" - "github.com/go-pg/pg/v10" ) // Babylon - -type Babylon struct { - bmdRepo bigmapdiff.Repository -} +type Babylon struct{} // NewBabylon - -func NewBabylon(bmdRepo bigmapdiff.Repository) *Babylon { - return &Babylon{ - bmdRepo: bmdRepo, - } +func NewBabylon() *Babylon { + return &Babylon{} } // Parse - -func (p *Babylon) Parse(script noderpc.Script, old *modelsContract.Contract, previous, next protocol.Protocol, timestamp time.Time, tx pg.DBI) error { - if err := p.getUpdates(script, *old, tx); err != nil { +func (p *Babylon) Parse(ctx context.Context, script noderpc.Script, old *modelsContract.Contract, previous, next protocol.Protocol, timestamp time.Time, tx models.Transaction) error { + if err := p.getUpdates(ctx, script, *old, tx); err != nil { return err } @@ -55,6 +51,7 @@ func (p *Babylon) Parse(script noderpc.Script, old *modelsContract.Contract, pre } contractScript := modelsContract.Script{ + Level: next.StartLevel, Hash: newHash, Code: s.Code, Storage: s.Storage, @@ -62,7 +59,7 @@ func (p *Babylon) Parse(script noderpc.Script, old *modelsContract.Contract, pre Views: s.Views, } - if err := contractScript.Save(tx); err != nil { + if err := tx.Scripts(ctx, &contractScript); err != nil { return err } @@ -70,14 +67,15 @@ func (p *Babylon) Parse(script noderpc.Script, old *modelsContract.Contract, pre m := &migration.Migration{ ContractID: old.ID, - Level: previous.EndLevel, + Contract: *old, + Level: next.StartLevel, ProtocolID: next.ID, PrevProtocolID: previous.ID, Timestamp: timestamp, Kind: types.MigrationKindUpdate, } - return m.Save(tx) + return tx.Migrations(ctx, m) } // IsMigratable - @@ -85,7 +83,7 @@ func (p *Babylon) IsMigratable(address string) bool { return true } -func (p *Babylon) getUpdates(script noderpc.Script, contract modelsContract.Contract, tx pg.DBI) error { +func (p *Babylon) getUpdates(ctx context.Context, script noderpc.Script, contract modelsContract.Contract, tx models.Transaction) error { storage, err := script.GetSettledStorage() if err != nil { return err @@ -100,22 +98,15 @@ func (p *Babylon) getUpdates(script noderpc.Script, contract modelsContract.Cont newPtr = p } - bmd, err := p.bmdRepo.GetByAddress(contract.Account.Address) + updatedRows, err := tx.BabylonUpdateBigMapDiffs(ctx, contract.Account.Address, newPtr) if err != nil { return err } - if len(bmd) == 0 { + if updatedRows == 0 { return nil } - for i := range bmd { - bmd[i].Ptr = newPtr - if err := bmd[i].Save(tx); err != nil { - return err - } - } - - keys, err := p.bmdRepo.CurrentByContract(contract.Account.Address) + keys, err := tx.DeleteBigMapStatesByContract(ctx, contract.Account.Address) if err != nil { return err } @@ -124,12 +115,10 @@ func (p *Babylon) getUpdates(script noderpc.Script, contract modelsContract.Cont } for i := range keys { - if _, err := tx.Model(&keys[i]).WherePK().Delete(); err != nil { - return err - } - keys[i].Ptr = newPtr - if err := keys[i].Save(tx); err != nil { + keys[i].ID = 0 + + if err := tx.BigMapStates(ctx, &keys[i]); err != nil { return err } } diff --git a/internal/parsers/migrations/carthage.go b/internal/parsers/migrations/carthage.go index 2b2c1282e..abcb67fb3 100644 --- a/internal/parsers/migrations/carthage.go +++ b/internal/parsers/migrations/carthage.go @@ -2,17 +2,18 @@ package migrations import ( "bytes" + "context" "encoding/json" "time" "github.com/baking-bad/bcdhub/internal/bcd" "github.com/baking-bad/bcdhub/internal/bcd/contract" + "github.com/baking-bad/bcdhub/internal/models" modelsContract "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/migration" "github.com/baking-bad/bcdhub/internal/models/protocol" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" - "github.com/go-pg/pg/v10" ) // Carthage - @@ -25,7 +26,7 @@ func NewCarthage() *Carthage { } // Parse - -func (p *Carthage) Parse(script noderpc.Script, old *modelsContract.Contract, previous, next protocol.Protocol, timestamp time.Time, tx pg.DBI) error { +func (p *Carthage) Parse(ctx context.Context, script noderpc.Script, old *modelsContract.Contract, previous, next protocol.Protocol, timestamp time.Time, tx models.Transaction) error { codeBytes, err := json.Marshal(script.Code) if err != nil { return err @@ -47,6 +48,7 @@ func (p *Carthage) Parse(script noderpc.Script, old *modelsContract.Contract, pr } contractScript := modelsContract.Script{ + Level: next.StartLevel, Hash: newHash, Code: s.Code, Storage: s.Storage, @@ -54,7 +56,7 @@ func (p *Carthage) Parse(script noderpc.Script, old *modelsContract.Contract, pr Views: s.Views, } - if err := contractScript.Save(tx); err != nil { + if err := tx.Scripts(ctx, &contractScript); err != nil { return err } @@ -62,14 +64,15 @@ func (p *Carthage) Parse(script noderpc.Script, old *modelsContract.Contract, pr m := &migration.Migration{ ContractID: old.ID, - Level: previous.EndLevel, + Contract: *old, + Level: next.StartLevel, ProtocolID: next.ID, PrevProtocolID: previous.ID, Timestamp: timestamp, Kind: types.MigrationKindUpdate, } - return m.Save(tx) + return tx.Migrations(ctx, m) } // IsMigratable - diff --git a/internal/parsers/migrations/implicit.go b/internal/parsers/migrations/implicit.go index 453871255..ffcab484c 100644 --- a/internal/parsers/migrations/implicit.go +++ b/internal/parsers/migrations/implicit.go @@ -5,7 +5,6 @@ import ( "github.com/baking-bad/bcdhub/internal/bcd/consts" "github.com/baking-bad/bcdhub/internal/config" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models/account" contracts "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/migration" @@ -16,6 +15,7 @@ import ( "github.com/baking-bad/bcdhub/internal/parsers" "github.com/baking-bad/bcdhub/internal/parsers/contract" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) // ImplicitParser - @@ -63,7 +63,10 @@ func (p *ImplicitParser) IsMigratable(address string) bool { } func (p *ImplicitParser) origination(ctx context.Context, implicit noderpc.ImplicitOperationsResult, head noderpc.Header, store parsers.Store) error { - if _, err := p.contractsRepo.Get(implicit.OriginatedContracts[0]); err == nil { + if len(implicit.OriginatedContracts) == 0 { + return nil + } + if _, err := p.contractsRepo.Get(ctx, implicit.OriginatedContracts[0]); err == nil { return nil } origination := operation.Operation{ @@ -72,8 +75,12 @@ func (p *ImplicitParser) origination(ctx context.Context, implicit noderpc.Impli Timestamp: head.Timestamp, Kind: types.OperationKindOrigination, Destination: account.Account{ - Address: implicit.OriginatedContracts[0], - Type: types.AccountTypeContract, + Address: implicit.OriginatedContracts[0], + Type: types.AccountTypeContract, + Level: head.Level, + OperationsCount: 1, + LastAction: head.Timestamp, + MigrationsCount: 1, }, ConsumedGas: implicit.ConsumedGas, PaidStorageSizeDiff: implicit.PaidStorageSizeDiff, @@ -87,7 +94,7 @@ func (p *ImplicitParser) origination(ctx context.Context, implicit noderpc.Impli } origination.Script = script - if err := p.contractParser.Parse(&origination, store); err != nil { + if err := p.contractParser.Parse(ctx, &origination, store); err != nil { return err } @@ -99,14 +106,14 @@ func (p *ImplicitParser) origination(ctx context.Context, implicit noderpc.Impli Level: head.Level, Timestamp: head.Timestamp, Kind: types.MigrationKindBootstrap, - Contract: contracts[i], + Contract: *contracts[i], }) + store.AddAccounts(origination.Destination) break } } - logger.Info().Msg("Implicit bootstrap migration found") - + log.Info().Msg("Implicit bootstrap migration found") return nil } @@ -127,9 +134,13 @@ func (p *ImplicitParser) transaction(implicit noderpc.ImplicitOperationsResult, for i := range implicit.BalanceUpdates { if implicit.BalanceUpdates[i].Kind == "contract" && implicit.BalanceUpdates[i].Origin == "subsidy" { tx.Destination = account.Account{ - Type: types.NewAccountType(implicit.BalanceUpdates[i].Contract), - Address: implicit.BalanceUpdates[i].Contract, + Type: types.NewAccountType(implicit.BalanceUpdates[i].Contract), + Address: implicit.BalanceUpdates[i].Contract, + Level: head.Level, + OperationsCount: 1, + LastAction: head.Timestamp, } + store.AddAccounts(tx.Destination) break } } @@ -139,6 +150,5 @@ func (p *ImplicitParser) transaction(implicit noderpc.ImplicitOperationsResult, } store.AddOperations(&tx) - return nil } diff --git a/internal/parsers/migrations/jakarta.go b/internal/parsers/migrations/jakarta.go index de9d389c7..b3334365f 100644 --- a/internal/parsers/migrations/jakarta.go +++ b/internal/parsers/migrations/jakarta.go @@ -2,17 +2,18 @@ package migrations import ( "bytes" + "context" "encoding/json" "time" "github.com/baking-bad/bcdhub/internal/bcd" "github.com/baking-bad/bcdhub/internal/bcd/contract" + "github.com/baking-bad/bcdhub/internal/models" modelsContract "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/migration" "github.com/baking-bad/bcdhub/internal/models/protocol" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" - "github.com/go-pg/pg/v10" ) // Jakarta - @@ -77,7 +78,7 @@ func NewJakarta() *Jakarta { } // Parse - -func (p *Jakarta) Parse(script noderpc.Script, old *modelsContract.Contract, previous, next protocol.Protocol, timestamp time.Time, tx pg.DBI) error { +func (p *Jakarta) Parse(ctx context.Context, script noderpc.Script, old *modelsContract.Contract, previous, next protocol.Protocol, timestamp time.Time, tx models.Transaction) error { codeBytes, err := json.Marshal(script.Code) if err != nil { return err @@ -106,7 +107,7 @@ func (p *Jakarta) Parse(script noderpc.Script, old *modelsContract.Contract, pre Views: s.Views, } - if err := contractScript.Save(tx); err != nil { + if err := tx.Scripts(ctx, &contractScript); err != nil { return err } @@ -114,14 +115,15 @@ func (p *Jakarta) Parse(script noderpc.Script, old *modelsContract.Contract, pre m := &migration.Migration{ ContractID: old.ID, - Level: previous.EndLevel, + Contract: *old, + Level: next.StartLevel, ProtocolID: next.ID, PrevProtocolID: previous.ID, Timestamp: timestamp, Kind: types.MigrationKindUpdate, } - return m.Save(tx) + return tx.Migrations(ctx, m) } // IsMigratable - diff --git a/internal/parsers/migrations/parser.go b/internal/parsers/migrations/parser.go index ce7e50685..a51cbfe9c 100644 --- a/internal/parsers/migrations/parser.go +++ b/internal/parsers/migrations/parser.go @@ -1,16 +1,17 @@ package migrations import ( + "context" "time" + "github.com/baking-bad/bcdhub/internal/models" modelsContract "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/protocol" "github.com/baking-bad/bcdhub/internal/noderpc" - "github.com/go-pg/pg/v10" ) // Parser - type Parser interface { - Parse(script noderpc.Script, old *modelsContract.Contract, previous, next protocol.Protocol, timestamp time.Time, tx pg.DBI) error + Parse(ctx context.Context, script noderpc.Script, old *modelsContract.Contract, previous, next protocol.Protocol, timestamp time.Time, tx models.Transaction) error IsMigratable(address string) bool } diff --git a/internal/parsers/migrations/vesting.go b/internal/parsers/migrations/vesting.go index 012922176..f30695e87 100644 --- a/internal/parsers/migrations/vesting.go +++ b/internal/parsers/migrations/vesting.go @@ -1,6 +1,8 @@ package migrations import ( + "context" + "github.com/baking-bad/bcdhub/internal/config" "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/migration" @@ -19,37 +21,45 @@ type VestingParser struct { } // NewVestingParser - -func NewVestingParser(ctx *config.Context, contractParser contract.Parser, proto protocol.Protocol) (*VestingParser, error) { +func NewVestingParser(ctx *config.Context, contractParser contract.Parser, proto protocol.Protocol) *VestingParser { return &VestingParser{ parser: contractParser, protocol: proto, - }, nil + } } // Parse - -func (p *VestingParser) Parse(data noderpc.ContractData, head noderpc.Header, address string, store parsers.Store) error { - if err := p.parser.Parse(&operation.Operation{ +func (p *VestingParser) Parse(ctx context.Context, data noderpc.ContractData, head noderpc.Header, address string, store parsers.Store) error { + vestingOperation := &operation.Operation{ ProtocolID: p.protocol.ID, Status: types.OperationStatusApplied, Kind: types.OperationKindOrigination, Amount: data.Balance, Counter: data.Counter, Source: account.Account{ - Address: data.Manager, - Type: types.NewAccountType(data.Manager), + Address: data.Manager, + Type: types.NewAccountType(data.Manager), + Level: head.Level, + LastAction: head.Timestamp, }, Destination: account.Account{ - Address: address, - Type: types.NewAccountType(address), + Address: address, + Type: types.NewAccountType(address), + Level: head.Level, + LastAction: head.Timestamp, + MigrationsCount: 1, }, Delegate: account.Account{ - Address: data.Delegate.Value, - Type: types.NewAccountType(data.Delegate.Value), + Address: data.Delegate.Value, + Type: types.NewAccountType(data.Delegate.Value), + Level: head.Level, + LastAction: head.Timestamp, }, Level: head.Level, Timestamp: head.Timestamp, Script: data.RawScript, - }, store); err != nil { + } + if err := p.parser.Parse(ctx, vestingOperation, store); err != nil { return err } @@ -61,8 +71,13 @@ func (p *VestingParser) Parse(data noderpc.ContractData, head noderpc.Header, ad ProtocolID: p.protocol.ID, Timestamp: head.Timestamp, Kind: types.MigrationKindBootstrap, - Contract: contracts[i], + Contract: *contracts[i], }) + store.AddAccounts( + vestingOperation.Source, + vestingOperation.Destination, + vestingOperation.Delegate, + ) break } } diff --git a/internal/parsers/operations/data/models/contract/KT19nHqEWZxFFbbDL1b7Y86escgEN7qUShGo.json b/internal/parsers/operations/data/models/contract/KT19nHqEWZxFFbbDL1b7Y86escgEN7qUShGo.json index aceabaf0d..d9c831006 100644 --- a/internal/parsers/operations/data/models/contract/KT19nHqEWZxFFbbDL1b7Y86escgEN7qUShGo.json +++ b/internal/parsers/operations/data/models/contract/KT19nHqEWZxFFbbDL1b7Y86escgEN7qUShGo.json @@ -6,8 +6,7 @@ "address": { "address": "KT19nHqEWZxFFbbDL1b7Y86escgEN7qUShGo", "network": "mainnet", - "type": 1, - "alias": "tZERO Registry" + "type": 1 }, "manager": { "address": "tz1TZERoLXqCytrJBmjdzNrAYie1TQ1c2cHN", diff --git a/internal/parsers/operations/data/models/contract/KT1Ap287P1NzsnToSJdA4aqSNjPomRaHBZSr.json b/internal/parsers/operations/data/models/contract/KT1Ap287P1NzsnToSJdA4aqSNjPomRaHBZSr.json index 3eef7d3e2..9eeeb522c 100644 --- a/internal/parsers/operations/data/models/contract/KT1Ap287P1NzsnToSJdA4aqSNjPomRaHBZSr.json +++ b/internal/parsers/operations/data/models/contract/KT1Ap287P1NzsnToSJdA4aqSNjPomRaHBZSr.json @@ -6,8 +6,7 @@ "account": { "address": "KT1Ap287P1NzsnToSJdA4aqSNjPomRaHBZSr", "network": "mainnet", - "type": 1, - "alias": "Atomex FA1.2" + "type": 1 }, "manager": { "address": "tz1bcoETzoyoSUFPi1YZBudKQBf1JUsER6ye", diff --git a/internal/parsers/operations/data/models/contract/KT1KemKUx79keZgFW756jQrqKcZJ21y4SPdS.json b/internal/parsers/operations/data/models/contract/KT1KemKUx79keZgFW756jQrqKcZJ21y4SPdS.json index 0333d2b3a..80b9828ae 100644 --- a/internal/parsers/operations/data/models/contract/KT1KemKUx79keZgFW756jQrqKcZJ21y4SPdS.json +++ b/internal/parsers/operations/data/models/contract/KT1KemKUx79keZgFW756jQrqKcZJ21y4SPdS.json @@ -6,8 +6,7 @@ "address": { "address": "KT1KemKUx79keZgFW756jQrqKcZJ21y4SPdS", "network": "mainnet", - "type": 1, - "alias": "tZERO Compliance" + "type": 1 }, "manager": { "address": "tz1TZERoLXqCytrJBmjdzNrAYie1TQ1c2cHN", diff --git a/internal/parsers/operations/data/models/contract/KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn.json b/internal/parsers/operations/data/models/contract/KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn.json index b8fc2ac3b..42dcb1675 100644 --- a/internal/parsers/operations/data/models/contract/KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn.json +++ b/internal/parsers/operations/data/models/contract/KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn.json @@ -6,8 +6,7 @@ "address": { "address": "KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn", "network": "mainnet", - "type": 1, - "alias": "tzBTC" + "type": 1 }, "tags": 128, "manager": { diff --git a/internal/parsers/operations/data/models/contract/KT1QcxwB4QyPKfmSwjH1VRxa6kquUjeDWeEy.json b/internal/parsers/operations/data/models/contract/KT1QcxwB4QyPKfmSwjH1VRxa6kquUjeDWeEy.json index 53df93fd3..2fe58007d 100644 --- a/internal/parsers/operations/data/models/contract/KT1QcxwB4QyPKfmSwjH1VRxa6kquUjeDWeEy.json +++ b/internal/parsers/operations/data/models/contract/KT1QcxwB4QyPKfmSwjH1VRxa6kquUjeDWeEy.json @@ -7,8 +7,7 @@ "address": { "address": "KT1QcxwB4QyPKfmSwjH1VRxa6kquUjeDWeEy", "network": "mainnet", - "type": 1, - "alias": "Minter" + "type": 1 }, "manager": { "address": "tz1codeYURj5z49HKX9zmLHms2vJN2qDjrtt", diff --git a/internal/parsers/operations/data/models/contract/KT1S5iPRQ612wcNm6mXDqDhTNegGFcvTV7vM.json b/internal/parsers/operations/data/models/contract/KT1S5iPRQ612wcNm6mXDqDhTNegGFcvTV7vM.json index ad1aac213..5e8eaab3a 100644 --- a/internal/parsers/operations/data/models/contract/KT1S5iPRQ612wcNm6mXDqDhTNegGFcvTV7vM.json +++ b/internal/parsers/operations/data/models/contract/KT1S5iPRQ612wcNm6mXDqDhTNegGFcvTV7vM.json @@ -7,8 +7,7 @@ "address": { "address": "KT1S5iPRQ612wcNm6mXDqDhTNegGFcvTV7vM", "network": "mainnet", - "type": 1, - "alias": "Aspen Digital" + "type": 1 }, "manager": { "address": "tz1TZERoLXqCytrJBmjdzNrAYie1TQ1c2cHN", diff --git a/internal/parsers/operations/data/rpc/opg/oozKKBjBK44uGCrMcT6wwPbUD62mF7ddenwXSyJKJAAiSRxq4JQ.json b/internal/parsers/operations/data/rpc/opg/oozKKBjBK44uGCrMcT6wwPbUD62mF7ddenwXSyJKJAAiSRxq4JQ.json new file mode 100644 index 000000000..0a0dea120 --- /dev/null +++ b/internal/parsers/operations/data/rpc/opg/oozKKBjBK44uGCrMcT6wwPbUD62mF7ddenwXSyJKJAAiSRxq4JQ.json @@ -0,0 +1,120 @@ +{ + "protocol":"PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf", + "chain_id":"NetXyuzvDo2Ugzb", + "hash":"oozKKBjBK44uGCrMcT6wwPbUD62mF7ddenwXSyJKJAAiSRxq4JQ", + "branch":"BLRf8KfLrQ9171LdZ3CZXXZbzxthdBUMXNBTyUcZEAHVBN7sYuw", + "contents":[{ + "kind": "transfer_ticket", + "source": "tz2UUqEaKhW3p7T7QvBSxd4jz2Kzc28oBvC7", + "fee": "668", + "counter": "666002", + "gas_limit": "3295", + "storage_limit": "110", + "ticket_contents": { + "string": "Ticket" + }, + "ticket_ty": { + "prim": "string" + }, + "ticket_ticketer": "KT1Nux298EEiVoTzF7jQS3iBV3K4ShN8ucSP", + "ticket_amount": "1", + "destination": "KT1MYutYhGoyCRf9y2JqfWoLKPJ3zMiDmMhE", + "entrypoint": "save", + "metadata": { + "balance_updates": [ + { + "kind": "contract", + "contract": "tz2UUqEaKhW3p7T7QvBSxd4jz2Kzc28oBvC7", + "change": "-668", + "origin": "block" + }, + { + "kind": "accumulator", + "category": "block fees", + "change": "668", + "origin": "block" + } + ], + "operation_result": { + "status": "applied", + "balance_updates": [ + { + "kind": "contract", + "contract": "tz2UUqEaKhW3p7T7QvBSxd4jz2Kzc28oBvC7", + "change": "-16500", + "origin": "block" + }, + { + "kind": "burned", + "category": "storage fees", + "change": "16500", + "origin": "block" + } + ], + "ticket_updates": [ + { + "ticket_token": { + "ticketer": "KT1Nux298EEiVoTzF7jQS3iBV3K4ShN8ucSP", + "content_type": {"prim":"string"}, + "content": {"string":"Ticket"} + }, + "updates": [ + { + "account": "tz2UUqEaKhW3p7T7QvBSxd4jz2Kzc28oBvC7", + "amount": "-1" + } + ] + } + ], + "consumed_milligas": "1282385", + "paid_storage_size_diff": "66" + }, + "internal_operation_results": [ + { + "kind": "transaction", + "source": "tz2UUqEaKhW3p7T7QvBSxd4jz2Kzc28oBvC7", + "nonce": 0, + "amount": "0", + "destination": "KT1MYutYhGoyCRf9y2JqfWoLKPJ3zMiDmMhE", + "parameters": {"entrypoint":"save","value":{"prim":"Pair","args":[{"bytes":"019d326434ec72a63f89180ef9cd739b59706efb3e00"},{"prim":"Pair","args":[{"string":"Ticket"},{"int":"1"}]}]}}, + "result": { + "status": "applied", + "storage": [{"prim":"Pair","args":[{"bytes":"019d326434ec72a63f89180ef9cd739b59706efb3e00"},{"prim":"Pair","args":[{"string":"Ticket"},{"int":"1"}]}]}], + "balance_updates": [ + { + "kind": "contract", + "contract": "tz2UUqEaKhW3p7T7QvBSxd4jz2Kzc28oBvC7", + "change": "-11000", + "origin": "block" + }, + { + "kind": "burned", + "category": "storage fees", + "change": "11000", + "origin": "block" + } + ], + "ticket_receipt": [ + { + "ticket_token": { + "ticketer": "KT1Nux298EEiVoTzF7jQS3iBV3K4ShN8ucSP", + "content_type": {"prim":"string"}, + "content": {"string":"Ticket"} + }, + "updates": [ + { + "account": "KT1MYutYhGoyCRf9y2JqfWoLKPJ3zMiDmMhE", + "amount": "1" + } + ] + } + ], + "consumed_milligas": "1912189", + "storage_size": "238", + "paid_storage_size_diff": "44" + } + } + ] + } + +}]} \ No newline at end of file diff --git a/internal/parsers/operations/event.go b/internal/parsers/operations/event.go index 7070fea6a..857e7f668 100644 --- a/internal/parsers/operations/event.go +++ b/internal/parsers/operations/event.go @@ -1,6 +1,8 @@ package operations import ( + "context" + "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/types" @@ -19,10 +21,14 @@ func NewEvent(params *ParseParams) Event { } // Parse - -func (p Event) Parse(data noderpc.Operation, store parsers.Store) error { +func (p Event) Parse(ctx context.Context, data noderpc.Operation, store parsers.Store) error { source := account.Account{ - Address: data.Source, - Type: types.NewAccountType(data.Source), + Address: data.Source, + Type: types.NewAccountType(data.Source), + Level: p.head.Level, + OperationsCount: 1, + LastAction: p.head.Timestamp, + EventsCount: 1, } event := operation.Operation{ @@ -45,13 +51,14 @@ func (p Event) Parse(data noderpc.Operation, store parsers.Store) error { Internal: true, } - parseOperationResult(data, &event) + parseOperationResult(data, &event, store) event.SetBurned(*p.protocol.Constants) p.stackTrace.Add(event) store.AddOperations(&event) + store.AddAccounts(event.Source) return nil } diff --git a/internal/parsers/operations/migration.go b/internal/parsers/operations/migration.go index 43387686a..f245b51d7 100644 --- a/internal/parsers/operations/migration.go +++ b/internal/parsers/operations/migration.go @@ -1,8 +1,9 @@ package operations import ( + "context" + "github.com/baking-bad/bcdhub/internal/bcd/ast" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/migration" "github.com/baking-bad/bcdhub/internal/models/operation" @@ -10,6 +11,7 @@ import ( "github.com/baking-bad/bcdhub/internal/noderpc" "github.com/baking-bad/bcdhub/internal/parsers" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) // Migration - @@ -23,7 +25,7 @@ func NewMigration(contracts contract.Repository) Migration { } // Parse - -func (m Migration) Parse(data noderpc.Operation, operation *operation.Operation, protocol string, store parsers.Store) error { +func (m Migration) Parse(ctx context.Context, data noderpc.Operation, operation *operation.Operation, protocol string, store parsers.Store) error { switch protocol { case "ProtoGenesisGenesisGenesisGenesisGenesisGenesk612im", @@ -43,7 +45,7 @@ func (m Migration) Parse(data noderpc.Operation, operation *operation.Operation, "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", "PtEdoTezd3RHSC31mpxxo1npxFjoWWcFgQtxapi51Z8TLu6v6Uq", "PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA": - return m.fromBigMapDiffs(data, operation, store) + return m.fromBigMapDiffs(ctx, data, operation, store) case "ProtoALphaALphaALphaALphaALphaALphaALphaALphaDdp3zK", "PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx", @@ -62,13 +64,13 @@ func (m Migration) Parse(data noderpc.Operation, operation *operation.Operation, "PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf", "ProxfordSW2S7fvchT1Zgj2avb5UES194neRyYVXoaDGvF9egt8": - return m.fromLazyStorageDiff(data, operation, store) + return m.fromLazyStorageDiff(ctx, data, operation, store) default: return errors.Errorf("unknown protocol for migration parser: %s", protocol) } } -func (m Migration) fromLazyStorageDiff(data noderpc.Operation, operation *operation.Operation, store parsers.Store) error { +func (m Migration) fromLazyStorageDiff(ctx context.Context, data noderpc.Operation, operation *operation.Operation, store parsers.Store) error { var lsd []noderpc.LazyStorageDiff switch { case data.Result != nil && data.Result.LazyStorageDiff != nil: @@ -89,20 +91,21 @@ func (m Migration) fromLazyStorageDiff(data noderpc.Operation, operation *operat } for j := range lsd[i].Diff.BigMap.Updates { - migration, err := m.createMigration(lsd[i].Diff.BigMap.Updates[j].Value, operation) + migration, err := m.createMigration(ctx, lsd[i].Diff.BigMap.Updates[j].Value, operation) if err != nil { return err } if migration != nil { + operation.Destination.MigrationsCount += 1 store.AddMigrations(migration) - logger.Info().Fields(migration.LogFields()).Msg("Migration detected") + log.Info().Fields(migration.LogFields()).Msg("Migration detected") } } } return nil } -func (m Migration) fromBigMapDiffs(data noderpc.Operation, operation *operation.Operation, store parsers.Store) error { +func (m Migration) fromBigMapDiffs(ctx context.Context, data noderpc.Operation, operation *operation.Operation, store parsers.Store) error { var bmd []noderpc.BigMapDiff switch { case data.Result != nil && data.Result.BigMapDiffs != nil: @@ -118,19 +121,20 @@ func (m Migration) fromBigMapDiffs(data noderpc.Operation, operation *operation. continue } - migration, err := m.createMigration(bmd[i].Value, operation) + migration, err := m.createMigration(ctx, bmd[i].Value, operation) if err != nil { return err } if migration != nil { + operation.Destination.MigrationsCount += 1 store.AddMigrations(migration) - logger.Info().Fields(migration.LogFields()).Msg("Migration detected") + log.Info().Fields(migration.LogFields()).Msg("Migration detected") } } return nil } -func (m Migration) createMigration(value []byte, operation *operation.Operation) (*migration.Migration, error) { +func (m Migration) createMigration(ctx context.Context, value []byte, operation *operation.Operation) (*migration.Migration, error) { if len(value) == 0 { return nil, nil } @@ -147,12 +151,13 @@ func (m Migration) createMigration(value []byte, operation *operation.Operation) return nil, nil } - c, err := m.contracts.Get(operation.Destination.Address) + c, err := m.contracts.Get(ctx, operation.Destination.Address) if err != nil { return nil, err } return &migration.Migration{ ContractID: c.ID, + Contract: c, Level: operation.Level, ProtocolID: operation.ProtocolID, Timestamp: operation.Timestamp, diff --git a/internal/parsers/operations/migration_test.go b/internal/parsers/operations/migration_test.go index e575d6ef4..4ef315730 100644 --- a/internal/parsers/operations/migration_test.go +++ b/internal/parsers/operations/migration_test.go @@ -1,6 +1,7 @@ package operations import ( + "context" "testing" "time" @@ -60,6 +61,7 @@ func TestMigration_Parse(t *testing.T) { Timestamp: timestamp, Hash: []byte("hash"), Kind: types.MigrationKindLambda, + Contract: contract.Contract{}, }, }, } @@ -71,12 +73,12 @@ func TestMigration_Parse(t *testing.T) { contractRepo. EXPECT(). - Get(gomock.Eq(tt.operation.Destination.Address)). + Get(gomock.Any(), tt.operation.Destination.Address). Return(contract.Contract{}, nil). AnyTimes() store := parsers.NewTestStore() - err = NewMigration(contractRepo).Parse(op, tt.operation, "PtEdoTezd3RHSC31mpxxo1npxFjoWWcFgQtxapi51Z8TLu6v6Uq", store) + err = NewMigration(contractRepo).Parse(context.Background(), op, tt.operation, "PtEdoTezd3RHSC31mpxxo1npxFjoWWcFgQtxapi51Z8TLu6v6Uq", store) require.NoError(t, err) if tt.want != nil { diff --git a/internal/parsers/operations/operation_group.go b/internal/parsers/operations/operation_group.go index 4dc17682f..61a5f0c53 100644 --- a/internal/parsers/operations/operation_group.go +++ b/internal/parsers/operations/operation_group.go @@ -1,6 +1,8 @@ package operations import ( + "context" + "github.com/baking-bad/bcdhub/internal/bcd" "github.com/baking-bad/bcdhub/internal/bcd/consts" "github.com/baking-bad/bcdhub/internal/bcd/encoding" @@ -11,7 +13,7 @@ import ( // OperationParser - type OperationParser interface { - Parse(data noderpc.Operation, store parsers.Store) error + Parse(ctx context.Context, data noderpc.Operation, store parsers.Store) error } // Group - @@ -25,7 +27,7 @@ func NewGroup(params *ParseParams) Group { } // Parse - -func (opg Group) Parse(data noderpc.LightOperationGroup, store parsers.Store) error { +func (opg Group) Parse(ctx context.Context, data noderpc.LightOperationGroup, store parsers.Store) error { helpers.SetTagSentry("hash", data.Hash) if data.Hash != "" { hash, err := encoding.DecodeBase58(data.Hash) @@ -48,7 +50,7 @@ func (opg Group) Parse(data noderpc.LightOperationGroup, store parsers.Store) er } contentParser := NewContent(opg.ParseParams) - if err := contentParser.Parse(operation, store); err != nil { + if err := contentParser.Parse(ctx, operation, store); err != nil { return err } contentParser.clear() @@ -84,7 +86,7 @@ func NewContent(params *ParseParams) Content { } // Parse - -func (content Content) Parse(data noderpc.Operation, store parsers.Store) error { +func (content Content) Parse(ctx context.Context, data noderpc.Operation, store parsers.Store) error { var operationParser OperationParser switch data.Kind { case consts.Origination, consts.OriginationNew: @@ -106,18 +108,18 @@ func (content Content) Parse(data noderpc.Operation, store parsers.Store) error default: return nil } - if err := operationParser.Parse(data, store); err != nil { + if err := operationParser.Parse(ctx, data, store); err != nil { return err } - if err := content.parseInternal(data, store); err != nil { + if err := content.parseInternal(ctx, data, store); err != nil { return err } return nil } -func (content Content) parseInternal(data noderpc.Operation, store parsers.Store) error { +func (content Content) parseInternal(ctx context.Context, data noderpc.Operation, store parsers.Store) error { if data.Metadata == nil { return nil } @@ -130,7 +132,7 @@ func (content Content) parseInternal(data noderpc.Operation, store parsers.Store } for i := range internals { - if err := content.Parse(internals[i], store); err != nil { + if err := content.Parse(ctx, internals[i], store); err != nil { return err } } diff --git a/internal/parsers/operations/operation_group_test.go b/internal/parsers/operations/operation_group_test.go index a856f906c..74ff8dd78 100644 --- a/internal/parsers/operations/operation_group_test.go +++ b/internal/parsers/operations/operation_group_test.go @@ -2,6 +2,7 @@ package operations import ( "context" + "database/sql" "fmt" "os" "testing" @@ -11,7 +12,6 @@ import ( "github.com/baking-bad/bcdhub/internal/bcd/encoding" "github.com/baking-bad/bcdhub/internal/cache" "github.com/baking-bad/bcdhub/internal/config" - "github.com/baking-bad/bcdhub/internal/models" "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/bigmapaction" "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" @@ -27,11 +27,12 @@ import ( mock_proto "github.com/baking-bad/bcdhub/internal/models/mock/protocol" "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/protocol" + "github.com/baking-bad/bcdhub/internal/models/ticket" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" "github.com/baking-bad/bcdhub/internal/parsers" "github.com/baking-bad/bcdhub/internal/testsuite" - "github.com/go-pg/pg/v10" + "github.com/shopspring/decimal" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" ) @@ -112,31 +113,31 @@ func TestGroup_Parse(t *testing.T) { contractRepo. EXPECT(). - Get(gomock.Any()). + Get(gomock.Any(), gomock.Any()). DoAndReturn(readTestContractModel). AnyTimes() contractRepo. EXPECT(). - Script(gomock.Any(), gomock.Any()). + Script(gomock.Any(), gomock.Any(), gomock.Any()). DoAndReturn(readTestScriptModel). AnyTimes() contractRepo. EXPECT(). - ScriptPart(gomock.Any(), gomock.Any(), gomock.Any()). + ScriptPart(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()). DoAndReturn(readTestScriptPart). AnyTimes() scriptRepo. EXPECT(). - ByHash(gomock.Any()). - Return(modelContract.Script{}, pg.ErrNoRows). + ByHash(gomock.Any(), gomock.Any()). + Return(modelContract.Script{}, sql.ErrNoRows). AnyTimes() globalConstantRepo. EXPECT(). - All(gomock.Eq("exprv5uiw7xXoEgRahR3YBn4iAVwfkNCMsrkneutuBZCGG5sS64kRw")). + All(gomock.Any(), gomock.Eq("exprv5uiw7xXoEgRahR3YBn4iAVwfkNCMsrkneutuBZCGG5sS64kRw")). Return([]modelContract.GlobalConstant{ { ID: 1, @@ -148,12 +149,6 @@ func TestGroup_Parse(t *testing.T) { }, nil). AnyTimes() - generalRepo. - EXPECT(). - Save(context.Background(), gomock.AssignableToTypeOf([]models.Model{})). - Return(nil). - AnyTimes() - generalRepo. EXPECT(). IsRecordNotFound(gomock.Any()). @@ -162,7 +157,7 @@ func TestGroup_Parse(t *testing.T) { bmdRepo. EXPECT(). - GetByPtr("KT1HBy1L43tiLe5MVJZ5RoxGy53Kx8kMgyoU", int64(2416)). + GetByPtr(gomock.Any(), "KT1HBy1L43tiLe5MVJZ5RoxGy53Kx8kMgyoU", int64(2416)). Return([]bigmapdiff.BigMapState{ { Ptr: 2416, @@ -179,7 +174,7 @@ func TestGroup_Parse(t *testing.T) { for _, ptr := range []int{25167, 25166, 25165, 25164} { bmdRepo. EXPECT(). - GetByPtr("KT1C2MfcjWb5R1ZDDxVULCsGuxrf5fEn5264", int64(ptr)). + GetByPtr(gomock.Any(), "KT1C2MfcjWb5R1ZDDxVULCsGuxrf5fEn5264", int64(ptr)). Return([]bigmapdiff.BigMapState{}, nil). AnyTimes() } @@ -187,14 +182,14 @@ func TestGroup_Parse(t *testing.T) { for _, ptr := range []int{40067, 40065} { bmdRepo. EXPECT(). - GetByPtr("KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", int64(ptr)). + GetByPtr(gomock.Any(), "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", int64(ptr)). Return([]bigmapdiff.BigMapState{}, nil). AnyTimes() } bmdRepo. EXPECT(). - GetByPtr("KT1Dc6A6jTY9sG4UvqKciqbJNAGtXqb4n7vZ", int64(2417)). + GetByPtr(gomock.Any(), "KT1Dc6A6jTY9sG4UvqKciqbJNAGtXqb4n7vZ", int64(2417)). Return([]bigmapdiff.BigMapState{ { Ptr: 2417, @@ -210,7 +205,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - Get("PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", int64(-1)). + Get(gomock.Any(), "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", int64(-1)). Return(protocol.Protocol{ Hash: "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", SymLink: bcd.SymLinkBabylon, @@ -220,7 +215,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - Get("PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", int64(-1)). + Get(gomock.Any(), "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", int64(-1)). Return(protocol.Protocol{ Hash: "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", SymLink: bcd.SymLinkBabylon, @@ -230,7 +225,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - Get("PsddFKi32cMJ2qPjf43Qv5GDWLDPZb3T3bF6fLKiF5HtvHNU7aP", int64(-1)). + Get(gomock.Any(), "PsddFKi32cMJ2qPjf43Qv5GDWLDPZb3T3bF6fLKiF5HtvHNU7aP", int64(-1)). Return(protocol.Protocol{ Hash: "PsddFKi32cMJ2qPjf43Qv5GDWLDPZb3T3bF6fLKiF5HtvHNU7aP", SymLink: bcd.SymLinkAlpha, @@ -240,7 +235,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - Get("PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA", int64(-1)). + Get(gomock.Any(), "PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA", int64(-1)). Return(protocol.Protocol{ Hash: "PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA", SymLink: bcd.SymLinkBabylon, @@ -250,7 +245,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - Get("PsFLorenaUUuikDWvMDr6fGBRG8kt3e3D3fHoXK1j1BFRxeSH4i", int64(-1)). + Get(gomock.Any(), "PsFLorenaUUuikDWvMDr6fGBRG8kt3e3D3fHoXK1j1BFRxeSH4i", int64(-1)). Return(protocol.Protocol{ Hash: "PsFLorenaUUuikDWvMDr6fGBRG8kt3e3D3fHoXK1j1BFRxeSH4i", SymLink: bcd.SymLinkBabylon, @@ -260,7 +255,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - Get("PtHangzHogokSuiMHemCuowEavgYTP8J5qQ9fQS793MHYFpCY3r", int64(-1)). + Get(gomock.Any(), "PtHangzHogokSuiMHemCuowEavgYTP8J5qQ9fQS793MHYFpCY3r", int64(-1)). Return(protocol.Protocol{ Hash: "PtHangzHogokSuiMHemCuowEavgYTP8J5qQ9fQS793MHYFpCY3r", SymLink: bcd.SymLinkBabylon, @@ -270,7 +265,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - Get("Psithaca2MLRFYargivpo7YvUr7wUDqyxrdhC5CQq78mRvimz6A", int64(-1)). + Get(gomock.Any(), "Psithaca2MLRFYargivpo7YvUr7wUDqyxrdhC5CQq78mRvimz6A", int64(-1)). Return(protocol.Protocol{ Hash: "Psithaca2MLRFYargivpo7YvUr7wUDqyxrdhC5CQq78mRvimz6A", SymLink: bcd.SymLinkBabylon, @@ -280,7 +275,17 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - GetByID(int64(0)). + Get(gomock.Any(), "PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf", int64(-1)). + Return(protocol.Protocol{ + Hash: "PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf", + SymLink: bcd.SymLinkJakarta, + ID: 7, + }, nil). + AnyTimes() + + protoRepo. + EXPECT(). + GetByID(gomock.Any(), int64(0)). Return(protocol.Protocol{ Hash: "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", SymLink: bcd.SymLinkBabylon, @@ -289,7 +294,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - GetByID(int64(1)). + GetByID(gomock.Any(), int64(1)). Return(protocol.Protocol{ Hash: "PsDELPH1Kxsxt8f9eWbxQeRxkjfbxoqM52jvs5Y5fBxWWh4ifpo", SymLink: bcd.SymLinkBabylon, @@ -299,7 +304,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - GetByID(int64(2)). + GetByID(gomock.Any(), int64(2)). Return(protocol.Protocol{ Hash: "PsddFKi32cMJ2qPjf43Qv5GDWLDPZb3T3bF6fLKiF5HtvHNU7aP", SymLink: bcd.SymLinkAlpha, @@ -309,7 +314,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - GetByID(int64(3)). + GetByID(gomock.Any(), int64(3)). Return(protocol.Protocol{ Hash: "PtEdo2ZkT9oKpimTah6x2embF25oss54njMuPzkJTEi5RqfdZFA", SymLink: bcd.SymLinkBabylon, @@ -319,7 +324,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - GetByID(int64(4)). + GetByID(gomock.Any(), int64(4)). Return(protocol.Protocol{ Hash: "PsFLorenaUUuikDWvMDr6fGBRG8kt3e3D3fHoXK1j1BFRxeSH4i", SymLink: bcd.SymLinkBabylon, @@ -329,7 +334,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - GetByID(int64(5)). + GetByID(gomock.Any(), int64(5)). Return(protocol.Protocol{ Hash: "PtHangzHogokSuiMHemCuowEavgYTP8J5qQ9fQS793MHYFpCY3r", SymLink: bcd.SymLinkBabylon, @@ -339,7 +344,7 @@ func TestGroup_Parse(t *testing.T) { protoRepo. EXPECT(). - GetByID(int64(6)). + GetByID(gomock.Any(), int64(6)). Return(protocol.Protocol{ Hash: "Psithaca2MLRFYargivpo7YvUr7wUDqyxrdhC5CQq78mRvimz6A", SymLink: bcd.SymLinkBabylon, @@ -347,19 +352,31 @@ func TestGroup_Parse(t *testing.T) { }, nil). AnyTimes() + protoRepo. + EXPECT(). + GetByID(gomock.Any(), int64(7)). + Return(protocol.Protocol{ + Hash: "PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf", + SymLink: bcd.SymLinkJakarta, + ID: 7, + }, nil). + AnyTimes() + accountsRepo. EXPECT(). - Get("KT1C2MfcjWb5R1ZDDxVULCsGuxrf5fEn5264"). + Get(gomock.Any(), "KT1C2MfcjWb5R1ZDDxVULCsGuxrf5fEn5264"). Return(account.Account{ - Address: "KT1C2MfcjWb5R1ZDDxVULCsGuxrf5fEn5264", - Type: types.AccountTypeContract, - ID: 6, + Address: "KT1C2MfcjWb5R1ZDDxVULCsGuxrf5fEn5264", + Type: types.AccountTypeContract, + ID: 6, + OperationsCount: 1, + LastAction: timestamp, }, nil). AnyTimes() operaitonsRepo. EXPECT(). - Last(gomock.Any(), int64(0)). + Last(gomock.Any(), gomock.Any(), int64(0)). Return(operation.Operation{ Status: types.OperationStatusApplied, DestinationID: 6, @@ -460,8 +477,11 @@ func TestGroup_Parse(t *testing.T) { { Kind: types.OperationKindTransaction, Source: account.Account{ - Address: "tz1aSPEN4RTZbn4aXEsxDiix38dDmacGQ8sq", - Type: types.AccountTypeTz, + Address: "tz1aSPEN4RTZbn4aXEsxDiix38dDmacGQ8sq", + Type: types.AccountTypeTz, + Level: 1068669, + OperationsCount: 1, + LastAction: timestamp, }, Fee: 37300, Counter: 5791164, @@ -470,8 +490,11 @@ func TestGroup_Parse(t *testing.T) { GasLimit: 369423, StorageLimit: 90, Destination: account.Account{ - Address: "KT1S5iPRQ612wcNm6mXDqDhTNegGFcvTV7vM", - Type: types.AccountTypeContract, + Address: "KT1S5iPRQ612wcNm6mXDqDhTNegGFcvTV7vM", + Type: types.AccountTypeContract, + Level: 1068669, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Status: types.OperationStatusApplied, @@ -484,8 +507,11 @@ func TestGroup_Parse(t *testing.T) { Timestamp: timestamp, Burned: 70000, Initiator: account.Account{ - Address: "tz1aSPEN4RTZbn4aXEsxDiix38dDmacGQ8sq", - Type: types.AccountTypeTz, + Address: "tz1aSPEN4RTZbn4aXEsxDiix38dDmacGQ8sq", + Type: types.AccountTypeTz, + Level: 1068669, + OperationsCount: 1, + LastAction: timestamp, }, ProtocolID: 1, Parameters: []byte("{\"entrypoint\":\"default\",\"value\":{\"prim\":\"Right\",\"args\":[{\"prim\":\"Left\",\"args\":[{\"prim\":\"Right\",\"args\":[{\"prim\":\"Right\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"string\":\"tz1aSPEN4RTZbn4aXEsxDiix38dDmacGQ8sq\"},{\"prim\":\"Pair\",\"args\":[{\"string\":\"tz1invbJv3AEm55ct7QF2dVbWZuaDekssYkV\"},{\"int\":\"8010000\"}]}]}]}]}]}]}}"), @@ -515,12 +541,18 @@ func TestGroup_Parse(t *testing.T) { }, { Kind: types.OperationKindTransaction, Source: account.Account{ - Address: "KT1S5iPRQ612wcNm6mXDqDhTNegGFcvTV7vM", - Type: types.AccountTypeContract, + Address: "KT1S5iPRQ612wcNm6mXDqDhTNegGFcvTV7vM", + Type: types.AccountTypeContract, + Level: 1068669, + OperationsCount: 1, + LastAction: timestamp, }, Destination: account.Account{ - Address: "KT19nHqEWZxFFbbDL1b7Y86escgEN7qUShGo", - Type: types.AccountTypeContract, + Address: "KT19nHqEWZxFFbbDL1b7Y86escgEN7qUShGo", + Type: types.AccountTypeContract, + Level: 1068669, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Status: types.OperationStatusApplied, @@ -538,20 +570,29 @@ func TestGroup_Parse(t *testing.T) { StorageSize: 5460, ProtocolID: 1, Initiator: account.Account{ - Address: "tz1aSPEN4RTZbn4aXEsxDiix38dDmacGQ8sq", - Type: types.AccountTypeTz, + Address: "tz1aSPEN4RTZbn4aXEsxDiix38dDmacGQ8sq", + Type: types.AccountTypeTz, + Level: 1068669, + OperationsCount: 1, + LastAction: timestamp, }, Parameters: []byte("{\"entrypoint\":\"validateAccounts\",\"value\":{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"bytes\":\"0000a2560a416161def96031630886abe950c4baf036\"},{\"bytes\":\"0000fdf98b65d53a9661e07f41093dcb6f3d931736ba\"}]},{\"prim\":\"Pair\",\"args\":[{\"int\":\"14151000\"},{\"int\":\"0\"}]}]},{\"prim\":\"Pair\",\"args\":[{\"prim\":\"True\"},{\"prim\":\"Pair\",\"args\":[{\"int\":\"8010000\"},{\"int\":\"18000000\"}]}]}]},{\"bytes\":\"01796ad78734892d5ae4186e84a30290040732ada70076616c696461746552756c6573\"}]}}"), DeffatedStorage: []byte("{\"int\":\"61\"}"), }, { Kind: types.OperationKindTransaction, Source: account.Account{ - Address: "KT19nHqEWZxFFbbDL1b7Y86escgEN7qUShGo", - Type: types.AccountTypeContract, + Address: "KT19nHqEWZxFFbbDL1b7Y86escgEN7qUShGo", + Type: types.AccountTypeContract, + Level: 1068669, + OperationsCount: 1, + LastAction: timestamp, }, Destination: account.Account{ - Address: "KT1KemKUx79keZgFW756jQrqKcZJ21y4SPdS", - Type: types.AccountTypeContract, + Address: "KT1KemKUx79keZgFW756jQrqKcZJ21y4SPdS", + Type: types.AccountTypeContract, + Level: 1068669, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Status: types.OperationStatusApplied, @@ -569,8 +610,11 @@ func TestGroup_Parse(t *testing.T) { ConsumedGas: 3505300, ProtocolID: 1, Initiator: account.Account{ - Address: "tz1aSPEN4RTZbn4aXEsxDiix38dDmacGQ8sq", - Type: types.AccountTypeTz, + Address: "tz1aSPEN4RTZbn4aXEsxDiix38dDmacGQ8sq", + Type: types.AccountTypeTz, + Level: 1068669, + OperationsCount: 1, + LastAction: timestamp, }, Parameters: []byte("{\"entrypoint\":\"validateRules\",\"value\":{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"prim\":\"None\"},{\"string\":\"US\"}]},{\"prim\":\"Pair\",\"args\":[{\"prim\":\"False\"},{\"bytes\":\"000056d8b91b541c9d20d51f929dcccca2f14928f1dc\"}]}]},{\"int\":\"2\"}]},{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"prim\":\"None\"},{\"string\":\"US\"}]},{\"prim\":\"Pair\",\"args\":[{\"prim\":\"False\"},{\"bytes\":\"0000c644b537bdb0dac40fe742010106546effd69395\"}]}]},{\"int\":\"6\"}]}]},{\"prim\":\"Pair\",\"args\":[{\"bytes\":\"0000a2560a416161def96031630886abe950c4baf036\"},{\"bytes\":\"0000fdf98b65d53a9661e07f41093dcb6f3d931736ba\"}]}]},{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"int\":\"14151000\"},{\"int\":\"0\"}]},{\"prim\":\"True\"}]}]},{\"prim\":\"Pair\",\"args\":[{\"bytes\":\"01bff38c4e363eacef338f7b2e15f00ca42fafa1ce00\"},{\"prim\":\"Pair\",\"args\":[{\"int\":\"8010000\"},{\"int\":\"18000000\"}]}]}]}}"), DeffatedStorage: []byte("{\"prim\":\"Pair\",\"args\":[{\"prim\":\"Pair\",\"args\":[{\"bytes\":\"000056d8b91b541c9d20d51f929dcccca2f14928f1dc\"},{\"bytes\":\"010d25f77b84dc2164a5d1ce5e8a5d3ca2b1d0cbf900\"}]},[]]}"), @@ -649,12 +693,18 @@ func TestGroup_Parse(t *testing.T) { Level: 1151495, Kind: types.OperationKindTransaction, Initiator: account.Account{ - Address: "tz1dMH7tW7RhdvVMR4wKVFF1Ke8m8ZDvrTTE", - Type: types.AccountTypeTz, + Address: "tz1dMH7tW7RhdvVMR4wKVFF1Ke8m8ZDvrTTE", + Type: types.AccountTypeTz, + Level: 1151495, + OperationsCount: 1, + LastAction: timestamp, }, Source: account.Account{ - Address: "tz1dMH7tW7RhdvVMR4wKVFF1Ke8m8ZDvrTTE", - Type: types.AccountTypeTz, + Address: "tz1dMH7tW7RhdvVMR4wKVFF1Ke8m8ZDvrTTE", + Type: types.AccountTypeTz, + Level: 1151495, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Fee: 43074, @@ -664,8 +714,11 @@ func TestGroup_Parse(t *testing.T) { StorageSize: 2976, StorageLimit: 47, Destination: account.Account{ - Address: "KT1Ap287P1NzsnToSJdA4aqSNjPomRaHBZSr", - Type: types.AccountTypeContract, + Address: "KT1Ap287P1NzsnToSJdA4aqSNjPomRaHBZSr", + Type: types.AccountTypeContract, + Level: 1151495, + OperationsCount: 1, + LastAction: timestamp, }, Parameters: []byte("{\"entrypoint\":\"redeem\",\"value\":{\"bytes\":\"a874aac22777351417c9bde0920cc7ed33e54453e1dd149a1f3a60521358d19a\"}}"), Entrypoint: types.NullString{ @@ -695,17 +748,26 @@ func TestGroup_Parse(t *testing.T) { Level: 1151495, Kind: types.OperationKindTransaction, Initiator: account.Account{ - Address: "tz1dMH7tW7RhdvVMR4wKVFF1Ke8m8ZDvrTTE", - Type: types.AccountTypeTz, + Address: "tz1dMH7tW7RhdvVMR4wKVFF1Ke8m8ZDvrTTE", + Type: types.AccountTypeTz, + Level: 1151495, + OperationsCount: 1, + LastAction: timestamp, }, Source: account.Account{ - Address: "KT1Ap287P1NzsnToSJdA4aqSNjPomRaHBZSr", - Type: types.AccountTypeContract, + Address: "KT1Ap287P1NzsnToSJdA4aqSNjPomRaHBZSr", + Type: types.AccountTypeContract, + Level: 1151495, + OperationsCount: 1, + LastAction: timestamp, }, Counter: 6909186, Destination: account.Account{ - Address: "KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn", - Type: types.AccountTypeContract, + Address: "KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn", + Type: types.AccountTypeContract, + Level: 1151495, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Parameters: []byte("{\"entrypoint\":\"transfer\",\"value\":{\"prim\":\"Pair\",\"args\":[{\"bytes\":\"011871cfab6dafee00330602b4342b6500c874c93b00\"},{\"prim\":\"Pair\",\"args\":[{\"bytes\":\"0000c2473c617946ce7b9f6843f193401203851cb2ec\"},{\"int\":\"7874880\"}]}]}}"), @@ -834,12 +896,18 @@ func TestGroup_Parse(t *testing.T) { Level: 86142, Kind: types.OperationKindOrigination, Initiator: account.Account{ - Address: "tz1SX7SPdx4ZJb6uP5Hh5XBVZhh9wTfFaud3", - Type: types.AccountTypeTz, + Address: "tz1SX7SPdx4ZJb6uP5Hh5XBVZhh9wTfFaud3", + Type: types.AccountTypeTz, + Level: 86142, + OperationsCount: 1, + LastAction: timestamp, }, Source: account.Account{ - Address: "tz1SX7SPdx4ZJb6uP5Hh5XBVZhh9wTfFaud3", - Type: types.AccountTypeTz, + Address: "tz1SX7SPdx4ZJb6uP5Hh5XBVZhh9wTfFaud3", + Type: types.AccountTypeTz, + Level: 86142, + OperationsCount: 1, + LastAction: timestamp, }, Fee: 510, Counter: 654594, @@ -847,8 +915,11 @@ func TestGroup_Parse(t *testing.T) { StorageLimit: 371, Amount: 0, Destination: account.Account{ - Address: "KT1NppzrgyLZD3aku7fssfhYPm5QqZwyabvR", - Type: types.AccountTypeContract, + Address: "KT1NppzrgyLZD3aku7fssfhYPm5QqZwyabvR", + Type: types.AccountTypeContract, + Level: 86142, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Burned: 87750, @@ -856,17 +927,32 @@ func TestGroup_Parse(t *testing.T) { DeffatedStorage: []byte("{\"int\":\"0\"}\n"), }, }, + Accounts: map[string]*account.Account{ + "KT1NppzrgyLZD3aku7fssfhYPm5QqZwyabvR": { + Address: "KT1NppzrgyLZD3aku7fssfhYPm5QqZwyabvR", + Type: types.AccountTypeContract, + Level: 86142, + OperationsCount: 1, + LastAction: timestamp, + }, + }, Contracts: []*modelContract.Contract{ { Level: 86142, Timestamp: timestamp, Account: account.Account{ - Address: "KT1NppzrgyLZD3aku7fssfhYPm5QqZwyabvR", - Type: types.AccountTypeContract, + Address: "KT1NppzrgyLZD3aku7fssfhYPm5QqZwyabvR", + Type: types.AccountTypeContract, + Level: 86142, + OperationsCount: 1, + LastAction: timestamp, }, Manager: account.Account{ - Address: "tz1SX7SPdx4ZJb6uP5Hh5XBVZhh9wTfFaud3", - Type: types.AccountTypeTz, + Address: "tz1SX7SPdx4ZJb6uP5Hh5XBVZhh9wTfFaud3", + Type: types.AccountTypeTz, + Level: 86142, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Babylon: modelContract.Script{ @@ -924,30 +1010,35 @@ func TestGroup_Parse(t *testing.T) { { Kind: types.OperationKindOrigination, Source: account.Account{ - - Address: "tz1MXrEgDNnR8PDryN8sq4B2m9Pqcf57wBqM", - Type: types.AccountTypeTz, + Address: "tz1MXrEgDNnR8PDryN8sq4B2m9Pqcf57wBqM", + Type: types.AccountTypeTz, + Level: 301436, + OperationsCount: 1, + LastAction: timestamp, }, Fee: 1555, Counter: 983250, GasLimit: 12251, StorageLimit: 351, Destination: account.Account{ - - Address: "KT1AbjG7vtpV8osdoJXcMRck8eTwst8dWoz4", - Type: types.AccountTypeContract, + Address: "KT1AbjG7vtpV8osdoJXcMRck8eTwst8dWoz4", + Type: types.AccountTypeContract, + Level: 301436, + OperationsCount: 1, + LastAction: timestamp, }, - Delegate: account.Account{}, - Status: types.OperationStatusApplied, - Level: 301436, - + Delegate: account.Account{}, + Status: types.OperationStatusApplied, + Level: 301436, Hash: encoding.MustDecodeBase58("onv6Q1dNejAGEJeQzwRannWsDSGw85FuFdhLnBrY18TBcC9p8kC"), Timestamp: timestamp, Burned: 331000, Initiator: account.Account{ - - Address: "tz1MXrEgDNnR8PDryN8sq4B2m9Pqcf57wBqM", - Type: types.AccountTypeTz, + Address: "tz1MXrEgDNnR8PDryN8sq4B2m9Pqcf57wBqM", + Type: types.AccountTypeTz, + Level: 301436, + OperationsCount: 1, + LastAction: timestamp, }, ProtocolID: 2, DeffatedStorage: []byte("[]"), @@ -960,14 +1051,18 @@ func TestGroup_Parse(t *testing.T) { Level: 301436, Timestamp: timestamp, Account: account.Account{ - - Address: "KT1AbjG7vtpV8osdoJXcMRck8eTwst8dWoz4", - Type: types.AccountTypeContract, + Address: "KT1AbjG7vtpV8osdoJXcMRck8eTwst8dWoz4", + Type: types.AccountTypeContract, + Level: 301436, + OperationsCount: 1, + LastAction: timestamp, }, Manager: account.Account{ - - Address: "tz1MXrEgDNnR8PDryN8sq4B2m9Pqcf57wBqM", - Type: types.AccountTypeTz, + Address: "tz1MXrEgDNnR8PDryN8sq4B2m9Pqcf57wBqM", + Type: types.AccountTypeTz, + Level: 301436, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Alpha: modelContract.Script{ @@ -1027,16 +1122,22 @@ func TestGroup_Parse(t *testing.T) { { Kind: types.OperationKindTransaction, Source: account.Account{ - Address: "tz1gXhGAXgKvrXjn4t16rYUXocqbch1XXJFN", - Type: types.AccountTypeTz, + Address: "tz1gXhGAXgKvrXjn4t16rYUXocqbch1XXJFN", + Type: types.AccountTypeTz, + Level: 72207, + OperationsCount: 1, + LastAction: timestamp, }, Fee: 4045, Counter: 155670, GasLimit: 37831, StorageLimit: 5265, Destination: account.Account{ - Address: "KT1C2MfcjWb5R1ZDDxVULCsGuxrf5fEn5264", - Type: types.AccountTypeContract, + Address: "KT1C2MfcjWb5R1ZDDxVULCsGuxrf5fEn5264", + Type: types.AccountTypeContract, + Level: 72207, + OperationsCount: 1, + LastAction: timestamp, }, Status: types.OperationStatusApplied, Level: 72207, @@ -1047,8 +1148,11 @@ func TestGroup_Parse(t *testing.T) { Valid: true, }, Initiator: account.Account{ - Address: "tz1gXhGAXgKvrXjn4t16rYUXocqbch1XXJFN", - Type: types.AccountTypeTz, + Address: "tz1gXhGAXgKvrXjn4t16rYUXocqbch1XXJFN", + Type: types.AccountTypeTz, + Level: 72207, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Parameters: []byte("{\"entrypoint\":\"default\",\"value\":{\"prim\":\"Right\",\"args\":[{\"prim\":\"Unit\"}]}}"), @@ -1084,13 +1188,19 @@ func TestGroup_Parse(t *testing.T) { }, { Kind: types.OperationKindOrigination, Source: account.Account{ - Address: "KT1C2MfcjWb5R1ZDDxVULCsGuxrf5fEn5264", - Type: types.AccountTypeContract, + Address: "KT1C2MfcjWb5R1ZDDxVULCsGuxrf5fEn5264", + Type: types.AccountTypeContract, + Level: 72207, + OperationsCount: 1, + LastAction: timestamp, }, Nonce: testsuite.Ptr[int64](0), Destination: account.Account{ - Address: "KT1JgHoXtZPjVfG82BY3FSys2VJhKVZo2EJU", - Type: types.AccountTypeContract, + Address: "KT1JgHoXtZPjVfG82BY3FSys2VJhKVZo2EJU", + Type: types.AccountTypeContract, + Level: 72207, + OperationsCount: 1, + LastAction: timestamp, }, Status: types.OperationStatusApplied, Level: 72207, @@ -1100,8 +1210,11 @@ func TestGroup_Parse(t *testing.T) { Counter: 155670, Internal: true, Initiator: account.Account{ - Address: "tz1gXhGAXgKvrXjn4t16rYUXocqbch1XXJFN", - Type: types.AccountTypeTz, + Address: "tz1gXhGAXgKvrXjn4t16rYUXocqbch1XXJFN", + Type: types.AccountTypeTz, + Level: 72207, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, ProtocolID: 3, @@ -1146,12 +1259,18 @@ func TestGroup_Parse(t *testing.T) { Level: 72207, Timestamp: timestamp, Account: account.Account{ - Address: "KT1JgHoXtZPjVfG82BY3FSys2VJhKVZo2EJU", - Type: types.AccountTypeContract, + Address: "KT1JgHoXtZPjVfG82BY3FSys2VJhKVZo2EJU", + Type: types.AccountTypeContract, + Level: 72207, + OperationsCount: 1, + LastAction: timestamp, }, Manager: account.Account{ - Address: "KT1C2MfcjWb5R1ZDDxVULCsGuxrf5fEn5264", - Type: types.AccountTypeContract, + Address: "KT1C2MfcjWb5R1ZDDxVULCsGuxrf5fEn5264", + Type: types.AccountTypeContract, + Level: 72207, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Babylon: modelContract.Script{ @@ -1211,20 +1330,24 @@ func TestGroup_Parse(t *testing.T) { { Kind: types.OperationKindTransaction, Source: account.Account{ - - Address: "tz1aCzsYRUgDZBV7zb7Si6q2AobrocFW5qwb", - Type: types.AccountTypeTz, + Address: "tz1aCzsYRUgDZBV7zb7Si6q2AobrocFW5qwb", + Type: types.AccountTypeTz, + Level: 1516349, + OperationsCount: 1, + LastAction: timestamp, }, Fee: 2235, Counter: 9432992, GasLimit: 18553, Destination: account.Account{ - Address: "KT1QcxwB4QyPKfmSwjH1VRxa6kquUjeDWeEy", - Type: types.AccountTypeContract, + Address: "KT1QcxwB4QyPKfmSwjH1VRxa6kquUjeDWeEy", + Type: types.AccountTypeContract, + Level: 1516349, + OperationsCount: 1, + LastAction: timestamp, }, - Status: types.OperationStatusApplied, - Level: 1516349, - + Status: types.OperationStatusApplied, + Level: 1516349, Hash: encoding.MustDecodeBase58("ooz1bkCQeYsZYP7vb4Dx7pYPRpWN11Z3G3yP1v4HAfdNXuHRv9c"), Timestamp: timestamp, Entrypoint: types.NullString{ @@ -1233,8 +1356,11 @@ func TestGroup_Parse(t *testing.T) { }, Tags: types.FA2Tag | types.LedgerTag, Initiator: account.Account{ - Address: "tz1aCzsYRUgDZBV7zb7Si6q2AobrocFW5qwb", - Type: types.AccountTypeTz, + Address: "tz1aCzsYRUgDZBV7zb7Si6q2AobrocFW5qwb", + Type: types.AccountTypeTz, + Level: 1516349, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Parameters: []byte(`{"entrypoint":"transfer","value":[{"prim":"Pair","args":[{"string":"tz1aCzsYRUgDZBV7zb7Si6q2AobrocFW5qwb"},[{"prim":"Pair","args":[{"string":"tz1a6ZKyEoCmfpsY74jEq6uKBK8RQXdj1aVi"},{"prim":"Pair","args":[{"int":"12"},{"int":"1"}]}]}]]}]}`), @@ -1309,7 +1435,6 @@ func TestGroup_Parse(t *testing.T) { want: &parsers.TestStore{ BigMapState: []*bigmapdiff.BigMapState{ { - Ptr: 1264, Contract: "KT1GBZmSxmnKJXGMdMLbugPfLyUPmuLSMwKS", LastUpdateLevel: 1520888, @@ -1324,14 +1449,18 @@ func TestGroup_Parse(t *testing.T) { Kind: types.OperationKindTransaction, Hash: encoding.MustDecodeBase58("oocFt4vkkgQGfoRH54328cJUbDdWvj3x6KEs5Arm4XhqwwJmnJ8"), Source: account.Account{ - - Address: "tz1WKygtstVY96oyc6Rmk945dMf33LeihgWT", - Type: types.AccountTypeTz, + Address: "tz1WKygtstVY96oyc6Rmk945dMf33LeihgWT", + Type: types.AccountTypeTz, + Level: 1520888, + OperationsCount: 1, + LastAction: timestamp, }, Initiator: account.Account{ - - Address: "tz1WKygtstVY96oyc6Rmk945dMf33LeihgWT", - Type: types.AccountTypeTz, + Address: "tz1WKygtstVY96oyc6Rmk945dMf33LeihgWT", + Type: types.AccountTypeTz, + Level: 1520888, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Status: types.OperationStatusApplied, @@ -1349,9 +1478,11 @@ func TestGroup_Parse(t *testing.T) { }, ProtocolID: 4, Destination: account.Account{ - - Address: "KT1H1MqmUM4aK9i1833EBmYCCEfkbt6ZdSBc", - Type: types.AccountTypeContract, + Address: "KT1H1MqmUM4aK9i1833EBmYCCEfkbt6ZdSBc", + Type: types.AccountTypeContract, + Level: 1520888, + OperationsCount: 1, + LastAction: timestamp, }, Parameters: []byte(`{"entrypoint":"update_record","value":{"prim":"Pair","args":[{"bytes":"62616c6c732e74657a"},{"prim":"Pair","args":[{"prim":"Some","args":[{"string":"tz1dDQc4KsTHEFe3USc66Wti2pBatZ3UDbD4"}]},{"prim":"Pair","args":[{"string":"tz1WKygtstVY96oyc6Rmk945dMf33LeihgWT"},[]]}]}]}}`), DeffatedStorage: []byte(`{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"01535d971759846a1f2be8610e36f2db40fe8ce40800"},{"int":"1268"}]},{"bytes":"01ebb657570e494e8a7bd43ac3bf7cfd0267a32a9f00"}]}`), @@ -1372,16 +1503,25 @@ func TestGroup_Parse(t *testing.T) { Valid: true, }, Initiator: account.Account{ - Address: "tz1WKygtstVY96oyc6Rmk945dMf33LeihgWT", - Type: types.AccountTypeTz, + Address: "tz1WKygtstVY96oyc6Rmk945dMf33LeihgWT", + Type: types.AccountTypeTz, + Level: 1520888, + OperationsCount: 1, + LastAction: timestamp, }, Source: account.Account{ - Address: "KT1H1MqmUM4aK9i1833EBmYCCEfkbt6ZdSBc", - Type: types.AccountTypeContract, + Address: "KT1H1MqmUM4aK9i1833EBmYCCEfkbt6ZdSBc", + Type: types.AccountTypeContract, + Level: 1520888, + OperationsCount: 1, + LastAction: timestamp, }, Destination: account.Account{ - Address: "KT1GBZmSxmnKJXGMdMLbugPfLyUPmuLSMwKS", - Type: types.AccountTypeContract, + Address: "KT1GBZmSxmnKJXGMdMLbugPfLyUPmuLSMwKS", + Type: types.AccountTypeContract, + Level: 1520888, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Parameters: []byte(`{"entrypoint":"execute","value":{"prim":"Pair","args":[{"string":"UpdateRecord"},{"prim":"Pair","args":[{"bytes":"0507070a0000000962616c6c732e74657a070705090a000000160000c0ca282a775946b5ecbe02e5cf73e25f6b62b70c07070a000000160000753f63893674b6d523f925f0d787bf9270b95c330200000000"},{"bytes":"0000753f63893674b6d523f925f0d787bf9270b95c33"}]}]}}`), @@ -1442,12 +1582,18 @@ func TestGroup_Parse(t *testing.T) { Kind: types.OperationKindRegisterGlobalConstant, Hash: encoding.MustDecodeBase58("ooffKPL6WmMgqzLGtRtLp2HdEbVL3K2fVzKQLyxsBFMC84wpjRt"), Source: account.Account{ - Address: "tz1SMARcpWCydHsGgz4MRoK9NkbpBmmUAfNe", - Type: types.AccountTypeTz, + Address: "tz1SMARcpWCydHsGgz4MRoK9NkbpBmmUAfNe", + Type: types.AccountTypeTz, + Level: 15400, + OperationsCount: 1, + LastAction: timestamp, }, Initiator: account.Account{ - Address: "tz1SMARcpWCydHsGgz4MRoK9NkbpBmmUAfNe", - Type: types.AccountTypeTz, + Address: "tz1SMARcpWCydHsGgz4MRoK9NkbpBmmUAfNe", + Type: types.AccountTypeTz, + Level: 15400, + OperationsCount: 1, + LastAction: timestamp, }, Status: types.OperationStatusApplied, Fee: 377, @@ -1514,16 +1660,25 @@ func TestGroup_Parse(t *testing.T) { Kind: types.OperationKindTransaction, Hash: encoding.MustDecodeBase58("oozvzXiZmVW9QtYjKmDuYqoHNCEvt32FwM2cUgQee2S1SGWgumA"), Source: account.Account{ - Address: "tz1RiUE3Ao53juAz4uDYx1J3tHJMye6jPfhp", - Type: types.AccountTypeTz, + Address: "tz1RiUE3Ao53juAz4uDYx1J3tHJMye6jPfhp", + Type: types.AccountTypeTz, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Destination: account.Account{ - Address: "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", - Type: types.AccountTypeContract, + Address: "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", + Type: types.AccountTypeContract, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Initiator: account.Account{ - Address: "tz1RiUE3Ao53juAz4uDYx1J3tHJMye6jPfhp", - Type: types.AccountTypeTz, + Address: "tz1RiUE3Ao53juAz4uDYx1J3tHJMye6jPfhp", + Type: types.AccountTypeTz, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Status: types.OperationStatusApplied, Fee: 4175, @@ -1556,16 +1711,25 @@ func TestGroup_Parse(t *testing.T) { Kind: types.OperationKindTransaction, Hash: encoding.MustDecodeBase58("oozvzXiZmVW9QtYjKmDuYqoHNCEvt32FwM2cUgQee2S1SGWgumA"), Source: account.Account{ - Address: "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", - Type: types.AccountTypeContract, + Address: "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", + Type: types.AccountTypeContract, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Destination: account.Account{ - Address: "KT19H9YbHqsxFTayap7aTEfbcnyPeALKYgt9", - Type: types.AccountTypeContract, + Address: "KT19H9YbHqsxFTayap7aTEfbcnyPeALKYgt9", + Type: types.AccountTypeContract, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Initiator: account.Account{ - Address: "tz1RiUE3Ao53juAz4uDYx1J3tHJMye6jPfhp", - Type: types.AccountTypeTz, + Address: "tz1RiUE3Ao53juAz4uDYx1J3tHJMye6jPfhp", + Type: types.AccountTypeTz, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Status: types.OperationStatusApplied, Nonce: testsuite.Ptr[int64](2), @@ -1602,16 +1766,25 @@ func TestGroup_Parse(t *testing.T) { Kind: types.OperationKindTransaction, Hash: encoding.MustDecodeBase58("oozvzXiZmVW9QtYjKmDuYqoHNCEvt32FwM2cUgQee2S1SGWgumA"), Source: account.Account{ - Address: "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", - Type: types.AccountTypeContract, + Address: "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", + Type: types.AccountTypeContract, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Destination: account.Account{ - Address: "KT19H9YbHqsxFTayap7aTEfbcnyPeALKYgt9", - Type: types.AccountTypeContract, + Address: "KT19H9YbHqsxFTayap7aTEfbcnyPeALKYgt9", + Type: types.AccountTypeContract, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Initiator: account.Account{ - Address: "tz1RiUE3Ao53juAz4uDYx1J3tHJMye6jPfhp", - Type: types.AccountTypeTz, + Address: "tz1RiUE3Ao53juAz4uDYx1J3tHJMye6jPfhp", + Type: types.AccountTypeTz, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Status: types.OperationStatusApplied, Nonce: testsuite.Ptr[int64](1), @@ -1652,16 +1825,25 @@ func TestGroup_Parse(t *testing.T) { Kind: types.OperationKindOrigination, Hash: encoding.MustDecodeBase58("oozvzXiZmVW9QtYjKmDuYqoHNCEvt32FwM2cUgQee2S1SGWgumA"), Source: account.Account{ - Address: "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", - Type: types.AccountTypeContract, + Address: "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", + Type: types.AccountTypeContract, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Destination: account.Account{ - Address: "KT1BM1SyQnTzNU1J8TZv5Mdj4ScuTgNKH5uj", - Type: types.AccountTypeContract, + Address: "KT1BM1SyQnTzNU1J8TZv5Mdj4ScuTgNKH5uj", + Type: types.AccountTypeContract, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Initiator: account.Account{ - Address: "tz1RiUE3Ao53juAz4uDYx1J3tHJMye6jPfhp", - Type: types.AccountTypeTz, + Address: "tz1RiUE3Ao53juAz4uDYx1J3tHJMye6jPfhp", + Type: types.AccountTypeTz, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Status: types.OperationStatusApplied, Nonce: testsuite.Ptr[int64](0), @@ -1920,21 +2102,34 @@ func TestGroup_Parse(t *testing.T) { Contract: "KT1BM1SyQnTzNU1J8TZv5Mdj4ScuTgNKH5uj", }, }, - + Accounts: map[string]*account.Account{ + "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6": { + Address: "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", + Type: types.AccountTypeContract, + Level: 381735, + OperationsCount: 4, + LastAction: timestamp, + }, + }, Contracts: []*modelContract.Contract{ { Timestamp: timestamp, Level: 381735, Account: account.Account{ - Address: "KT1BM1SyQnTzNU1J8TZv5Mdj4ScuTgNKH5uj", - Type: types.AccountTypeContract, + Address: "KT1BM1SyQnTzNU1J8TZv5Mdj4ScuTgNKH5uj", + Type: types.AccountTypeContract, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, Manager: account.Account{ - Address: "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", - Type: types.AccountTypeContract, + Address: "KT1Jk8LRDoj6LkopYZwRq5ZEWBhYv8nVc6e6", + Type: types.AccountTypeContract, + Level: 381735, + OperationsCount: 1, + LastAction: timestamp, }, - Tags: 16640, - LastAction: timestamp, + Tags: 16640, Babylon: modelContract.Script{ Hash: "c52584fb0678ae8b5f7e8021899b7c96060bbbe15c26cc52a3fa122f25262105", FailStrings: []string{ @@ -2116,9 +2311,11 @@ func TestGroup_Parse(t *testing.T) { { Kind: types.OperationKindOrigination, Source: account.Account{ - - Address: "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb", - Type: types.AccountTypeTz, + Address: "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb", + Type: types.AccountTypeTz, + Level: 707452, + OperationsCount: 1, + LastAction: timestamp, }, Fee: 724, Counter: 12837, @@ -2127,16 +2324,22 @@ func TestGroup_Parse(t *testing.T) { Burned: 386000, AllocatedDestinationContractBurned: 257000, Destination: account.Account{ - Address: "KT1KRzp5hckBwLLswCreweLMdueL3jJhTN1S", - Type: types.AccountTypeContract, + Address: "KT1KRzp5hckBwLLswCreweLMdueL3jJhTN1S", + Type: types.AccountTypeContract, + Level: 707452, + OperationsCount: 1, + LastAction: timestamp, }, Status: types.OperationStatusApplied, Level: 707452, Hash: encoding.MustDecodeBase58("opPDkVe1nU5xqLyoWYQ2r6H7PaJM5S4Pe4WtTmEE7UMQAwfnuiJ"), Timestamp: timestamp, Initiator: account.Account{ - Address: "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb", - Type: types.AccountTypeTz, + Address: "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb", + Type: types.AccountTypeTz, + Level: 707452, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, ProtocolID: 6, @@ -2146,14 +2349,20 @@ func TestGroup_Parse(t *testing.T) { Contracts: []*modelContract.Contract{ { Account: account.Account{ - Address: "KT1KRzp5hckBwLLswCreweLMdueL3jJhTN1S", - Type: types.AccountTypeContract, + Address: "KT1KRzp5hckBwLLswCreweLMdueL3jJhTN1S", + Type: types.AccountTypeContract, + Level: 707452, + OperationsCount: 1, + LastAction: timestamp, }, Level: 707452, Timestamp: timestamp, Manager: account.Account{ - Address: "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb", - Type: types.AccountTypeTz, + Address: "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb", + Type: types.AccountTypeTz, + Level: 707452, + OperationsCount: 1, + LastAction: timestamp, }, Delegate: account.Account{}, Babylon: modelContract.Script{ @@ -2177,6 +2386,192 @@ func TestGroup_Parse(t *testing.T) { }, }, }, + }, { + name: "oozKKBjBK44uGCrMcT6wwPbUD62mF7ddenwXSyJKJAAiSRxq4JQ", + ctx: &config.Context{ + RPC: rpc, + Storage: generalRepo, + Contracts: contractRepo, + BigMapDiffs: bmdRepo, + Blocks: blockRepo, + Protocols: protoRepo, + Operations: operaitonsRepo, + Scripts: scriptRepo, + GlobalConstants: globalConstantRepo, + Cache: cache.NewCache( + rpc, accountsRepo, contractRepo, protoRepo, + ), + }, + paramsOpts: []ParseParamsOption{ + WithHead(noderpc.Header{ + Timestamp: timestamp, + Protocol: "PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf", + Level: 1616868, + ChainID: "NetXyuzvDo2Ugzb", + }), + WithProtocol(&protocol.Protocol{ + Constants: &protocol.Constants{ + CostPerByte: 1000, + HardGasLimitPerOperation: 400000, + HardStorageLimitPerOperation: 60000, + TimeBetweenBlocks: 60, + }, + Hash: "PtNairobiyssHuh87hEhfVBGCVrK3WnS8Z2FT4ymB5tAa4r1nQf", + ID: 7, + SymLink: bcd.SymLinkJakarta, + }), + }, + storage: map[string]int64{}, + filename: "./data/rpc/opg/oozKKBjBK44uGCrMcT6wwPbUD62mF7ddenwXSyJKJAAiSRxq4JQ.json", + want: &parsers.TestStore{ + Operations: []*operation.Operation{ + { + Kind: types.OperationKindTransferTicket, + Source: account.Account{ + Address: "tz2UUqEaKhW3p7T7QvBSxd4jz2Kzc28oBvC7", + Type: types.AccountTypeTz, + Level: 1616868, + OperationsCount: 1, + LastAction: timestamp, + }, + Fee: 668, + Counter: 666002, + GasLimit: 3295, + StorageLimit: 110, + Burned: 0, + Entrypoint: types.NewNullString(testsuite.Ptr("save")), + Destination: account.Account{ + Address: "KT1MYutYhGoyCRf9y2JqfWoLKPJ3zMiDmMhE", + Type: types.AccountTypeContract, + Level: 1616868, + OperationsCount: 1, + LastAction: timestamp, + }, + Status: types.OperationStatusApplied, + Level: 1616868, + Hash: encoding.MustDecodeBase58("oozKKBjBK44uGCrMcT6wwPbUD62mF7ddenwXSyJKJAAiSRxq4JQ"), + Timestamp: timestamp, + Initiator: account.Account{ + Address: "tz2UUqEaKhW3p7T7QvBSxd4jz2Kzc28oBvC7", + Type: types.AccountTypeTz, + Level: 1616868, + OperationsCount: 1, + LastAction: timestamp, + }, + Delegate: account.Account{}, + ProtocolID: 7, + TicketUpdatesCount: 1, + TicketUpdates: []*ticket.TicketUpdate{ + { + Account: account.Account{ + Address: "tz2UUqEaKhW3p7T7QvBSxd4jz2Kzc28oBvC7", + Type: types.AccountTypeTz, + Level: 1616868, + LastAction: timestamp, + }, + Amount: decimal.RequireFromString("-1"), + Level: 1616868, + Timestamp: timestamp, + Ticket: ticket.Ticket{ + Level: 1616868, + Ticketer: account.Account{ + Address: "KT1Nux298EEiVoTzF7jQS3iBV3K4ShN8ucSP", + Type: types.AccountTypeContract, + Level: 1616868, + TicketUpdatesCount: 1, + LastAction: timestamp, + }, + ContentType: []byte(`{"prim":"string"}`), + Content: []byte(`{"string":"Ticket"}`), + UpdatesCount: 1, + }, + }, + }, + }, { + Kind: types.OperationKindTransaction, + Source: account.Account{ + Address: "tz2UUqEaKhW3p7T7QvBSxd4jz2Kzc28oBvC7", + Type: types.AccountTypeTz, + Level: 1616868, + OperationsCount: 1, + LastAction: timestamp, + }, + Counter: 666002, + Nonce: testsuite.Ptr(int64(0)), + Amount: 0, + ConsumedGas: 1912189, + StorageSize: 238, + PaidStorageSizeDiff: 44, + Internal: true, + Entrypoint: types.NewNullString(testsuite.Ptr("save")), + Destination: account.Account{ + Address: "KT1MYutYhGoyCRf9y2JqfWoLKPJ3zMiDmMhE", + Type: types.AccountTypeContract, + Level: 1616868, + OperationsCount: 1, + LastAction: timestamp, + }, + Status: types.OperationStatusApplied, + Level: 1616868, + Hash: encoding.MustDecodeBase58("oozKKBjBK44uGCrMcT6wwPbUD62mF7ddenwXSyJKJAAiSRxq4JQ"), + Timestamp: timestamp, + Initiator: account.Account{ + Address: "tz2UUqEaKhW3p7T7QvBSxd4jz2Kzc28oBvC7", + Type: types.AccountTypeTz, + Level: 1616868, + OperationsCount: 1, + LastAction: timestamp, + }, + Delegate: account.Account{}, + ProtocolID: 7, + TicketUpdatesCount: 1, + Burned: 44000, + Parameters: []byte(`{"entrypoint":"save","value":{"prim":"Pair","args":[{"bytes":"019d326434ec72a63f89180ef9cd739b59706efb3e00"},{"prim":"Pair","args":[{"string":"Ticket"},{"int":"1"}]}]}}`), + DeffatedStorage: []byte(`[{"prim":"Pair","args":[{"bytes":"019d326434ec72a63f89180ef9cd739b59706efb3e00"},{"prim":"Pair","args":[{"string":"Ticket"},{"int":"1"}]}]}]`), + TicketUpdates: []*ticket.TicketUpdate{ + { + Account: account.Account{ + Address: "KT1MYutYhGoyCRf9y2JqfWoLKPJ3zMiDmMhE", + Type: types.AccountTypeContract, + Level: 1616868, + LastAction: timestamp, + }, + Amount: decimal.RequireFromString("1"), + Level: 1616868, + Timestamp: timestamp, + Ticket: ticket.Ticket{ + Level: 1616868, + Ticketer: account.Account{ + Address: "KT1Nux298EEiVoTzF7jQS3iBV3K4ShN8ucSP", + Type: types.AccountTypeContract, + Level: 1616868, + LastAction: timestamp, + TicketUpdatesCount: 1, + }, + ContentType: []byte(`{"prim":"string"}`), + Content: []byte(`{"string":"Ticket"}`), + UpdatesCount: 1, + }, + }, + }, + }, + }, + Tickets: map[string]*ticket.Ticket{ + "44f09c8c9d1135c11c71f31ab4126d464cad6067010e1d440e4749331450d860": { + Level: 1616868, + Ticketer: account.Account{ + Address: "KT1Nux298EEiVoTzF7jQS3iBV3K4ShN8ucSP", + Type: types.AccountTypeContract, + Level: 1616868, + TicketUpdatesCount: 1, + LastAction: timestamp, + }, + ContentType: []byte(`{"prim":"string"}`), + Content: []byte(`{"string":"Ticket"}`), + UpdatesCount: 2, + }, + }, + }, }, } @@ -2199,12 +2594,12 @@ func TestGroup_Parse(t *testing.T) { err := readJSONFile(tt.filename, &op) require.NoError(t, err) - parseParams, err := NewParseParams(tt.ctx, tt.paramsOpts...) + parseParams, err := NewParseParams(context.Background(), tt.ctx, tt.paramsOpts...) require.NoError(t, err) store := parsers.NewTestStore() - err = NewGroup(parseParams).Parse(op, store) - require.Equal(t, tt.wantErr, err != nil) + err = NewGroup(parseParams).Parse(context.Background(), op, store) + require.Equal(t, tt.wantErr, err != nil, err) if err == nil { compareParserResponse(t, store, tt.want) } diff --git a/internal/parsers/operations/origination.go b/internal/parsers/operations/origination.go index a2af3f2cf..0574d91f1 100644 --- a/internal/parsers/operations/origination.go +++ b/internal/parsers/operations/origination.go @@ -23,10 +23,13 @@ func NewOrigination(params *ParseParams) Origination { var delegatorContract = []byte(`{"code":[{"prim":"parameter","args":[{"prim":"or","args":[{"prim":"lambda","args":[{"prim":"unit"},{"prim":"list","args":[{"prim":"operation"}]}],"annots":["%do"]},{"prim":"unit","annots":["%default"]}]}]},{"prim":"storage","args":[{"prim":"key_hash"}]},{"prim":"code","args":[[[[{"prim":"DUP"},{"prim":"CAR"},{"prim":"DIP","args":[[{"prim":"CDR"}]]}]],{"prim":"IF_LEFT","args":[[{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"0"}]},{"prim":"AMOUNT"},[[{"prim":"COMPARE"},{"prim":"EQ"}],{"prim":"IF","args":[[],[[{"prim":"UNIT"},{"prim":"FAILWITH"}]]]}],[{"prim":"DIP","args":[[{"prim":"DUP"}]]},{"prim":"SWAP"}],{"prim":"IMPLICIT_ACCOUNT"},{"prim":"ADDRESS"},{"prim":"SENDER"},[[{"prim":"COMPARE"},{"prim":"EQ"}],{"prim":"IF","args":[[],[[{"prim":"UNIT"},{"prim":"FAILWITH"}]]]}],{"prim":"UNIT"},{"prim":"EXEC"},{"prim":"PAIR"}],[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PAIR"}]]}]]}],"storage":{"bytes":"0079943a60100e0394ac1c8f6ccfaeee71ec9c2d94"}}`) // Parse - -func (p Origination) Parse(data noderpc.Operation, store parsers.Store) error { +func (p Origination) Parse(ctx context.Context, data noderpc.Operation, store parsers.Store) error { source := account.Account{ - Address: data.Source, - Type: types.NewAccountType(data.Source), + Address: data.Source, + Type: types.NewAccountType(data.Source), + Level: p.head.Level, + OperationsCount: 1, + LastAction: p.head.Timestamp, } origination := operation.Operation{ @@ -43,8 +46,10 @@ func (p Origination) Parse(data noderpc.Operation, store parsers.Store) error { StorageLimit: data.StorageLimit, Amount: *data.Balance, Delegate: account.Account{ - Address: data.Delegate, - Type: types.NewAccountType(data.Delegate), + Address: data.Delegate, + Type: types.NewAccountType(data.Delegate), + Level: p.head.Level, + LastAction: p.head.Timestamp, }, Parameters: data.Parameters, Nonce: data.Nonce, @@ -58,19 +63,24 @@ func (p Origination) Parse(data noderpc.Operation, store parsers.Store) error { p.fillInternal(&origination) - parseOperationResult(data, &origination) + parseOperationResult(data, &origination, store) origination.SetBurned(*p.protocol.Constants) p.stackTrace.Add(origination) if origination.IsApplied() { - if err := p.appliedHandler(context.Background(), data, &origination, store); err != nil { + if err := p.appliedHandler(ctx, data, &origination, store); err != nil { return err } + store.AddAccounts(origination.Destination) } store.AddOperations(&origination) + store.AddAccounts( + origination.Source, + origination.Delegate, + ) return nil } @@ -88,16 +98,16 @@ func (p Origination) appliedHandler(ctx context.Context, item noderpc.Operation, origination.DeffatedStorage = rawStorage } - if err := p.specific.ContractParser.Parse(origination, store); err != nil { + if err := p.specific.ContractParser.Parse(ctx, origination, store); err != nil { return err } contracts := store.ListContracts() - if err := setTags(p.ctx, contracts[0], origination); err != nil { + if err := setTags(ctx, p.ctx, contracts[0], origination); err != nil { return err } - if err := p.specific.StorageParser.ParseOrigination(item, origination, store); err != nil { + if err := p.specific.StorageParser.ParseOrigination(ctx, item, origination, store); err != nil { return err } diff --git a/internal/parsers/operations/params.go b/internal/parsers/operations/params.go index e3f6de0a2..a6d2ef6bf 100644 --- a/internal/parsers/operations/params.go +++ b/internal/parsers/operations/params.go @@ -1,6 +1,8 @@ package operations import ( + "context" + "github.com/baking-bad/bcdhub/internal/bcd" "github.com/baking-bad/bcdhub/internal/config" "github.com/baking-bad/bcdhub/internal/models/operation" @@ -67,25 +69,25 @@ func WithMainOperation(main *operation.Operation) ParseParamsOption { } // NewParseParams - -func NewParseParams(ctx *config.Context, opts ...ParseParamsOption) (*ParseParams, error) { +func NewParseParams(ctx context.Context, configContext *config.Context, opts ...ParseParamsOption) (*ParseParams, error) { params := &ParseParams{ - ctx: ctx, + ctx: configContext, stackTrace: stacktrace.New(), - withEvents: ctx.Network == types.Mainnet, + withEvents: configContext.Network == types.Mainnet, } for i := range opts { opts[i](params) } if params.protocol == nil { - proto, err := ctx.Protocols.Get(bcd.GetCurrentProtocol(), 0) + proto, err := configContext.Protocols.Get(ctx, bcd.GetCurrentProtocol(), 0) if err != nil { return nil, err } params.protocol = &proto } - specific, err := protocols.Get(ctx, params.protocol.Hash) + specific, err := protocols.Get(configContext, params.protocol.Hash) if err != nil { return nil, err } diff --git a/internal/parsers/operations/register_global_constant.go b/internal/parsers/operations/register_global_constant.go index 35a70aa49..a8540e88d 100644 --- a/internal/parsers/operations/register_global_constant.go +++ b/internal/parsers/operations/register_global_constant.go @@ -1,6 +1,8 @@ package operations import ( + "context" + "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/types" @@ -19,10 +21,13 @@ func NewRegisterGlobalConstant(params *ParseParams) RegisterGlobalConstant { } // Parse - -func (p RegisterGlobalConstant) Parse(data noderpc.Operation, store parsers.Store) error { +func (p RegisterGlobalConstant) Parse(ctx context.Context, data noderpc.Operation, store parsers.Store) error { source := account.Account{ - Address: data.Source, - Type: types.NewAccountType(data.Source), + Address: data.Source, + Type: types.NewAccountType(data.Source), + Level: p.head.Level, + OperationsCount: 1, + LastAction: p.head.Timestamp, } registerGlobalConstant := operation.Operation{ @@ -40,12 +45,13 @@ func (p RegisterGlobalConstant) Parse(data noderpc.Operation, store parsers.Stor Nonce: data.Nonce, ContentIndex: p.contentIdx, } - parseOperationResult(data, ®isterGlobalConstant) + parseOperationResult(data, ®isterGlobalConstant, store) p.stackTrace.Add(registerGlobalConstant) store.AddOperations(®isterGlobalConstant) if registerGlobalConstant.IsApplied() { store.AddGlobalConstants(NewGlobalConstant().Parse(data, registerGlobalConstant)) } + store.AddAccounts(registerGlobalConstant.Source) return nil } diff --git a/internal/parsers/operations/result.go b/internal/parsers/operations/result.go index 679d749ab..a91409a3b 100644 --- a/internal/parsers/operations/result.go +++ b/internal/parsers/operations/result.go @@ -7,9 +7,10 @@ import ( "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" + "github.com/baking-bad/bcdhub/internal/parsers" ) -func parseOperationResult(data noderpc.Operation, tx *operation.Operation) { +func parseOperationResult(data noderpc.Operation, tx *operation.Operation, store parsers.Store) { result := data.GetResult() if result == nil { return @@ -31,15 +32,21 @@ func parseOperationResult(data noderpc.Operation, tx *operation.Operation) { } if len(result.Originated) > 0 { tx.Destination = account.Account{ - Address: result.Originated[0], - Type: types.AccountTypeContract, + Address: result.Originated[0], + Type: types.AccountTypeContract, + Level: tx.Level, + OperationsCount: 1, + LastAction: tx.Timestamp, } } if len(result.OriginatedRollup) > 0 { tx.Destination = account.Account{ - Address: result.OriginatedRollup, - Type: types.AccountTypeRollup, + Address: result.OriginatedRollup, + Type: types.AccountTypeRollup, + Level: tx.Level, + OperationsCount: 1, + LastAction: tx.Timestamp, } } @@ -53,6 +60,6 @@ func parseOperationResult(data noderpc.Operation, tx *operation.Operation) { } if tx.IsApplied() { - new(TicketUpdateParser).Parse(result, tx) + new(TicketUpdateParser).Parse(result, tx, store) } } diff --git a/internal/parsers/operations/result_test.go b/internal/parsers/operations/result_test.go index 944ca2999..6baf46397 100644 --- a/internal/parsers/operations/result_test.go +++ b/internal/parsers/operations/result_test.go @@ -8,6 +8,7 @@ import ( "github.com/baking-bad/bcdhub/internal/models/ticket" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" + "github.com/baking-bad/bcdhub/internal/parsers" "github.com/stretchr/testify/require" ) @@ -23,7 +24,7 @@ func Test_parseOperationResult(t *testing.T) { want: operation.Operation{ Status: types.OperationStatusApplied, ConsumedGas: 1020700, - TickerUpdates: make([]*ticket.TicketUpdate, 0), + TicketUpdates: make([]*ticket.TicketUpdate, 0), }, }, { name: "test 2", @@ -31,7 +32,7 @@ func Test_parseOperationResult(t *testing.T) { want: operation.Operation{ Status: types.OperationStatusApplied, ConsumedGas: 1020700, - TickerUpdates: make([]*ticket.TicketUpdate, 0), + TicketUpdates: make([]*ticket.TicketUpdate, 0), }, }, { name: "test 3", @@ -42,10 +43,11 @@ func Test_parseOperationResult(t *testing.T) { StorageSize: 232, PaidStorageSizeDiff: 232, Destination: account.Account{ - Address: "KT1FVhijNC7ZBL5EjcetiKddDQ2n98t8w4jo", - Type: types.AccountTypeContract, + Address: "KT1FVhijNC7ZBL5EjcetiKddDQ2n98t8w4jo", + Type: types.AccountTypeContract, + OperationsCount: 1, }, - TickerUpdates: make([]*ticket.TicketUpdate, 0), + TicketUpdates: make([]*ticket.TicketUpdate, 0), }, }, } @@ -55,8 +57,10 @@ func Test_parseOperationResult(t *testing.T) { err := readJSONFile(tt.fileName, &op) require.NoError(t, err) + store := parsers.NewTestStore() + var res operation.Operation - parseOperationResult(op, &res) + parseOperationResult(op, &res, store) require.Equal(t, tt.want, res) }) } diff --git a/internal/parsers/operations/smart_rollup.go b/internal/parsers/operations/smart_rollup.go index 0bbf3386c..b12b46028 100644 --- a/internal/parsers/operations/smart_rollup.go +++ b/internal/parsers/operations/smart_rollup.go @@ -24,8 +24,11 @@ func (sr SmartRolupParser) Parse(data noderpc.Operation, operation operation.Ope result := data.GetResult() rollup := smartrollup.SmartRollup{ Address: account.Account{ - Address: result.Address, - Type: types.NewAccountType(result.Address), + Address: result.Address, + Type: types.NewAccountType(result.Address), + Level: operation.Level, + OperationsCount: 1, + LastAction: operation.Timestamp, }, GenesisCommitmentHash: result.GenesisCommitmentHash, PvmKind: data.PvmKind, diff --git a/internal/parsers/operations/sr_execute_outbox_message.go b/internal/parsers/operations/sr_execute_outbox_message.go index 21583014c..98db83b81 100644 --- a/internal/parsers/operations/sr_execute_outbox_message.go +++ b/internal/parsers/operations/sr_execute_outbox_message.go @@ -1,6 +1,7 @@ package operations import ( + "context" "encoding/hex" "github.com/baking-bad/bcdhub/internal/bcd/encoding" @@ -23,10 +24,13 @@ func NewSrExecuteOutboxMessage(params *ParseParams) SrExecuteOutboxMessage { } // Parse - -func (p SrExecuteOutboxMessage) Parse(data noderpc.Operation, store parsers.Store) error { +func (p SrExecuteOutboxMessage) Parse(ctx context.Context, data noderpc.Operation, store parsers.Store) error { source := account.Account{ - Address: data.Source, - Type: types.NewAccountType(data.Source), + Address: data.Source, + Type: types.NewAccountType(data.Source), + Level: p.head.Level, + OperationsCount: 1, + LastAction: p.head.Timestamp, } operation := operation.Operation{ @@ -46,13 +50,17 @@ func (p SrExecuteOutboxMessage) Parse(data noderpc.Operation, store parsers.Stor } if data.Rollup != nil { operation.Destination = account.Account{ - Address: *data.Rollup, - Type: types.NewAccountType(*data.Rollup), + Address: *data.Rollup, + Type: types.NewAccountType(*data.Rollup), + Level: p.head.Level, + OperationsCount: 1, + LastAction: p.head.Timestamp, } + store.AddAccounts(operation.Destination) } p.fillInternal(&operation) operation.SetBurned(*p.protocol.Constants) - parseOperationResult(data, &operation) + parseOperationResult(data, &operation, store) p.stackTrace.Add(operation) if operation.IsApplied() { @@ -70,6 +78,7 @@ func (p SrExecuteOutboxMessage) Parse(data noderpc.Operation, store parsers.Stor } store.AddOperations(&operation) + store.AddAccounts(operation.Source) return nil } diff --git a/internal/parsers/operations/sr_originate.go b/internal/parsers/operations/sr_originate.go index e9216476f..ea02a2c61 100644 --- a/internal/parsers/operations/sr_originate.go +++ b/internal/parsers/operations/sr_originate.go @@ -1,6 +1,8 @@ package operations import ( + "context" + "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/types" @@ -19,10 +21,13 @@ func NewSrOriginate(params *ParseParams) SrOriginate { } // Parse - -func (p SrOriginate) Parse(data noderpc.Operation, store parsers.Store) error { +func (p SrOriginate) Parse(ctx context.Context, data noderpc.Operation, store parsers.Store) error { source := account.Account{ - Address: data.Source, - Type: types.NewAccountType(data.Source), + Address: data.Source, + Type: types.NewAccountType(data.Source), + Level: p.head.Level, + OperationsCount: 1, + LastAction: p.head.Timestamp, } operation := operation.Operation{ @@ -42,7 +47,7 @@ func (p SrOriginate) Parse(data noderpc.Operation, store parsers.Store) error { p.fillInternal(&operation) operation.SetBurned(*p.protocol.Constants) - parseOperationResult(data, &operation) + parseOperationResult(data, &operation, store) p.stackTrace.Add(operation) store.AddOperations(&operation) @@ -53,9 +58,12 @@ func (p SrOriginate) Parse(data noderpc.Operation, store parsers.Store) error { return err } store.AddSmartRollups(&smartRollup) + store.AddAccounts(smartRollup.Address) operation.Destination = smartRollup.Address } + store.AddAccounts(operation.Source) + return nil } diff --git a/internal/parsers/operations/tag.go b/internal/parsers/operations/tag.go index 4e0e4149a..f4529df2d 100644 --- a/internal/parsers/operations/tag.go +++ b/internal/parsers/operations/tag.go @@ -1,22 +1,24 @@ package operations import ( + "context" + "github.com/baking-bad/bcdhub/internal/config" "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/types" ) -func setTags(ctx *config.Context, contract *contract.Contract, op *operation.Operation) error { +func setTags(ctx context.Context, configCtx *config.Context, contract *contract.Contract, op *operation.Operation) error { if op.Destination.Type != types.AccountTypeContract { return nil } var tags types.Tags if contract == nil { - c, err := ctx.Cache.ContractTags(op.Destination.Address) + c, err := configCtx.Cache.ContractTags(ctx, op.Destination.Address) if err != nil { - if ctx.Storage.IsRecordNotFound(err) { + if configCtx.Storage.IsRecordNotFound(err) { return nil } return err diff --git a/internal/parsers/operations/test/contracts/KT1MYutYhGoyCRf9y2JqfWoLKPJ3zMiDmMhE_babylon.json b/internal/parsers/operations/test/contracts/KT1MYutYhGoyCRf9y2JqfWoLKPJ3zMiDmMhE_babylon.json new file mode 100644 index 000000000..927805567 --- /dev/null +++ b/internal/parsers/operations/test/contracts/KT1MYutYhGoyCRf9y2JqfWoLKPJ3zMiDmMhE_babylon.json @@ -0,0 +1 @@ +[{"prim":"parameter","args":[{"prim":"or","args":[{"prim":"ticket","args":[{"prim":"string"}],"annots":["%save"]},{"prim":"address","annots":["%send"]}]}]},{"prim":"storage","args":[{"prim":"list","args":[{"prim":"ticket","args":[{"prim":"string"}]}]}]},{"prim":"code","args":[[{"prim":"UNPAIR"},{"prim":"IF_LEFT","args":[[{"prim":"CONS"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PAIR"}],[{"prim":"SWAP"},{"prim":"IF_CONS","args":[[{"prim":"DIG","args":[{"int":"2"}]},{"prim":"CONTRACT","args":[{"prim":"ticket","args":[{"prim":"string"}]}],"annots":["%ticket"]},[{"prim":"IF_NONE","args":[[[{"prim":"UNIT"},{"prim":"FAILWITH"}]],[]]}],{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"0"}]},{"prim":"DIG","args":[{"int":"2"}]},{"prim":"TRANSFER_TOKENS"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"SWAP"},{"prim":"CONS"},{"prim":"PAIR"}],[{"prim":"PUSH","args":[{"prim":"string"},{"string":"no ticket to send"}]},{"prim":"FAILWITH"}]]}]]}]]}] \ No newline at end of file diff --git a/internal/parsers/operations/test_common.go b/internal/parsers/operations/test_common.go index 2049f0720..1a5646fa7 100644 --- a/internal/parsers/operations/test_common.go +++ b/internal/parsers/operations/test_common.go @@ -11,10 +11,12 @@ import ( "github.com/baking-bad/bcdhub/internal/bcd" "github.com/baking-bad/bcdhub/internal/bcd/consts" astContract "github.com/baking-bad/bcdhub/internal/bcd/contract" + "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/bigmapaction" "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/ticket" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" "github.com/baking-bad/bcdhub/internal/parsers" @@ -53,7 +55,7 @@ func readRPCScript(_ context.Context, address string, _ int64) (noderpc.Script, return script, errors.Errorf("unknown RPC script: %s", address) } -func readTestScriptModel(address, symLink string) (contract.Script, error) { +func readTestScriptModel(_ context.Context, address, symLink string) (contract.Script, error) { data, err := readTestScript(address, bcd.SymLinkBabylon) if err != nil { return contract.Script{}, err @@ -85,7 +87,7 @@ func readTestScriptModel(address, symLink string) (contract.Script, error) { }, nil } -func readTestScriptPart(address, symLink, part string) ([]byte, error) { +func readTestScriptPart(_ context.Context, address, symLink, part string) ([]byte, error) { data, err := readTestScript(address, bcd.SymLinkBabylon) if err != nil { return nil, err @@ -106,7 +108,7 @@ func readTestScriptPart(address, symLink, part string) ([]byte, error) { return nil, nil } -func readTestContractModel(address string) (contract.Contract, error) { +func readTestContractModel(_ context.Context, address string) (contract.Contract, error) { var c contract.Contract f, err := os.Open(fmt.Sprintf("./data/models/contract/%s.json", address)) if err != nil { @@ -124,6 +126,7 @@ func compareParserResponse(t *testing.T, got, want *parsers.TestStore) { require.Len(t, got.Migrations, len(want.Migrations)) require.Len(t, got.Operations, len(want.Operations)) require.Len(t, got.GlobalConstants, len(want.GlobalConstants)) + require.Len(t, got.Tickets, len(want.Tickets)) for i := range got.Contracts { compareContract(t, want.Contracts[i], got.Contracts[i]) @@ -140,6 +143,22 @@ func compareParserResponse(t *testing.T, got, want *parsers.TestStore) { for i := range got.GlobalConstants { require.Equal(t, want.GlobalConstants[i], got.GlobalConstants[i]) } + for hash := range got.Tickets { + require.Equal(t, want.Tickets[hash], got.Tickets[hash]) + } + for key, wantAddress := range want.Accounts { + gotAddress, ok := got.Accounts[key] + require.True(t, ok) + require.Equal(t, wantAddress, gotAddress) + } +} + +func compareAddress(t *testing.T, want, got account.Account) { + if want.Address == "" && got.Address == "" { + return + } + + require.Equal(t, want, got) } func compareOperations(t *testing.T, want, got *operation.Operation) { @@ -159,16 +178,17 @@ func compareOperations(t *testing.T, want, got *operation.Operation) { require.Equal(t, want.Hash, got.Hash) require.EqualValues(t, want.Status, got.Status) require.EqualValues(t, want.Kind, got.Kind) - require.Equal(t, want.Initiator, got.Initiator) - require.Equal(t, want.Source, got.Source) - require.Equal(t, want.Destination, got.Destination) - require.Equal(t, want.Delegate, got.Delegate) + compareAddress(t, want.Initiator, got.Initiator) + compareAddress(t, want.Source, got.Source) + compareAddress(t, want.Destination, got.Destination) + compareAddress(t, want.Delegate, got.Delegate) require.Equal(t, want.Entrypoint, got.Entrypoint) compareBytesArray(t, want.Parameters, got.Parameters) compareBytesArray(t, want.DeffatedStorage, got.DeffatedStorage) require.EqualValues(t, want.Tags, got.Tags) require.Len(t, got.BigMapDiffs, len(want.BigMapDiffs)) require.Len(t, got.BigMapActions, len(want.BigMapActions)) + require.Len(t, got.TicketUpdates, len(want.TicketUpdates)) for i := range want.BigMapDiffs { compareBigMapDiff(t, want.BigMapDiffs[i], got.BigMapDiffs[i]) @@ -177,6 +197,17 @@ func compareOperations(t *testing.T, want, got *operation.Operation) { for i := range want.BigMapActions { compareBigMapAction(t, want.BigMapActions[i], got.BigMapActions[i]) } + + for i := range want.TicketUpdates { + compareTicketUpdates(t, want.TicketUpdates[i], got.TicketUpdates[i]) + } +} + +func compareTicketUpdates(t *testing.T, want, got *ticket.TicketUpdate) { + require.EqualValues(t, want.Account, got.Account) + require.EqualValues(t, want.Ticket, got.Ticket) + require.EqualValues(t, want.Level, got.Level) + require.EqualValues(t, want.Timestamp, got.Timestamp) } func compareBigMapDiff(t *testing.T, want, got *bigmapdiff.BigMapDiff) { diff --git a/internal/parsers/operations/ticket_updates.go b/internal/parsers/operations/ticket_updates.go index a3998336b..a49a9ad24 100644 --- a/internal/parsers/operations/ticket_updates.go +++ b/internal/parsers/operations/ticket_updates.go @@ -6,6 +6,7 @@ import ( "github.com/baking-bad/bcdhub/internal/models/ticket" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/noderpc" + "github.com/baking-bad/bcdhub/internal/parsers" "github.com/shopspring/decimal" ) @@ -13,40 +14,59 @@ import ( type TicketUpdateParser struct { } -func (p *TicketUpdateParser) Parse(data *noderpc.OperationResult, operation *operation.Operation) { +func (p *TicketUpdateParser) Parse(data *noderpc.OperationResult, operation *operation.Operation, store parsers.Store) { if data == nil { return } - operation.TickerUpdates = make([]*ticket.TicketUpdate, 0) + operation.TicketUpdates = make([]*ticket.TicketUpdate, 0) for i := range data.TicketUpdates { - tckt := p.toModel(data.TicketUpdates[i], operation) - operation.TickerUpdates = append(operation.TickerUpdates, tckt...) + tckt := p.toModel(data.TicketUpdates[i], operation, store) + operation.TicketUpdates = append(operation.TicketUpdates, tckt...) } for i := range data.TicketReceipt { - tckt := p.toModel(data.TicketReceipt[i], operation) - operation.TickerUpdates = append(operation.TickerUpdates, tckt...) + tckt := p.toModel(data.TicketReceipt[i], operation, store) + operation.TicketUpdates = append(operation.TicketUpdates, tckt...) } - operation.TicketUpdatesCount = len(operation.TickerUpdates) + operation.TicketUpdatesCount = len(operation.TicketUpdates) } -func (p *TicketUpdateParser) toModel(data noderpc.TicketUpdate, operation *operation.Operation) []*ticket.TicketUpdate { +func (p *TicketUpdateParser) toModel(data noderpc.TicketUpdate, operation *operation.Operation, store parsers.Store) []*ticket.TicketUpdate { + tckt := ticket.Ticket{ + ContentType: data.TicketToken.ContentType, + Content: data.TicketToken.Content, + Ticketer: account.Account{ + Address: data.TicketToken.Ticketer, + Type: types.NewAccountType(data.TicketToken.Ticketer), + Level: operation.Level, + LastAction: operation.Timestamp, + TicketUpdatesCount: 1, + }, + UpdatesCount: 1, + Level: operation.Level, + } + store.AddTickets(tckt) + updates := make([]*ticket.TicketUpdate, 0) for i := range data.Updates { - updates = append(updates, &ticket.TicketUpdate{ + update := ticket.TicketUpdate{ Level: operation.Level, Timestamp: operation.Timestamp, - Ticketer: account.Account{ - Address: data.TicketToken.Ticketer, - Type: types.NewAccountType(data.TicketToken.Ticketer), - }, - ContentType: data.TicketToken.ContentType, - Content: data.TicketToken.Content, + Ticket: tckt, Account: account.Account{ - Address: data.Updates[i].Account, - Type: types.NewAccountType(data.Updates[i].Account), + Address: data.Updates[i].Account, + Type: types.NewAccountType(data.Updates[i].Account), + LastAction: operation.Timestamp, + Level: operation.Level, }, Amount: decimal.RequireFromString(data.Updates[i].Amount), + } + updates = append(updates, &update) + store.AddAccounts(update.Account, tckt.Ticketer) + store.AddTicketBalances(ticket.Balance{ + Account: update.Account, + Ticket: tckt, + Amount: update.Amount.Copy(), }) } return updates diff --git a/internal/parsers/operations/transaction.go b/internal/parsers/operations/transaction.go index d255660b0..435297bc6 100644 --- a/internal/parsers/operations/transaction.go +++ b/internal/parsers/operations/transaction.go @@ -1,6 +1,8 @@ package operations import ( + "context" + "github.com/baking-bad/bcdhub/internal/bcd" "github.com/baking-bad/bcdhub/internal/bcd/ast" "github.com/baking-bad/bcdhub/internal/bcd/consts" @@ -28,10 +30,13 @@ func NewTransaction(params *ParseParams) Transaction { } // Parse - -func (p Transaction) Parse(data noderpc.Operation, store parsers.Store) error { +func (p Transaction) Parse(ctx context.Context, data noderpc.Operation, store parsers.Store) error { source := account.Account{ - Address: data.Source, - Type: modelsTypes.NewAccountType(data.Source), + Address: data.Source, + Type: modelsTypes.NewAccountType(data.Source), + Level: p.head.Level, + OperationsCount: 1, + LastAction: p.head.Timestamp, } tx := operation.Operation{ @@ -48,12 +53,17 @@ func (p Transaction) Parse(data noderpc.Operation, store parsers.Store) error { StorageLimit: data.StorageLimit, Amount: *data.Amount, Destination: account.Account{ - Address: *data.Destination, - Type: modelsTypes.NewAccountType(*data.Destination), + Address: *data.Destination, + Type: modelsTypes.NewAccountType(*data.Destination), + Level: p.head.Level, + OperationsCount: 1, + LastAction: p.head.Timestamp, }, Delegate: account.Account{ - Address: data.Delegate, - Type: modelsTypes.NewAccountType(data.Delegate), + Address: data.Delegate, + Type: modelsTypes.NewAccountType(data.Delegate), + Level: p.head.Level, + LastAction: p.head.Timestamp, }, Nonce: data.Nonce, Parameters: data.Parameters, @@ -62,15 +72,20 @@ func (p Transaction) Parse(data noderpc.Operation, store parsers.Store) error { p.fillInternal(&tx) - parseOperationResult(data, &tx) + parseOperationResult(data, &tx, store) tx.SetBurned(*p.protocol.Constants) store.AddOperations(&tx) + store.AddAccounts( + tx.Source, + tx.Delegate, + tx.Destination, + ) switch tx.Destination.Type { case modelsTypes.AccountTypeContract: - return p.parseContractParams(data, store, &tx) + return p.parseContractParams(ctx, data, store, &tx) case modelsTypes.AccountTypeSmartRollup: return p.parseSmartRollupParams(data, &tx) default: @@ -90,14 +105,14 @@ func (p Transaction) parseSmartRollupParams(data noderpc.Operation, tx *operatio return nil } -func (p Transaction) parseContractParams(data noderpc.Operation, store parsers.Store, tx *operation.Operation) error { +func (p Transaction) parseContractParams(ctx context.Context, data noderpc.Operation, store parsers.Store, tx *operation.Operation) error { for i := range tx.Errors { if tx.Errors[i].Is("contract.non_existing_contract") { return nil } } - scriptEntity, err := p.ctx.Contracts.Script(tx.Destination.Address, p.protocol.SymLink) + scriptEntity, err := p.ctx.Cache.Script(ctx, tx.Destination.Address, p.protocol.SymLink) if err != nil { if !tx.Internal { return nil @@ -142,7 +157,7 @@ func (p Transaction) parseContractParams(data noderpc.Operation, store parsers.S return err } - if err := setTags(p.ctx, nil, tx); err != nil { + if err := setTags(ctx, p.ctx, nil, tx); err != nil { return err } @@ -152,7 +167,7 @@ func (p Transaction) parseContractParams(data noderpc.Operation, store parsers.S p.stackTrace.Add(*tx) if tx.IsApplied() { - if err := p.appliedHandler(data, tx, store); err != nil { + if err := p.appliedHandler(ctx, data, tx, store); err != nil { return err } } @@ -173,12 +188,12 @@ func (p Transaction) fillInternal(tx *operation.Operation) { tx.Initiator = p.main.Source } -func (p Transaction) appliedHandler(item noderpc.Operation, tx *operation.Operation, store parsers.Store) error { - if err := p.specific.StorageParser.ParseTransaction(item, tx, store); err != nil { +func (p Transaction) appliedHandler(ctx context.Context, item noderpc.Operation, tx *operation.Operation, store parsers.Store) error { + if err := p.specific.StorageParser.ParseTransaction(ctx, item, tx, store); err != nil { return err } - return NewMigration(p.ctx.Contracts).Parse(item, tx, p.protocol.Hash, store) + return NewMigration(p.ctx.Contracts).Parse(ctx, item, tx, p.protocol.Hash, store) } func (p Transaction) getEntrypoint(tx *operation.Operation) error { diff --git a/internal/parsers/operations/transfer_ticket.go b/internal/parsers/operations/transfer_ticket.go index 80385e447..d7c007f59 100644 --- a/internal/parsers/operations/transfer_ticket.go +++ b/internal/parsers/operations/transfer_ticket.go @@ -1,6 +1,8 @@ package operations import ( + "context" + "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/types" @@ -19,10 +21,13 @@ func NewTransferTicket(params *ParseParams) TransferTicket { } // Parse - -func (p TransferTicket) Parse(data noderpc.Operation, store parsers.Store) error { +func (p TransferTicket) Parse(ctx context.Context, data noderpc.Operation, store parsers.Store) error { source := account.Account{ - Address: data.Source, - Type: types.NewAccountType(data.Source), + Address: data.Source, + Type: types.NewAccountType(data.Source), + Level: p.head.Level, + OperationsCount: 1, + LastAction: p.head.Timestamp, } transferTicket := operation.Operation{ @@ -45,17 +50,22 @@ func (p TransferTicket) Parse(data noderpc.Operation, store parsers.Store) error if data.Destination != nil { transferTicket.Destination = account.Account{ - Address: *data.Destination, - Type: types.NewAccountType(*data.Destination), + Address: *data.Destination, + Type: types.NewAccountType(*data.Destination), + Level: p.head.Level, + OperationsCount: 1, + LastAction: p.head.Timestamp, } + store.AddAccounts(transferTicket.Destination) } p.fillInternal(&transferTicket) transferTicket.SetBurned(*p.protocol.Constants) - parseOperationResult(data, &transferTicket) + parseOperationResult(data, &transferTicket, store) p.stackTrace.Add(transferTicket) store.AddOperations(&transferTicket) + store.AddAccounts(transferTicket.Source) return nil } diff --git a/internal/parsers/operations/tx_rollup_origination.go b/internal/parsers/operations/tx_rollup_origination.go index b5c2fde65..8c90c0648 100644 --- a/internal/parsers/operations/tx_rollup_origination.go +++ b/internal/parsers/operations/tx_rollup_origination.go @@ -1,6 +1,8 @@ package operations import ( + "context" + "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/types" @@ -19,10 +21,13 @@ func NewTxRollupOrigination(params *ParseParams) TxRollupOrigination { } // Parse - -func (p TxRollupOrigination) Parse(data noderpc.Operation, store parsers.Store) error { +func (p TxRollupOrigination) Parse(ctx context.Context, data noderpc.Operation, store parsers.Store) error { source := account.Account{ - Address: data.Source, - Type: types.NewAccountType(data.Source), + Address: data.Source, + Type: types.NewAccountType(data.Source), + Level: p.head.Level, + OperationsCount: 1, + LastAction: p.head.Timestamp, } txRollupOrigination := operation.Operation{ @@ -43,13 +48,18 @@ func (p TxRollupOrigination) Parse(data noderpc.Operation, store parsers.Store) p.fillInternal(&txRollupOrigination) - parseOperationResult(data, &txRollupOrigination) + parseOperationResult(data, &txRollupOrigination, store) txRollupOrigination.SetBurned(*p.protocol.Constants) p.stackTrace.Add(txRollupOrigination) store.AddOperations(&txRollupOrigination) + store.AddAccounts(txRollupOrigination.Source) + + if txRollupOrigination.IsApplied() { + store.AddAccounts(txRollupOrigination.Destination) + } return nil } diff --git a/cmd/indexer/indexer/protocol.go b/internal/parsers/protocols/functions.go similarity index 71% rename from cmd/indexer/indexer/protocol.go rename to internal/parsers/protocols/functions.go index b597c9c2a..7bffe898c 100644 --- a/cmd/indexer/indexer/protocol.go +++ b/internal/parsers/protocols/functions.go @@ -1,4 +1,4 @@ -package indexer +package protocols import ( "context" @@ -8,19 +8,18 @@ import ( "github.com/baking-bad/bcdhub/internal/noderpc" ) -func createProtocol(ctx context.Context, rpc noderpc.INode, chainID, hash string, level int64) (protocol protocol.Protocol, err error) { - protocol.SymLink, err = bcd.GetProtoSymLink(hash) +func Create(ctx context.Context, rpc noderpc.INode, head noderpc.Header) (protocol protocol.Protocol, err error) { + protocol.SymLink, err = bcd.GetProtoSymLink(head.Protocol) if err != nil { return } - protocol.Alias = hash[:8] - protocol.Hash = hash - protocol.StartLevel = level - protocol.ChainID = chainID + protocol.Alias = head.Protocol[:8] + protocol.Hash = head.Protocol + protocol.StartLevel = head.Level + protocol.ChainID = head.ChainID err = setProtocolConstants(ctx, rpc, &protocol) - return } diff --git a/internal/parsers/protocols/migration.go b/internal/parsers/protocols/migration.go new file mode 100644 index 000000000..d598d8211 --- /dev/null +++ b/internal/parsers/protocols/migration.go @@ -0,0 +1,202 @@ +package protocols + +import ( + "context" + + "github.com/baking-bad/bcdhub/internal/bcd" + "github.com/baking-bad/bcdhub/internal/config" + "github.com/baking-bad/bcdhub/internal/models" + "github.com/baking-bad/bcdhub/internal/models/protocol" + "github.com/baking-bad/bcdhub/internal/models/types" + "github.com/baking-bad/bcdhub/internal/noderpc" + "github.com/baking-bad/bcdhub/internal/parsers/migrations" + "github.com/baking-bad/bcdhub/internal/postgres/store" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" +) + +type Migration struct { + network types.Network + ctx *config.Context +} + +func NewMigration( + network types.Network, + ctx *config.Context, +) Migration { + return Migration{ + network: network, + ctx: ctx, + } +} + +func (m Migration) Do( + ctx context.Context, + tx models.Transaction, + currentProtocol protocol.Protocol, + head noderpc.Header, +) (protocol.Protocol, error) { + if err := m.finilizeProtocol(ctx, tx, currentProtocol, head); err != nil { + return currentProtocol, errors.Wrapf(err, "finalization of %s", currentProtocol.Hash) + } + + newProto, err := m.newProtocol(ctx, tx, head) + if err != nil { + return currentProtocol, errors.Wrapf(err, "creating new protocol: %s", head.Hash) + } + + if err := m.contractMigrations(ctx, tx, head, currentProtocol, newProto); err != nil { + return currentProtocol, errors.Wrapf(err, "contracts migration to new protocol: %s", head.Protocol) + } + + return newProto, nil +} + +func (m Migration) finilizeProtocol( + ctx context.Context, + tx models.Transaction, + proto protocol.Protocol, + head noderpc.Header, +) error { + if proto.EndLevel > 0 || head.Level == 1 { + return nil + } + log.Info(). + Str("network", m.network.String()). + Msgf("Finalizing the previous protocol: %s", proto.Alias) + + proto.EndLevel = head.Level - 1 + return tx.Protocol(ctx, &proto) +} + +func (m Migration) newProtocol( + ctx context.Context, + tx models.Transaction, + head noderpc.Header, +) (protocol.Protocol, error) { + log.Info(). + Str("network", m.network.String()). + Msgf("Creating new protocol %s starting at %d", head.Protocol, head.Level) + + newProtocol, err := Create(ctx, m.ctx.RPC, head) + if err != nil { + return newProtocol, err + } + err = tx.Protocol(ctx, &newProtocol) + return newProtocol, err +} + +func (m Migration) contractMigrations( + ctx context.Context, + tx models.Transaction, + head noderpc.Header, + currentProtocol protocol.Protocol, + newProtocol protocol.Protocol, +) error { + if head.Level == 1 { + return m.vestingMigration(ctx, tx, head, currentProtocol) + } + + if currentProtocol.SymLink == "" { + return errors.Errorf("[%s] Protocol should be initialized", m.network) + } + + if newProtocol.SymLink != currentProtocol.SymLink { + return m.standartMigration(ctx, currentProtocol, newProtocol, head, tx) + } + + log.Info(). + Str("network", m.network.String()). + Msgf("Same symlink %s for %s / %s", newProtocol.SymLink, currentProtocol.Alias, newProtocol.Alias) + + return nil +} + +func (m Migration) vestingMigration(ctx context.Context, tx models.Transaction, head noderpc.Header, currentProtocol protocol.Protocol) error { + addresses, err := m.ctx.RPC.GetContractsByBlock(ctx, head.Level) + if err != nil { + return err + } + + specific, err := Get(m.ctx, currentProtocol.Hash) + if err != nil { + return err + } + + p := migrations.NewVestingParser(m.ctx, specific.ContractParser, currentProtocol) + store := store.NewStore(m.ctx.StorageDB.DB, m.ctx.Stats) + + for _, address := range addresses { + if !bcd.IsContract(address) { + continue + } + + data, err := m.ctx.RPC.GetContractData(ctx, address, head.Level) + if err != nil { + return err + } + + if err := p.Parse(ctx, data, head, address, store); err != nil { + return err + } + } + + return store.Save(ctx) +} + +func (m Migration) standartMigration(ctx context.Context, currentProtocol, newProtocol protocol.Protocol, head noderpc.Header, tx models.Transaction) error { + log.Info().Str("network", m.network.String()).Msg("Try to find migrations...") + + contracts, err := m.ctx.Contracts.AllExceptDelegators(ctx) + if err != nil { + return err + } + log.Info().Str("network", m.network.String()).Msgf("Now %2d contracts are indexed", len(contracts)) + + specific, err := Get(m.ctx, newProtocol.Hash) + if err != nil { + return err + } + + for i := range contracts { + if !specific.MigrationParser.IsMigratable(contracts[i].Account.Address) && newProtocol.SymLink == bcd.SymLinkJakarta { + if err := tx.JakartaVesting(ctx, &contracts[i]); err != nil { + return errors.Wrap(err, "jakarta vesting migration error") + } + continue + } + + log.Info().Str("network", m.network.String()).Msgf("Migrate %s...", contracts[i].Account.Address) + script, err := m.ctx.RPC.GetScriptJSON(ctx, contracts[i].Account.Address, newProtocol.StartLevel) + if err != nil { + return err + } + + if err := specific.MigrationParser.Parse( + ctx, script, &contracts[i], currentProtocol, newProtocol, head.Timestamp, tx, + ); err != nil { + return err + } + + switch newProtocol.SymLink { + case bcd.SymLinkBabylon: + err = tx.BabylonUpdateNonDelegator(ctx, &contracts[i]) + case bcd.SymLinkJakarta: + err = tx.JakartaUpdateNonDelegator(ctx, &contracts[i]) + } + + if err != nil { + return errors.Wrapf(err, "migration of contract error: %s", contracts[i].Account.Address) + } + + } + + // only delegator contracts + switch newProtocol.SymLink { + case bcd.SymLinkBabylon: + err = tx.ToBabylon(ctx) + case bcd.SymLinkJakarta: + err = tx.ToJakarta(ctx) + } + return err +} diff --git a/internal/parsers/protocols/protocol.go b/internal/parsers/protocols/protocol.go index 08f4ebd0e..160d5c166 100644 --- a/internal/parsers/protocols/protocol.go +++ b/internal/parsers/protocols/protocol.go @@ -40,7 +40,7 @@ func Get(ctx *config.Context, protocol string) (*Specific, error) { return &Specific{ StorageParser: storage.NewBabylon(ctx.BigMapDiffs, ctx.Operations, ctx.Accounts), ContractParser: contract.NewBabylon(ctx), - MigrationParser: migrations.NewBabylon(ctx.BigMapDiffs), + MigrationParser: migrations.NewBabylon(), NeedReceiveRawStorage: true, }, nil case "PsCARTHAGazKbHtnKfLzQg3kms52kSRpgnDY982a9oYsSXRLQEb", diff --git a/internal/parsers/stacktrace/stacktrace.go b/internal/parsers/stacktrace/stacktrace.go index 50245f778..c8c3c4f39 100644 --- a/internal/parsers/stacktrace/stacktrace.go +++ b/internal/parsers/stacktrace/stacktrace.go @@ -5,9 +5,9 @@ import ( "io" "strings" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/models/types" + "github.com/rs/zerolog/log" ) // Item - @@ -153,7 +153,7 @@ func (st *StackTrace) String() string { } if err := st.print(topLevel, 1, &builder); err != nil { - logger.Err(err) + log.Err(err).Msg("print stacktrace") } return builder.String() } @@ -172,17 +172,3 @@ func (st *StackTrace) print(arr []int64, depth int, builder io.StringWriter) err } return nil } - -// Fill - -func (st *StackTrace) Fill(repo operation.Repository, op operation.Operation) error { - ops, err := repo.Get(map[string]interface{}{ - "hash": op.Hash, - }, 0, true) - if err != nil { - return err - } - for i := range ops { - st.Add(ops[i]) - } - return nil -} diff --git a/internal/parsers/storage/alpha.go b/internal/parsers/storage/alpha.go index 5f4af28c0..40555cf2d 100644 --- a/internal/parsers/storage/alpha.go +++ b/internal/parsers/storage/alpha.go @@ -1,6 +1,8 @@ package storage import ( + "context" + "github.com/baking-bad/bcdhub/internal/bcd/ast" "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" "github.com/baking-bad/bcdhub/internal/models/operation" @@ -18,7 +20,7 @@ func NewAlpha() *Alpha { } // ParseTransaction - -func (a *Alpha) ParseTransaction(content noderpc.Operation, operation *operation.Operation, store parsers.Store) error { +func (a *Alpha) ParseTransaction(ctx context.Context, content noderpc.Operation, operation *operation.Operation, store parsers.Store) error { result := content.GetResult() if result == nil { return nil @@ -29,7 +31,7 @@ func (a *Alpha) ParseTransaction(content noderpc.Operation, operation *operation } // ParseOrigination - -func (a *Alpha) ParseOrigination(content noderpc.Operation, operation *operation.Operation, store parsers.Store) error { +func (a *Alpha) ParseOrigination(ctx context.Context, content noderpc.Operation, operation *operation.Operation, store parsers.Store) error { if content.Script == nil { return nil } diff --git a/internal/parsers/storage/alpha_test.go b/internal/parsers/storage/alpha_test.go index 90f55f361..3df6ee580 100644 --- a/internal/parsers/storage/alpha_test.go +++ b/internal/parsers/storage/alpha_test.go @@ -1,6 +1,7 @@ package storage import ( + "context" "testing" "time" @@ -79,7 +80,7 @@ func TestAlpha_ParseOrigination(t *testing.T) { tt.args.operation.AST = tree store := parsers.NewTestStore() - err = a.ParseOrigination(content, &tt.args.operation, store) + err = a.ParseOrigination(context.Background(), content, &tt.args.operation, store) require.Equal(t, tt.wantErr, err != nil) if err != nil { return diff --git a/internal/parsers/storage/babylon.go b/internal/parsers/storage/babylon.go index bb721104c..9e9f67ad3 100644 --- a/internal/parsers/storage/babylon.go +++ b/internal/parsers/storage/babylon.go @@ -1,6 +1,8 @@ package storage import ( + "context" + "github.com/baking-bad/bcdhub/internal/bcd/ast" "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/bigmapaction" @@ -35,27 +37,27 @@ func NewBabylon(bigmapdiffs bigmapdiff.Repository, operations operation.Reposito } // ParseTransaction - -func (b *Babylon) ParseTransaction(content noderpc.Operation, operation *operation.Operation, store parsers.Store) error { +func (b *Babylon) ParseTransaction(ctx context.Context, content noderpc.Operation, operation *operation.Operation, store parsers.Store) error { result := content.GetResult() if result == nil { return nil } operation.DeffatedStorage = result.Storage - return b.handleBigMapDiff(result, *content.Destination, operation, result.Storage, store) + return b.handleBigMapDiff(ctx, result, *content.Destination, operation, result.Storage, store) } // ParseOrigination - -func (b *Babylon) ParseOrigination(content noderpc.Operation, operation *operation.Operation, store parsers.Store) error { +func (b *Babylon) ParseOrigination(ctx context.Context, content noderpc.Operation, operation *operation.Operation, store parsers.Store) error { result := content.GetResult() if result == nil { return nil } - return b.handleBigMapDiff(result, result.Originated[0], operation, operation.DeffatedStorage, store) + return b.handleBigMapDiff(ctx, result, result.Originated[0], operation, operation.DeffatedStorage, store) } -func (b *Babylon) initPointersTypes(result *noderpc.OperationResult, operation *operation.Operation, data []byte) error { +func (b *Babylon) initPointersTypes(ctx context.Context, result *noderpc.OperationResult, operation *operation.Operation, data []byte) error { level := operation.Level if operation.IsTransaction() && operation.Level >= 2 { level = operation.Level - 1 @@ -74,12 +76,12 @@ func (b *Babylon) initPointersTypes(result *noderpc.OperationResult, operation * return nil } - account, err := b.accounts.Get(operation.Destination.Address) + account, err := b.accounts.Get(ctx, operation.Destination.Address) if err != nil { return err } - operaiton, err := b.operations.Last(map[string]interface{}{ + operaiton, err := b.operations.Last(ctx, map[string]interface{}{ "destination_id": account.ID, "status": types.OperationStatusApplied, }, 0) @@ -137,16 +139,16 @@ func (b *Babylon) checkPointers(result *noderpc.OperationResult, storage *ast.Ty return nil } -func (b *Babylon) handleBigMapDiff(result *noderpc.OperationResult, address string, op *operation.Operation, storageData []byte, store parsers.Store) error { +func (b *Babylon) handleBigMapDiff(ctx context.Context, result *noderpc.OperationResult, address string, op *operation.Operation, storageData []byte, store parsers.Store) error { if len(result.BigMapDiffs) == 0 { return nil } - if err := b.initPointersTypes(result, op, storageData); err != nil { + if err := b.initPointersTypes(ctx, result, op, storageData); err != nil { return nil } - handlers := map[string]func(noderpc.BigMapDiff, string, *operation.Operation, parsers.Store) error{ + handlers := map[string]func(context.Context, noderpc.BigMapDiff, string, *operation.Operation, parsers.Store) error{ types.BigMapActionStringUpdate: b.handleBigMapDiffUpdate, types.BigMapActionStringCopy: b.handleBigMapDiffCopy, types.BigMapActionStringRemove: b.handleBigMapDiffRemove, @@ -160,7 +162,7 @@ func (b *Babylon) handleBigMapDiff(result *noderpc.OperationResult, address stri continue } - if err := handler(result.BigMapDiffs[i], address, op, store); err != nil { + if err := handler(ctx, result.BigMapDiffs[i], address, op, store); err != nil { return err } } @@ -169,7 +171,7 @@ func (b *Babylon) handleBigMapDiff(result *noderpc.OperationResult, address stri return nil } -func (b *Babylon) handleBigMapDiffUpdate(item noderpc.BigMapDiff, address string, operation *operation.Operation, store parsers.Store) error { +func (b *Babylon) handleBigMapDiffUpdate(_ context.Context, item noderpc.BigMapDiff, address string, operation *operation.Operation, store parsers.Store) error { ptr := *item.BigMap bmd := bigmapdiff.BigMapDiff{ @@ -195,7 +197,7 @@ func (b *Babylon) handleBigMapDiffUpdate(item noderpc.BigMapDiff, address string return nil } -func (b *Babylon) handleBigMapDiffCopy(item noderpc.BigMapDiff, address string, operation *operation.Operation, store parsers.Store) error { +func (b *Babylon) handleBigMapDiffCopy(ctx context.Context, item noderpc.BigMapDiff, address string, operation *operation.Operation, store parsers.Store) error { sourcePtr := *item.SourceBigMap destinationPtr := *item.DestBigMap @@ -215,7 +217,7 @@ func (b *Babylon) handleBigMapDiffCopy(item noderpc.BigMapDiff, address string, b.ptrMap[destinationPtr] = sourcePtr - bmd, err := b.getCopyBigMapDiff(sourcePtr, address) + bmd, err := b.getCopyBigMapDiff(ctx, sourcePtr, address) if err != nil { return err } @@ -244,12 +246,12 @@ func (b *Babylon) handleBigMapDiffCopy(item noderpc.BigMapDiff, address string, return nil } -func (b *Babylon) handleBigMapDiffRemove(item noderpc.BigMapDiff, address string, operation *operation.Operation, store parsers.Store) error { +func (b *Babylon) handleBigMapDiffRemove(ctx context.Context, item noderpc.BigMapDiff, address string, operation *operation.Operation, store parsers.Store) error { ptr := *item.BigMap if ptr < 0 { return nil } - states, err := b.bigmapdiffs.GetByPtr(address, ptr) + states, err := b.bigmapdiffs.GetByPtr(ctx, address, ptr) if err != nil { return err } @@ -269,7 +271,7 @@ func (b *Babylon) handleBigMapDiffRemove(item noderpc.BigMapDiff, address string return nil } -func (b *Babylon) handleBigMapDiffAlloc(item noderpc.BigMapDiff, address string, operation *operation.Operation, _ parsers.Store) error { +func (b *Babylon) handleBigMapDiffAlloc(_ context.Context, item noderpc.BigMapDiff, address string, operation *operation.Operation, _ parsers.Store) error { ptr := *item.BigMap if ptr > -1 { operation.BigMapActions = append(operation.BigMapActions, b.createBigMapDiffAction("alloc", address, &ptr, nil, operation)) @@ -338,9 +340,9 @@ func (b *Babylon) updateTemporaryPointers(src, dst int64) { b.temporaryPointers[dst] = dstBigMap } -func (b *Babylon) getCopyBigMapDiff(src int64, address string) (bmd []bigmapdiff.BigMapDiff, err error) { +func (b *Babylon) getCopyBigMapDiff(ctx context.Context, src int64, address string) (bmd []bigmapdiff.BigMapDiff, err error) { if src > -1 { - states, err := b.bigmapdiffs.GetByPtr(address, src) + states, err := b.bigmapdiffs.GetByPtr(ctx, address, src) if err != nil { return nil, err } diff --git a/internal/parsers/storage/babylon_test.go b/internal/parsers/storage/babylon_test.go index 1d5ae3942..6e2e20cfe 100644 --- a/internal/parsers/storage/babylon_test.go +++ b/internal/parsers/storage/babylon_test.go @@ -1,6 +1,7 @@ package storage import ( + "context" "testing" "github.com/baking-bad/bcdhub/internal/bcd/ast" @@ -89,7 +90,7 @@ func TestBabylon_ParseTransaction(t *testing.T) { repo. EXPECT(). - GetByPtr(gomock.Any(), gomock.Any()). + GetByPtr(gomock.Any(), gomock.Any(), gomock.Any()). Return([]bigmapdiff.BigMapState{}, nil). AnyTimes() @@ -102,7 +103,7 @@ func TestBabylon_ParseTransaction(t *testing.T) { tt.args.operation.AST = tree store := parsers.NewTestStore() - err = b.ParseTransaction(content, &tt.args.operation, store) + err = b.ParseTransaction(context.Background(), content, &tt.args.operation, store) require.Equal(t, tt.wantErr, err != nil) if err != nil { return diff --git a/internal/parsers/storage/big_map.go b/internal/parsers/storage/big_map.go index 967ceba27..d981feed9 100644 --- a/internal/parsers/storage/big_map.go +++ b/internal/parsers/storage/big_map.go @@ -23,7 +23,7 @@ func GetBigMapPtr(ctx context.Context, repo models.GeneralRepository, contracts if err != nil { return 0, err } - storageTypeByte, err := contracts.ScriptPart(address, symLink, consts.STORAGE) + storageTypeByte, err := contracts.ScriptPart(ctx, address, symLink, consts.STORAGE) if err != nil { return 0, err } @@ -57,12 +57,12 @@ func GetBigMapPtr(ctx context.Context, repo models.GeneralRepository, contracts } // FindByName - -func FindByName(repo models.GeneralRepository, contracts contract.Repository, address, key, protocol string) *ast.BigMap { +func FindByName(ctx context.Context, repo models.GeneralRepository, contracts contract.Repository, address, key, protocol string) *ast.BigMap { symLink, err := bcd.GetProtoSymLink(protocol) if err != nil { return nil } - storageTypeByte, err := contracts.ScriptPart(address, symLink, consts.STORAGE) + storageTypeByte, err := contracts.ScriptPart(ctx, address, symLink, consts.STORAGE) if err != nil { return nil } diff --git a/internal/parsers/storage/lazy_babylon.go b/internal/parsers/storage/lazy_babylon.go index ad1d93313..9380bca80 100644 --- a/internal/parsers/storage/lazy_babylon.go +++ b/internal/parsers/storage/lazy_babylon.go @@ -1,6 +1,8 @@ package storage import ( + "context" + "github.com/baking-bad/bcdhub/internal/bcd/ast" "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/bigmapaction" @@ -35,27 +37,27 @@ func NewLazyBabylon(repo bigmapdiff.Repository, operations operation.Repository, } // ParseTransaction - -func (b *LazyBabylon) ParseTransaction(content noderpc.Operation, operation *operation.Operation, store parsers.Store) error { +func (b *LazyBabylon) ParseTransaction(ctx context.Context, content noderpc.Operation, operation *operation.Operation, store parsers.Store) error { result := content.GetResult() if result == nil { return nil } operation.DeffatedStorage = result.Storage - return b.handleBigMapDiff(result, *content.Destination, operation, result.Storage, store) + return b.handleBigMapDiff(ctx, result, *content.Destination, operation, result.Storage, store) } // ParseOrigination - -func (b *LazyBabylon) ParseOrigination(content noderpc.Operation, operation *operation.Operation, store parsers.Store) error { +func (b *LazyBabylon) ParseOrigination(ctx context.Context, content noderpc.Operation, operation *operation.Operation, store parsers.Store) error { result := content.GetResult() if result == nil { return nil } - return b.handleBigMapDiff(result, result.Originated[0], operation, operation.DeffatedStorage, store) + return b.handleBigMapDiff(ctx, result, result.Originated[0], operation, operation.DeffatedStorage, store) } -func (b *LazyBabylon) initPointersTypes(result *noderpc.OperationResult, operation *operation.Operation, data []byte) error { +func (b *LazyBabylon) initPointersTypes(ctx context.Context, result *noderpc.OperationResult, operation *operation.Operation, data []byte) error { level := operation.Level if operation.IsTransaction() && operation.Level >= 2 { level = operation.Level - 1 @@ -74,12 +76,12 @@ func (b *LazyBabylon) initPointersTypes(result *noderpc.OperationResult, operati return nil } - account, err := b.accounts.Get(operation.Destination.Address) + account, err := b.accounts.Get(ctx, operation.Destination.Address) if err != nil { return err } - operaiton, err := b.operations.Last(map[string]interface{}{ + operaiton, err := b.operations.Last(ctx, map[string]interface{}{ "destination_id": account.ID, "status": types.OperationStatusApplied, }, 0) @@ -141,16 +143,16 @@ func (b *LazyBabylon) checkPointers(result *noderpc.OperationResult, storage *as return nil } -func (b *LazyBabylon) handleBigMapDiff(result *noderpc.OperationResult, address string, op *operation.Operation, storageData []byte, store parsers.Store) error { +func (b *LazyBabylon) handleBigMapDiff(ctx context.Context, result *noderpc.OperationResult, address string, op *operation.Operation, storageData []byte, store parsers.Store) error { if len(result.LazyStorageDiff) == 0 { return nil } - if err := b.initPointersTypes(result, op, storageData); err != nil { + if err := b.initPointersTypes(ctx, result, op, storageData); err != nil { return nil } - handlers := map[string]func(*noderpc.LazyBigMapDiff, int64, string, *operation.Operation, parsers.Store) error{ + handlers := map[string]func(context.Context, *noderpc.LazyBigMapDiff, int64, string, *operation.Operation, parsers.Store) error{ types.BigMapActionStringUpdate: b.handleBigMapDiffUpdate, types.BigMapActionStringCopy: b.handleBigMapDiffCopy, types.BigMapActionStringRemove: b.handleBigMapDiffRemove, @@ -167,7 +169,7 @@ func (b *LazyBabylon) handleBigMapDiff(result *noderpc.OperationResult, address continue } - if err := handler(result.LazyStorageDiff[i].Diff.BigMap, result.LazyStorageDiff[i].ID, address, op, store); err != nil { + if err := handler(ctx, result.LazyStorageDiff[i].Diff.BigMap, result.LazyStorageDiff[i].ID, address, op, store); err != nil { return err } } @@ -177,7 +179,7 @@ func (b *LazyBabylon) handleBigMapDiff(result *noderpc.OperationResult, address return nil } -func (b *LazyBabylon) handleBigMapDiffUpdate(diff *noderpc.LazyBigMapDiff, ptr int64, address string, operation *operation.Operation, store parsers.Store) error { +func (b *LazyBabylon) handleBigMapDiffUpdate(ctx context.Context, diff *noderpc.LazyBigMapDiff, ptr int64, address string, operation *operation.Operation, store parsers.Store) error { for i := range diff.Updates { bmd := bigmapdiff.BigMapDiff{ Ptr: ptr, @@ -203,7 +205,7 @@ func (b *LazyBabylon) handleBigMapDiffUpdate(diff *noderpc.LazyBigMapDiff, ptr i return nil } -func (b *LazyBabylon) handleBigMapDiffCopy(diff *noderpc.LazyBigMapDiff, ptr int64, address string, operation *operation.Operation, store parsers.Store) error { +func (b *LazyBabylon) handleBigMapDiffCopy(ctx context.Context, diff *noderpc.LazyBigMapDiff, ptr int64, address string, operation *operation.Operation, store parsers.Store) error { sourcePtr := *diff.Source if ptr > -1 { @@ -222,7 +224,7 @@ func (b *LazyBabylon) handleBigMapDiffCopy(diff *noderpc.LazyBigMapDiff, ptr int b.ptrMap[ptr] = sourcePtr - bmd, err := b.getCopyBigMapDiff(sourcePtr, address) + bmd, err := b.getCopyBigMapDiff(ctx, sourcePtr, address) if err != nil { return err } @@ -251,11 +253,11 @@ func (b *LazyBabylon) handleBigMapDiffCopy(diff *noderpc.LazyBigMapDiff, ptr int return nil } -func (b *LazyBabylon) handleBigMapDiffRemove(diff *noderpc.LazyBigMapDiff, ptr int64, address string, operation *operation.Operation, store parsers.Store) error { +func (b *LazyBabylon) handleBigMapDiffRemove(ctx context.Context, diff *noderpc.LazyBigMapDiff, ptr int64, address string, operation *operation.Operation, store parsers.Store) error { if ptr < 0 { return nil } - states, err := b.repo.GetByPtr(address, ptr) + states, err := b.repo.GetByPtr(ctx, address, ptr) if err != nil { return err } @@ -275,12 +277,12 @@ func (b *LazyBabylon) handleBigMapDiffRemove(diff *noderpc.LazyBigMapDiff, ptr i return nil } -func (b *LazyBabylon) handleBigMapDiffAlloc(diff *noderpc.LazyBigMapDiff, ptr int64, address string, operation *operation.Operation, store parsers.Store) error { +func (b *LazyBabylon) handleBigMapDiffAlloc(ctx context.Context, diff *noderpc.LazyBigMapDiff, ptr int64, address string, operation *operation.Operation, store parsers.Store) error { if ptr > -1 { operation.BigMapActions = append(operation.BigMapActions, b.createBigMapDiffAction("alloc", address, &ptr, nil, operation)) } - return b.handleBigMapDiffUpdate(diff, ptr, address, operation, store) + return b.handleBigMapDiffUpdate(ctx, diff, ptr, address, operation, store) } func (b *LazyBabylon) getDiffsFromUpdates(ptr int64) ([]bigmapdiff.BigMapDiff, error) { @@ -343,9 +345,9 @@ func (b *LazyBabylon) updateTemporaryPointers(src, dst int64) { b.temporaryPointers[dst] = dstBigMap } -func (b *LazyBabylon) getCopyBigMapDiff(src int64, address string) (bmd []bigmapdiff.BigMapDiff, err error) { +func (b *LazyBabylon) getCopyBigMapDiff(ctx context.Context, src int64, address string) (bmd []bigmapdiff.BigMapDiff, err error) { if src > -1 { - states, err := b.repo.GetByPtr(address, src) + states, err := b.repo.GetByPtr(ctx, address, src) if err != nil { return nil, err } diff --git a/internal/parsers/storage/parser.go b/internal/parsers/storage/parser.go index 8a089147f..b2c00e189 100644 --- a/internal/parsers/storage/parser.go +++ b/internal/parsers/storage/parser.go @@ -1,6 +1,8 @@ package storage import ( + "context" + "github.com/baking-bad/bcdhub/internal/models/operation" "github.com/baking-bad/bcdhub/internal/noderpc" "github.com/baking-bad/bcdhub/internal/parsers" @@ -11,6 +13,6 @@ var json = jsoniter.ConfigCompatibleWithStandardLibrary // Parser - type Parser interface { - ParseTransaction(content noderpc.Operation, operation *operation.Operation, store parsers.Store) error - ParseOrigination(content noderpc.Operation, operation *operation.Operation, store parsers.Store) error + ParseTransaction(ctx context.Context, content noderpc.Operation, operation *operation.Operation, store parsers.Store) error + ParseOrigination(ctx context.Context, content noderpc.Operation, operation *operation.Operation, store parsers.Store) error } diff --git a/internal/parsers/store.go b/internal/parsers/store.go index eb3ce2820..a074ef488 100644 --- a/internal/parsers/store.go +++ b/internal/parsers/store.go @@ -2,12 +2,16 @@ package parsers import ( "context" + "fmt" + "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/block" "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/migration" "github.com/baking-bad/bcdhub/internal/models/operation" smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" + "github.com/baking-bad/bcdhub/internal/models/ticket" ) // Store - @@ -18,19 +22,27 @@ type Store interface { AddOperations(operations ...*operation.Operation) AddGlobalConstants(constants ...*contract.GlobalConstant) AddSmartRollups(rollups ...*smartrollup.SmartRollup) + AddTickets(tickets ...ticket.Ticket) + AddTicketBalances(balances ...ticket.Balance) ListContracts() []*contract.Contract ListOperations() []*operation.Operation + AddAccounts(accounts ...account.Account) Save(ctx context.Context) error + SetBlock(block *block.Block) } // TestStore - type TestStore struct { + Block *block.Block BigMapState []*bigmapdiff.BigMapState Contracts []*contract.Contract Migrations []*migration.Migration Operations []*operation.Operation GlobalConstants []*contract.GlobalConstant SmartRollups []*smartrollup.SmartRollup + Tickets map[string]*ticket.Ticket + TicketBalances map[string]*ticket.Balance + Accounts map[string]*account.Account } // NewTestStore - @@ -42,6 +54,9 @@ func NewTestStore() *TestStore { Operations: make([]*operation.Operation, 0), GlobalConstants: make([]*contract.GlobalConstant, 0), SmartRollups: make([]*smartrollup.SmartRollup, 0), + Tickets: make(map[string]*ticket.Ticket, 0), + TicketBalances: make(map[string]*ticket.Balance, 0), + Accounts: make(map[string]*account.Account), } } @@ -75,6 +90,44 @@ func (store *TestStore) AddSmartRollups(rollups ...*smartrollup.SmartRollup) { store.SmartRollups = append(store.SmartRollups, rollups...) } +// AddAccounts - +func (store *TestStore) AddAccounts(accounts ...account.Account) { + for i := range accounts { + if account, ok := store.Accounts[accounts[i].Address]; !ok { + store.Accounts[accounts[i].Address] = &accounts[i] + } else { + account.OperationsCount += accounts[i].OperationsCount + account.EventsCount += accounts[i].EventsCount + account.MigrationsCount += accounts[i].MigrationsCount + account.TicketUpdatesCount += accounts[i].TicketUpdatesCount + } + } +} + +// AddTickets - +func (store *TestStore) AddTickets(tickets ...ticket.Ticket) { + for i := range tickets { + hash := tickets[i].Hash() + if t, ok := store.Tickets[hash]; !ok { + store.Tickets[hash] = &tickets[i] + } else { + t.UpdatesCount += tickets[i].UpdatesCount + } + } +} + +// AddTicketBalances - +func (store *TestStore) AddTicketBalances(balance ...ticket.Balance) { + for i := range balance { + key := fmt.Sprintf("%s_%s", balance[i].Ticket.Hash(), balance[i].Account.Address) + if t, ok := store.TicketBalances[key]; !ok { + store.TicketBalances[key] = &balance[i] + } else { + t.Amount = t.Amount.Add(balance[i].Amount) + } + } +} + // ListContracts - func (store *TestStore) ListContracts() []*contract.Contract { return store.Contracts @@ -89,3 +142,7 @@ func (store *TestStore) ListOperations() []*operation.Operation { func (store *TestStore) Save(ctx context.Context) error { return nil } + +func (store *TestStore) SetBlock(block *block.Block) { + store.Block = block +} diff --git a/internal/periodic/general_worker.go b/internal/periodic/general_worker.go index 8b60bfa23..b531116bb 100644 --- a/internal/periodic/general_worker.go +++ b/internal/periodic/general_worker.go @@ -5,9 +5,9 @@ import ( "strings" "time" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/teztnets" "github.com/robfig/cron/v3" + "github.com/rs/zerolog/log" ) // GeneralWorker - @@ -48,7 +48,7 @@ func (w *GeneralWorker) Start(ctx context.Context) { } if _, err := w.checkNetwork(ctx); err != nil { - logger.Error().Err(err).Msg("failed to receive periodic network info") + log.Err(err).Msg("failed to receive periodic network info") return } @@ -56,7 +56,7 @@ func (w *GeneralWorker) Start(ctx context.Context) { w.schedule, w.handleScheduleEvent(ctx), ); err != nil { - logger.Error().Err(err).Msg("failed to run cron function") + log.Err(err).Msg("failed to run cron function") return } @@ -71,11 +71,11 @@ func (w *GeneralWorker) Close() error { func (w *GeneralWorker) handleScheduleEvent(ctx context.Context) func() { return func() { - logger.Info().Msg("trying to receive new rpc url") + log.Info().Msg("trying to receive new rpc url") changed, err := w.checkNetwork(ctx) if err != nil { - logger.Error().Err(err).Msg("failed to receive periodic network info") + log.Err(err).Msg("failed to receive periodic network info") } if changed { return @@ -91,7 +91,7 @@ func (w *GeneralWorker) handleScheduleEvent(ctx context.Context) func() { case <-ticker.C: changed, err := w.checkNetwork(ctx) if err != nil { - logger.Error().Err(err).Msg("failed to receive periodic network info") + log.Err(err).Msg("failed to receive periodic network info") } if changed { return @@ -118,11 +118,11 @@ func (w *GeneralWorker) checkNetwork(ctx context.Context) (bool, error) { network := parts[0] if current := w.urls[network]; current != data.RPCURL { if err := w.handler(ctx, network, data.RPCURL); err != nil { - logger.Error().Err(err).Str("network", network).Msg("failed to apply new rpc url") + log.Err(err).Str("network", network).Msg("failed to apply new rpc url") } w.urls[network] = data.RPCURL - logger.Info().Str("network", network).Str("url", data.RPCURL).Msg("new url was found") + log.Info().Str("network", network).Str("url", data.RPCURL).Msg("new url was found") changed = true } } diff --git a/internal/periodic/worker.go b/internal/periodic/worker.go index a47b95866..a78e050c7 100644 --- a/internal/periodic/worker.go +++ b/internal/periodic/worker.go @@ -5,10 +5,10 @@ import ( "strings" "time" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/teztnets" "github.com/robfig/cron/v3" + "github.com/rs/zerolog/log" ) // Worker - @@ -53,7 +53,7 @@ func (w *Worker) Start(ctx context.Context) { } if _, err := w.checkNetwork(ctx); err != nil { - logger.Error().Err(err).Str("network", w.network.String()).Msg("failed to receive periodic network info") + log.Err(err).Str("network", w.network.String()).Msg("failed to receive periodic network info") return } @@ -61,7 +61,7 @@ func (w *Worker) Start(ctx context.Context) { w.schedule, w.handleScheduleEvent(ctx), ); err != nil { - logger.Error().Err(err).Str("network", w.network.String()).Msg("failed to run cron function") + log.Err(err).Str("network", w.network.String()).Msg("failed to run cron function") return } @@ -76,14 +76,14 @@ func (w *Worker) Close() error { func (w *Worker) handleScheduleEvent(ctx context.Context) func() { return func() { - logger.Info().Str("network", w.network.String()).Msg("trying to receive new rpc url") + log.Info().Str("network", w.network.String()).Msg("trying to receive new rpc url") changed, err := w.checkNetwork(ctx) if err != nil { - logger.Error().Err(err).Str("network", w.network.String()).Msg("failed to receive periodic network info") + log.Err(err).Str("network", w.network.String()).Msg("failed to receive periodic network info") } if changed { - logger.Info().Msg("rpc url changed") + log.Info().Msg("rpc url changed") return } @@ -97,10 +97,10 @@ func (w *Worker) handleScheduleEvent(ctx context.Context) func() { case <-ticker.C: changed, err := w.checkNetwork(ctx) if err != nil { - logger.Error().Err(err).Str("network", w.network.String()).Msg("failed to receive periodic network info") + log.Err(err).Str("network", w.network.String()).Msg("failed to receive periodic network info") } if changed { - logger.Info().Msg("rpc url changed") + log.Info().Msg("rpc url changed") return } } @@ -127,12 +127,12 @@ func (w *Worker) checkNetwork(ctx context.Context) (bool, error) { if w.currentUrl != data.RPCURL { if w.currentUrl != "" { if err := w.handler(ctx, w.network.String(), data.RPCURL); err != nil { - logger.Error().Err(err).Str("network", w.network.String()).Msg("failed to apply new rpc url") + log.Err(err).Str("network", w.network.String()).Msg("failed to apply new rpc url") } } w.currentUrl = data.RPCURL - logger.Info().Str("network", parts[0]).Str("url", w.currentUrl).Msg("new url was found") + log.Info().Str("network", parts[0]).Str("url", w.currentUrl).Msg("new url was found") return true, nil } } diff --git a/internal/postgres/account/storage.go b/internal/postgres/account/storage.go index 318e060ce..312cb0360 100644 --- a/internal/postgres/account/storage.go +++ b/internal/postgres/account/storage.go @@ -1,6 +1,8 @@ package account import ( + "context" + "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/postgres/core" ) @@ -16,10 +18,29 @@ func NewStorage(pg *core.Postgres) *Storage { } // Get - -func (storage *Storage) Get(address string) (account account.Account, err error) { - err = storage.DB.Model(&account). +func (storage *Storage) Get(ctx context.Context, address string) (account account.Account, err error) { + err = storage.DB.NewSelect().Model(&account). Where("address = ?", address). Limit(1). - Select(&account) + Scan(ctx) + return +} + +// RecentlyCalled - +func (storage *Storage) RecentlyCalledContracts(ctx context.Context, offset, size int64) (accounts []account.Account, err error) { + query := storage.DB.NewSelect().Model(&accounts). + Where("type = 1") + + if offset > 0 { + query.Offset(int(offset)) + } + if size > 0 { + query.Limit(int(size)) + } else { + query.Limit(10) + } + err = query. + OrderExpr("last_action desc, operations_count desc"). + Scan(ctx) return } diff --git a/internal/postgres/bigmapaction/storage.go b/internal/postgres/bigmapaction/storage.go index 966fd4d5f..b8846854f 100644 --- a/internal/postgres/bigmapaction/storage.go +++ b/internal/postgres/bigmapaction/storage.go @@ -1,10 +1,10 @@ package bigmapaction import ( - "github.com/baking-bad/bcdhub/internal/models" + "context" + "github.com/baking-bad/bcdhub/internal/models/bigmapaction" "github.com/baking-bad/bcdhub/internal/postgres/core" - "github.com/go-pg/pg/v10/orm" ) // Storage - @@ -18,12 +18,9 @@ func NewStorage(pg *core.Postgres) *Storage { } // Get - -func (storage *Storage) Get(ptr, limit, offset int64) (actions []bigmapaction.BigMapAction, err error) { - query := storage.DB.Model().Table(models.DocBigMapActions). - WhereGroup(func(q *orm.Query) (*orm.Query, error) { - q.Where("source_ptr = ? AND action <> 3", ptr).WhereOr("destination_ptr = ? AND action = 3 ", ptr) - return q, nil - }). +func (storage *Storage) Get(ctx context.Context, ptr, limit, offset int64) (actions []bigmapaction.BigMapAction, err error) { + query := storage.DB.NewSelect().Model(&actions). + Where("source_ptr = ? AND action <> 3", ptr).WhereOr("destination_ptr = ? AND action = 3 ", ptr). Order("id DESC") if limit > 0 { @@ -32,6 +29,6 @@ func (storage *Storage) Get(ptr, limit, offset int64) (actions []bigmapaction.Bi if offset > 0 { query.Offset(int(offset)) } - err = query.Select(&actions) + err = query.Scan(ctx) return } diff --git a/internal/postgres/bigmapdiff/context.go b/internal/postgres/bigmapdiff/context.go index 021fda615..717c1de0e 100644 --- a/internal/postgres/bigmapdiff/context.go +++ b/internal/postgres/bigmapdiff/context.go @@ -1,13 +1,13 @@ package bigmapdiff import ( - "github.com/baking-bad/bcdhub/internal/models" "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" - "github.com/go-pg/pg/v10/orm" + "github.com/uptrace/bun" ) -func (storage *Storage) buildGetContext(ctx bigmapdiff.GetContext) *orm.Query { - query := storage.DB.Model().Table(models.DocBigMapDiff).ColumnExpr("max(id) as id, count(id) as keys_count") +func (storage *Storage) buildGetContext(ctx bigmapdiff.GetContext) *bun.SelectQuery { + query := storage.DB.NewSelect().Model((*bigmapdiff.BigMapDiff)(nil)). + ColumnExpr("max(id) as id, count(id) as keys_count") if ctx.Contract != "" { query.Where("contract = ?", ctx.Contract) @@ -34,8 +34,8 @@ func (storage *Storage) buildGetContext(ctx bigmapdiff.GetContext) *orm.Query { return query.Group("key_hash").Order("id desc") } -func (storage *Storage) buildGetContextForState(ctx bigmapdiff.GetContext) *orm.Query { - query := storage.DB.Model().Table(models.DocBigMapState) +func (storage *Storage) buildGetContextForState(ctx bigmapdiff.GetContext) *bun.SelectQuery { + query := storage.DB.NewSelect().Model((*bigmapdiff.BigMapState)(nil)) if ctx.Contract != "" { query.Where("contract = ?", ctx.Contract) diff --git a/internal/postgres/bigmapdiff/storage.go b/internal/postgres/bigmapdiff/storage.go index 3cfa07f09..39d3b718e 100644 --- a/internal/postgres/bigmapdiff/storage.go +++ b/internal/postgres/bigmapdiff/storage.go @@ -1,13 +1,14 @@ package bigmapdiff import ( - "github.com/baking-bad/bcdhub/internal/models" + "context" + "database/sql" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" "github.com/baking-bad/bcdhub/internal/postgres/consts" "github.com/baking-bad/bcdhub/internal/postgres/core" - "github.com/go-pg/pg/v10" - "github.com/go-pg/pg/v10/orm" "github.com/pkg/errors" + "github.com/uptrace/bun" ) // Storage - @@ -20,60 +21,37 @@ func NewStorage(pg *core.Postgres) *Storage { return &Storage{pg} } -func bigMapKey(keyHash string, ptr int64) func(db *orm.Query) *orm.Query { - return func(q *orm.Query) *orm.Query { - return q.Where("key_hash = ?", keyHash).Where("ptr = ?", ptr) - } +func bigMapKey(q *bun.SelectQuery, keyHash string, ptr int64) *bun.SelectQuery { + return q.Where("key_hash = ?", keyHash).Where("ptr = ?", ptr) } // CurrentByKey - -func (storage *Storage) Current(keyHash string, ptr int64) (data bigmapdiff.BigMapState, err error) { +func (storage *Storage) Current(ctx context.Context, keyHash string, ptr int64) (data bigmapdiff.BigMapState, err error) { if ptr < 0 { err = errors.Wrapf(consts.ErrInvalidPointer, "%d", ptr) return } - query := storage.DB.Model().Table(models.DocBigMapState) - bigMapKey(keyHash, ptr)(query) - err = query.Select(&data) + err = bigMapKey(storage.DB.NewSelect().Model(&data), keyHash, ptr).Scan(ctx) return } // GetForAddress - -func (storage *Storage) GetForAddress(address string) (response []bigmapdiff.BigMapState, err error) { - query := storage.DB.Model().Table(models.DocBigMapState) - core.Contract(address)(query) - err = query.Order("id desc").Select(&response) - return -} - -// GetByAddress - -func (storage *Storage) GetByAddress(address string) (response []bigmapdiff.BigMapDiff, err error) { - query := storage.DB.Model().Table(models.DocBigMapDiff) - core.Contract(address)(query) - err = query.Order("level desc").Select(&response) - return -} - -// GetValuesByKey - -func (storage *Storage) GetValuesByKey(keyHash string) (response []bigmapdiff.BigMapState, err error) { - err = storage.DB.Model().Table(models.DocBigMapState). - Where("key_hash = ?", keyHash). - Order("last_update_level desc"). - Select(&response) +func (storage *Storage) GetForAddress(ctx context.Context, address string) (response []bigmapdiff.BigMapState, err error) { + err = core.Contract(storage.DB.NewSelect().Model(&response), address).Order("id desc").Scan(ctx) return } // Count - -func (storage *Storage) Count(ptr int64) (int64, error) { - count, err := storage.DB.Model().Table(models.DocBigMapState). +func (storage *Storage) Count(ctx context.Context, ptr int64) (int, error) { + return storage.DB.NewSelect(). + Model((*bigmapdiff.BigMapState)(nil)). Where("ptr = ?", ptr). - Count() - return int64(count), err + Count(ctx) } // Previous - -func (storage *Storage) Previous(filters []bigmapdiff.BigMapDiff) ([]bigmapdiff.BigMapDiff, error) { +func (storage *Storage) Previous(ctx context.Context, filters []bigmapdiff.BigMapDiff) ([]bigmapdiff.BigMapDiff, error) { if len(filters) == 0 { return nil, nil } @@ -82,13 +60,13 @@ func (storage *Storage) Previous(filters []bigmapdiff.BigMapDiff) ([]bigmapdiff. for i := range filters { var prev bigmapdiff.BigMapDiff - if err := storage.DB.Model(&prev). + if err := storage.DB.NewSelect().Model(&prev). Where("id < ?", filters[i].ID). Where("key_hash = ?", filters[i].KeyHash). Where("ptr = ? ", filters[i].Ptr). Order("id desc").Limit(1). - Select(); err != nil { - if errors.Is(err, pg.ErrNoRows) { + Scan(ctx); err != nil { + if errors.Is(err, sql.ErrNoRows) { continue } return nil, err @@ -100,84 +78,93 @@ func (storage *Storage) Previous(filters []bigmapdiff.BigMapDiff) ([]bigmapdiff. } // GetForOperation - -func (storage *Storage) GetForOperation(id int64) (response []bigmapdiff.BigMapDiff, err error) { - err = storage.DB.Model().Table(models.DocBigMapDiff). - Where("operation_id = ?", id).Select(&response) +func (storage *Storage) GetForOperation(ctx context.Context, id int64) (response []bigmapdiff.BigMapDiff, err error) { + err = storage.DB.NewSelect(). + Model(&response). + Where("operation_id = ?", id). + Scan(ctx) return } // GetByPtrAndKeyHash - -func (storage *Storage) GetByPtrAndKeyHash(ptr int64, keyHash string, size, offset int64) ([]bigmapdiff.BigMapDiff, int64, error) { +func (storage *Storage) GetByPtrAndKeyHash(ctx context.Context, ptr int64, keyHash string, size, offset int64) ([]bigmapdiff.BigMapDiff, int64, error) { if ptr < 0 { return nil, 0, errors.Wrapf(consts.ErrInvalidPointer, "%d", ptr) } limit := storage.GetPageSize(size) - query := storage.DB.Model().Table(models.DocBigMapDiff). + var response []bigmapdiff.BigMapDiff + + query := storage.DB.NewSelect().Model(&response). Where("key_hash = ?", keyHash). Where("ptr = ?", ptr) query = core.OrderByLevelDesc(query) - var response []bigmapdiff.BigMapDiff if err := query. Limit(limit). Offset(int(offset)). - Select(&response); err != nil { + Scan(ctx); err != nil { return nil, 0, err } - count, err := storage.DB.Model().Table(models.DocBigMapDiff). + count, err := storage.DB.NewSelect(). + Model((*bigmapdiff.BigMapDiff)(nil)). Where("key_hash = ?", keyHash). Where("ptr = ?", ptr). - Count() + Count(ctx) return response, int64(count), err } // GetByPtr - -func (storage *Storage) GetByPtr(contract string, ptr int64) (response []bigmapdiff.BigMapState, err error) { - query := storage.DB.Model().Table(models.DocBigMapState).Where("ptr = ?", ptr) - core.Contract(contract)(query) - err = query.Select(&response) +func (storage *Storage) GetByPtr(ctx context.Context, contract string, ptr int64) (response []bigmapdiff.BigMapState, err error) { + query := storage.DB.NewSelect(). + Model(&response). + Where("ptr = ?", ptr) + err = core.Contract(query, contract).Scan(ctx) return } // Get - -func (storage *Storage) Get(ctx bigmapdiff.GetContext) ([]bigmapdiff.Bucket, error) { - if *ctx.Ptr < 0 { - return nil, errors.Errorf("Invalid pointer value: %d", *ctx.Ptr) +func (storage *Storage) Get(ctx context.Context, reqCtx bigmapdiff.GetContext) ([]bigmapdiff.Bucket, error) { + if reqCtx.Ptr != nil && *reqCtx.Ptr < 0 { + return nil, errors.Errorf("Invalid pointer value: %d", *reqCtx.Ptr) } var bmd []bigmapdiff.Bucket - subQuery := storage.buildGetContext(ctx) + subQuery := storage.buildGetContext(reqCtx) + + query := storage.DB.NewSelect(). + Model((*bigmapdiff.BigMapDiff)(nil)). + ColumnExpr("*, bmd.keys_count"). + Join("inner join (?) as bmd on bmd.id = big_map_diff.id", subQuery) - query := storage.DB.Model().Table(models.DocBigMapDiff).ColumnExpr("*, bmd.keys_count").Join("inner join (?) as bmd on bmd.id = big_map_diffs.id", subQuery) - err := query.Select(&bmd) + err := query.Scan(ctx, &bmd) return bmd, err } // GetStats - -func (storage *Storage) GetStats(ptr int64) (stats bigmapdiff.Stats, err error) { - total, err := storage.DB.Model((*bigmapdiff.BigMapState)(nil)). +func (storage *Storage) GetStats(ctx context.Context, ptr int64) (stats bigmapdiff.Stats, err error) { + total, err := storage.DB.NewSelect().Model((*bigmapdiff.BigMapState)(nil)). Where("ptr = ?", ptr). - Count() + Count(ctx) if err != nil { return stats, err } - active, err := storage.DB.Model((*bigmapdiff.BigMapState)(nil)). + active, err := storage.DB.NewSelect().Model((*bigmapdiff.BigMapState)(nil)). Where("ptr = ?", ptr). Where("removed = false"). - Count() + Count(ctx) if err != nil { return stats, err } - if err := storage.DB.Model((*bigmapdiff.BigMapState)(nil)). + if err := storage.DB.NewSelect().Model((*bigmapdiff.BigMapState)(nil)). Column("contract"). Where("ptr = ?", ptr). Limit(1). - Select(&stats.Contract); err != nil { + Scan(ctx, &stats.Contract); err != nil { if !storage.IsRecordNotFound(err) { return stats, err } @@ -189,38 +176,8 @@ func (storage *Storage) GetStats(ptr int64) (stats bigmapdiff.Stats, err error) return } -// CurrentByContract - -func (storage *Storage) CurrentByContract(contract string) (keys []bigmapdiff.BigMapState, err error) { - err = storage.DB.Model().Table(models.DocBigMapState). - Where("contract = ?", contract). - Select(&keys) - - return -} - -// StatesChangedAfter - -func (storage *Storage) StatesChangedAfter(level int64) (states []bigmapdiff.BigMapState, err error) { - err = storage.DB.Model().Table(models.DocBigMapState). - Where("last_update_level = ?", level). - Select(&states) - return -} - -// LastDiff - -func (storage *Storage) LastDiff(ptr int64, keyHash string, skipRemoved bool) (diff bigmapdiff.BigMapDiff, err error) { - query := storage.DB.Model().Table(models.DocBigMapDiff) - bigMapKey(keyHash, ptr)(query) - - if skipRemoved { - query.Where("value is not null") - } - - err = query.Order("id desc").Limit(1).Select(&diff) - return -} - // Keys - -func (storage *Storage) Keys(ctx bigmapdiff.GetContext) (states []bigmapdiff.BigMapState, err error) { - err = storage.buildGetContextForState(ctx).Select(&states) +func (storage *Storage) Keys(ctx context.Context, req bigmapdiff.GetContext) (states []bigmapdiff.BigMapState, err error) { + err = storage.buildGetContextForState(req).Scan(ctx, &states) return } diff --git a/internal/postgres/block/storage.go b/internal/postgres/block/storage.go index a3d0f5f1c..d0ba01761 100644 --- a/internal/postgres/block/storage.go +++ b/internal/postgres/block/storage.go @@ -1,6 +1,8 @@ package block import ( + "context" + "github.com/baking-bad/bcdhub/internal/models/block" "github.com/baking-bad/bcdhub/internal/postgres/core" ) @@ -16,22 +18,24 @@ func NewStorage(pg *core.Postgres) *Storage { } // Get - -func (storage *Storage) Get(level int64) (block block.Block, err error) { - err = storage.DB.Model(&block). +func (storage *Storage) Get(ctx context.Context, level int64) (block block.Block, err error) { + err = storage.DB.NewSelect(). + Model(&block). Where("level = ?", level). Limit(1). Relation("Protocol"). - Select() + Scan(ctx) return } // Last - returns current indexer state for network -func (storage *Storage) Last() (block block.Block, err error) { - err = storage.DB.Model(&block). +func (storage *Storage) Last(ctx context.Context) (block block.Block, err error) { + err = storage.DB.NewSelect(). + Model(&block). Order("id desc"). Limit(1). Relation("Protocol"). - Select() + Scan(ctx) if storage.IsRecordNotFound(err) { err = nil } diff --git a/internal/postgres/contract/storage.go b/internal/postgres/contract/storage.go index 5a1deca2b..33ca93d28 100644 --- a/internal/postgres/contract/storage.go +++ b/internal/postgres/contract/storage.go @@ -1,7 +1,7 @@ package contract import ( - "math/rand" + "context" "github.com/baking-bad/bcdhub/internal/bcd" "github.com/baking-bad/bcdhub/internal/bcd/consts" @@ -9,7 +9,6 @@ import ( "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/postgres/core" - "github.com/go-pg/pg/v10" "github.com/pkg/errors" ) @@ -24,230 +23,169 @@ func NewStorage(pg *core.Postgres) *Storage { } // Get - -func (storage *Storage) Get(address string) (response contract.Contract, err error) { +func (storage *Storage) Get(ctx context.Context, address string) (response contract.Contract, err error) { var accountID int64 - if err = storage.DB.Model((*account.Account)(nil)).Column("id").Where("address = ?", address).Select(&accountID); err != nil { + if err = storage.DB.NewSelect(). + Model((*account.Account)(nil)). + Column("id"). + Where("address = ?", address). + Scan(ctx, &accountID); err != nil { return } - err = storage.DB.Model(&response).Where("contract.account_id = ?", accountID).Relation("Account").Relation("Manager").Relation("Delegate").Relation("Alpha").Relation("Babylon").Relation("Jakarta").Select() + err = storage.DB.NewSelect(). + Model(&response). + Where("contract.account_id = ?", accountID). + Relation("Account").Relation("Manager"). + Relation("Delegate").Relation("Alpha"). + Relation("Babylon").Relation("Jakarta"). + Scan(ctx) return } -// GetAll - -func (storage *Storage) GetAll(filters map[string]interface{}) (response []contract.Contract, err error) { - query := storage.DB.Model((*contract.Contract)(nil)) - for key, value := range filters { - query.Where("? = ?", pg.Ident(key), value) - } - err = query.Relation("Account").Relation("Manager").Relation("Delegate").Select(&response) - return -} - -// GetRandom - -func (storage *Storage) GetRandom() (response contract.Contract, err error) { - var id int64 - if err = storage.DB.Model(&response).ColumnExpr("max(contract.id)").Select(&id); err != nil { - return - } - - err = storage.DB.Model(&response).Where("contract.id = ?", rand.Int63n(id)). - Relation("Account").Relation("Manager").Relation("Delegate").Relation("Alpha").Relation("Babylon").Relation("Jakarta").First() - return -} - -// GetTokens - -func (storage *Storage) GetTokens(tokenInterface string, offset, size int64) ([]contract.Contract, int64, error) { - tags := types.FA12Tag | types.FA1Tag | types.FA2Tag - if tokenInterface == "fa1-2" || tokenInterface == "fa1" || tokenInterface == "fa2" { - tags = types.NewTags([]string{tokenInterface}) - } - - query := storage.DB.Model((*contract.Contract)(nil)). - Where("(tags & ?) > 0", tags). - Order("id desc"). - Limit(storage.GetPageSize(size)). - Offset(int(offset)) - - var contracts []contract.Contract - err := storage.DB.Model().TableExpr("(?) as contract", query). - ColumnExpr("contract.*"). - ColumnExpr("account.address as account__address, account.alias as account__alias"). - ColumnExpr("manager.address as manager__address, manager.alias as manager__alias"). - ColumnExpr("delegate.address as delegate__address, delegate.alias as delegate__alias"). - Join(`LEFT JOIN "accounts" AS "account" ON "account"."id" = "contract"."account_id"`). - Join(`LEFT JOIN "accounts" AS "manager" ON "manager"."id" = "contract"."manager_id" `). - Join(`LEFT JOIN "accounts" AS "delegate" ON "delegate"."id" = "contract"."delegate_id"`). - Select(&contracts) - if err != nil { - return nil, 0, err - } - - count, err := storage.DB.Model((*contract.Contract)(nil)).Where("(contract.tags & ?) > 0", tags).Count() - return contracts, int64(count), err -} - // ByHash - -func (storage *Storage) ByHash(hash string) (result contract.Script, err error) { - err = storage.DB.Model(&result).Where("hash = ?", hash).First() +func (storage *Storage) ByHash(ctx context.Context, hash string) (result contract.Script, err error) { + err = storage.DB.NewSelect().Model(&result).Where("hash = ?", hash).Limit(1).Scan(ctx) return } // Script - -func (storage *Storage) Script(address string, symLink string) (contract.Script, error) { +func (storage *Storage) Script(ctx context.Context, address string, symLink string) (contract.Script, error) { var accountID int64 - if err := storage.DB.Model((*account.Account)(nil)).Column("id").Where("address = ?", address).Select(&accountID); err != nil { + if err := storage.DB. + NewSelect(). + Model((*account.Account)(nil)). + Column("id"). + Where("address = ?", address). + Scan(ctx, &accountID); err != nil { return contract.Script{}, err } var c contract.Contract - query := storage.DB.Model(&c).Where("account_id = ?", accountID) + query := storage.DB.NewSelect().Model(&c).Where("account_id = ?", accountID) switch symLink { case bcd.SymLinkAlpha: - err := query.Relation("Alpha").Select() + err := query.Relation("Alpha").Scan(ctx) return c.Alpha, err case bcd.SymLinkBabylon: - err := query.Relation("Babylon").Select() + err := query.Relation("Babylon").Scan(ctx) return c.Babylon, err case bcd.SymLinkJakarta: - err := query.Relation("Jakarta").Select() + err := query.Relation("Jakarta").Scan(ctx) return c.Jakarta, err } return c.Alpha, errors.Errorf("unknown protocol symbolic link: %s", symLink) } -// GetScripts - -func (storage *Storage) GetScripts(limit, offset int) (scripts []contract.Script, err error) { - err = storage.DB.Model(&scripts). - ColumnExpr("id, tags, hash, fail_strings, annotations, entrypoints"). - Limit(limit).Offset(offset).Order("id asc").Select() - return -} - -// UpdateProjectID - -func (storage *Storage) UpdateProjectID(scripts []contract.Script) error { - _, err := storage.DB.Model(&scripts).Set("project_id = _data.project_id").WherePK().Update() - return err -} - // Code - -func (storage *Storage) Code(id int64) ([]byte, error) { +func (storage *Storage) Code(ctx context.Context, id int64) ([]byte, error) { var data []byte - err := storage.DB.Model((*contract.Script)(nil)).Where("id = ?", id).Column("code").Select(&data) + err := storage.DB.NewSelect().Model((*contract.Script)(nil)).Where("id = ?", id).Column("code").Scan(ctx, &data) return data, err } // Parameter - -func (storage *Storage) Parameter(id int64) ([]byte, error) { +func (storage *Storage) Parameter(ctx context.Context, id int64) ([]byte, error) { var data []byte - err := storage.DB.Model((*contract.Script)(nil)).Where("id = ?", id).Column("parameter").Select(&data) + err := storage.DB.NewSelect(). + Model((*contract.Script)(nil)). + Where("id = ?", id). + Column("parameter"). + Scan(ctx, &data) return data, err } // Storage - -func (storage *Storage) Storage(id int64) ([]byte, error) { +func (storage *Storage) Storage(ctx context.Context, id int64) ([]byte, error) { var data []byte - err := storage.DB.Model((*contract.Script)(nil)).Where("id = ?", id).Column("storage").Select(&data) + err := storage.DB.NewSelect(). + Model((*contract.Script)(nil)). + Where("id = ?", id). + Column("storage"). + Scan(ctx, &data) return data, err } // Storage - -func (storage *Storage) Views(id int64) ([]byte, error) { +func (storage *Storage) Views(ctx context.Context, id int64) ([]byte, error) { var data []byte - err := storage.DB.Model((*contract.Script)(nil)).Where("id = ?", id).Column("views").Select(&data) + err := storage.DB.NewSelect(). + Model((*contract.Script)(nil)). + Where("id = ?", id). + Column("views"). + Scan(ctx, &data) return data, err } // ScriptPart - -func (storage *Storage) ScriptPart(address string, symLink, part string) ([]byte, error) { +func (storage *Storage) ScriptPart(ctx context.Context, address string, symLink, part string) ([]byte, error) { var accountID int64 - if err := storage.DB.Model((*account.Account)(nil)).Column("id").Where("address = ?", address).Select(&accountID); err != nil { + if err := storage.DB.NewSelect(). + Model((*account.Account)(nil)). + Column("id"). + Where("address = ?", address). + Scan(ctx, &accountID); err != nil { return nil, err } - query := storage.DB.Model((*contract.Contract)(nil)).Where("account_id = ?", accountID) + var scriptId int64 + scriptIdQuery := storage.DB.NewSelect(). + Model((*contract.Contract)(nil)). + Where("account_id = ?", accountID) switch symLink { case bcd.SymLinkAlpha: - switch part { - case consts.PARAMETER: - query.Column("alpha.parameter").Relation("Alpha._") - case consts.CODE: - query.Column("alpha.code").Relation("Alpha._") - case consts.STORAGE: - query.Column("alpha.storage").Relation("Alpha._") - case consts.VIEWS: - query.Column("alpha.views").Relation("Alpha._") - default: - return nil, errors.Errorf("unknown script part name: %s", part) - } + scriptIdQuery = scriptIdQuery.Column("alpha_id") case bcd.SymLinkBabylon: - switch part { - case consts.PARAMETER: - query.Column("babylon.parameter").Relation("Babylon._") - case consts.CODE: - query.Column("babylon.code").Relation("Babylon._") - case consts.STORAGE: - query.Column("babylon.storage").Relation("Babylon._") - case consts.VIEWS: - query.Column("babylon.views").Relation("Babylon._") - default: - return nil, errors.Errorf("unknown script part name: %s", part) - } + scriptIdQuery = scriptIdQuery.Column("babylon_id") case bcd.SymLinkJakarta: - switch part { - case consts.PARAMETER: - query.Column("jakarta.parameter").Relation("Jakarta._") - case consts.CODE: - query.Column("jakarta.code").Relation("Jakarta._") - case consts.STORAGE: - query.Column("jakarta.storage").Relation("Jakarta._") - case consts.VIEWS: - query.Column("jakarta.views").Relation("Jakarta._") - default: - return nil, errors.Errorf("unknown script part name: %s", part) - } + scriptIdQuery = scriptIdQuery.Column("jakarta_id") default: return nil, errors.Errorf("unknown protocol symbolic link: %s", symLink) } - var data []byte - err := query.Select(pg.Scan(&data)) - return data, err -} -// RecentlyCalled - -func (storage *Storage) RecentlyCalled(offset, size int64) (contracts []contract.Contract, err error) { - query := storage.DB.Model((*contract.Contract)(nil)). - ColumnExpr("contract.id, contract.tx_count, contract.last_action, contract.account_id"). - ColumnExpr("account.address as account__address, account.alias as account__alias"). - Join(`LEFT JOIN "accounts" AS "account" ON "account"."id" = "contract"."account_id"`) - - if offset > 0 { - query.Offset(int(offset)) + if err := scriptIdQuery.Scan(ctx, &scriptId); err != nil { + return nil, err } - if size > 0 { - query.Limit(int(size)) - } else { - query.Limit(10) + + partQuery := storage.DB.NewSelect(). + Model((*contract.Script)(nil)). + Where("id = ?", scriptId) + + switch part { + case consts.PARAMETER: + partQuery.Column("parameter") + case consts.CODE: + partQuery.Column("code") + case consts.STORAGE: + partQuery.Column("storage") + case consts.VIEWS: + partQuery.Column("views") + default: + return nil, errors.Errorf("unknown script part name: %s", part) } - err = query. - OrderExpr("contract.last_action desc, contract.tx_count desc"). - Select(&contracts) - return -} -// Count - -func (storage *Storage) Count() (int, error) { - return storage.DB.Model((*contract.Contract)(nil)).CountEstimate(1000000) + var data []byte + err := partQuery.Scan(ctx, &data) + return data, err } // FindOne - -func (storage *Storage) FindOne(tags types.Tags) (result contract.Contract, err error) { - err = storage.DB.Model(&result). +func (storage *Storage) FindOne(ctx context.Context, tags types.Tags) (result contract.Contract, err error) { + err = storage.DB.NewSelect().Model(&result). Where("tags&? > 0", tags). - ColumnExpr("contract.id, contract.tx_count, contract.last_action, contract.account_id, contract.timestamp, contract.level"). - ColumnExpr("account.address as account__address, account.alias as account__alias"). + ColumnExpr("contract.id, contract.account_id, contract.timestamp, contract.level"). + ColumnExpr("account.address as account__address, account.operations_count as account__operations_count, account.last_action as account__last_action"). Join(`LEFT JOIN "accounts" AS "account" ON "account"."id" = "contract"."account_id"`). - First() + Limit(1). + Scan(ctx) + return +} + +func (storage *Storage) AllExceptDelegators(ctx context.Context) (contracts []contract.Contract, err error) { + err = storage.DB.NewSelect().Model(&contracts). + Relation("Account"). + Where("tags & 4 = 0"). // except delegator contracts + Scan(ctx) return } diff --git a/internal/postgres/core/bulk.go b/internal/postgres/core/bulk.go deleted file mode 100644 index 8e1330b07..000000000 --- a/internal/postgres/core/bulk.go +++ /dev/null @@ -1,42 +0,0 @@ -package core - -import ( - "context" - "reflect" - - "github.com/baking-bad/bcdhub/internal/models" - "github.com/go-pg/pg/v10" -) - -// Save - perform insert or update items -func (p *Postgres) Save(ctx context.Context, items []models.Model) error { - if len(items) == 0 { - return nil - } - - return p.DB.RunInTransaction(ctx, func(tx *pg.Tx) error { - for i := range items { - if err := items[i].Save(tx); err != nil { - return err - } - } - return nil - }) -} - -// BulkDelete - -func (p *Postgres) BulkDelete(ctx context.Context, items []models.Model) error { - if len(items) == 0 { - return nil - } - - return p.DB.RunInTransaction(ctx, func(tx *pg.Tx) error { - for i := range items { - el := reflect.ValueOf(items[i]).Interface() - if _, err := tx.Model().Table(items[i].GetIndex()).Delete(el); err != nil { - return err - } - } - return nil - }) -} diff --git a/internal/postgres/core/config.go b/internal/postgres/core/config.go new file mode 100644 index 000000000..e3623012e --- /dev/null +++ b/internal/postgres/core/config.go @@ -0,0 +1,21 @@ +package core + +import "fmt" + +type Config struct { + Host string `yaml:"host"` + Port int `yaml:"port"` + User string `yaml:"user"` + DBName string `yaml:"dbname"` + Password string `yaml:"password"` + SslMode string `yaml:"sslmode"` +} + +// ConnectionString - +func (cfg Config) ConnectionString() string { + database := cfg.DBName + if database == "" { + database = "postgres" + } + return fmt.Sprintf("host=%s port=%d user=%s password=%s sslmode=%s dbname=%s", cfg.Host, cfg.Port, cfg.User, cfg.Password, cfg.SslMode, database) +} diff --git a/internal/postgres/core/delete.go b/internal/postgres/core/delete.go deleted file mode 100644 index 0a8e24d75..000000000 --- a/internal/postgres/core/delete.go +++ /dev/null @@ -1,13 +0,0 @@ -package core - -// DeleteByContract - -func (p *Postgres) DeleteByContract(indices []string, address string) error { - for i := range indices { - if _, err := p.DB.Model().Table(indices[i]). - Where("contract = ?", address). - Delete(); err != nil { - return err - } - } - return nil -} diff --git a/internal/postgres/core/get.go b/internal/postgres/core/get.go index 7b7d5e6b4..b82364228 100644 --- a/internal/postgres/core/get.go +++ b/internal/postgres/core/get.go @@ -1,26 +1,13 @@ package core import ( + "context" + "github.com/baking-bad/bcdhub/internal/models" - "github.com/go-pg/pg/v10" ) // GetByID - -func (p *Postgres) GetByID(output models.Model) error { - err := p.DB.Model().Table(output.GetIndex()).Where("id = ?", output.GetID()).Select(output) +func (p *Postgres) GetByID(ctx context.Context, output models.Model) error { + err := p.DB.NewSelect().Model(output).Where("id = ?", output.GetID()).Scan(ctx) return err } - -// GetAll - -func (p *Postgres) GetAll(index string) ([]models.Model, error) { - var result []models.Model - err := p.DB.Model().Table(index).Select(&result) - return result, err -} - -// GetByIDs - -func (p *Postgres) GetByIDs(index string, ids ...int64) ([]models.Model, error) { - var result []models.Model - err := p.DB.Model().Table(index).Where("id IN (?)", pg.In(ids)).Select(&result) - return result, err -} diff --git a/internal/postgres/core/histogram.go b/internal/postgres/core/histogram.go deleted file mode 100644 index 028b83f71..000000000 --- a/internal/postgres/core/histogram.go +++ /dev/null @@ -1,45 +0,0 @@ -package core - -import ( - "github.com/baking-bad/bcdhub/internal/helpers" - "github.com/pkg/errors" -) - -const ( - year = "year" - month = "month" - week = "week" - hour = "hour" - day = "day" - all = "all" -) - -// ValidateHistogramPeriod - -func ValidateHistogramPeriod(period string) error { - if !helpers.StringInArray(period, []string{day, week, month, year, hour, all}) { - return errors.Errorf("Invalid period: %s", period) - } - return nil -} - -// GetHistogramInterval - -func GetHistogramInterval(period string) string { - switch period { - case hour: - return "now() - interval '23 hour'" // -1 hour/day/week/month because postgres series count current date. In maths: [from; to] -> (from; to] - case day: - return "now() - interval '30 day'" - case week: - return "now() - interval '15 week'" - case month: - return "now() - interval '11 month'" - default: - return "date '2018-06-25'" - } -} - -// HistogramResponse - -type HistogramResponse struct { - DatePart float64 - Value float64 -} diff --git a/internal/postgres/core/index.go b/internal/postgres/core/index.go index ee03895bc..4030a25c5 100644 --- a/internal/postgres/core/index.go +++ b/internal/postgres/core/index.go @@ -3,64 +3,142 @@ package core import ( "context" - "github.com/baking-bad/bcdhub/internal/models" - "github.com/go-pg/pg/v10/orm" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/block" + "github.com/baking-bad/bcdhub/internal/models/contract" + "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/uptrace/bun" ) -// CreateTables - -func (p *Postgres) CreateTables() error { - for _, index := range models.AllModels() { - if err := p.DB.Model(index).CreateTable(&orm.CreateTableOptions{ - IfNotExists: true, - }); err != nil { +func (p *Postgres) CreateIndex(ctx context.Context, name, columns string, model any) error { + _, err := p.DB.NewCreateIndex(). + Model(model). + IfNotExists(). + Index(name). + ColumnExpr(columns). + Exec(ctx) + return err +} + +func createBaseIndices(ctx context.Context, db bun.IDB) error { + return db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { + // Blocks + if _, err := db.NewCreateIndex(). + Model((*block.Block)(nil)). + IfNotExists(). + Index("blocks_level_idx"). + Column("level"). + Exec(ctx); err != nil { return err } - } - return nil -} -// Drop - drops full database -func (p *Postgres) Drop(ctx context.Context) error { - for _, table := range models.ManyToMany() { - if err := p.DB.Model(table).DropTable(&orm.DropTableOptions{ - IfExists: true, - Cascade: true, - }); err != nil { + // Big map diff + if _, err := db.NewCreateIndex(). + Model((*bigmapdiff.BigMapDiff)(nil)). + IfNotExists(). + Index("big_map_diff_idx"). + ColumnExpr("contract, ptr"). + Exec(ctx); err != nil { + return err + } + if _, err := db.NewCreateIndex(). + Model((*bigmapdiff.BigMapDiff)(nil)). + IfNotExists(). + Index("big_map_diff_key_hash_idx"). + ColumnExpr("key_hash, ptr"). + Exec(ctx); err != nil { return err } - } - for _, table := range models.AllModels() { - if err := p.DB.Model(table).DropTable(&orm.DropTableOptions{ - IfExists: true, - Cascade: true, - }); err != nil { + // Big map state + if _, err := db.NewCreateIndex(). + Model((*bigmapdiff.BigMapState)(nil)). + IfNotExists(). + Index("big_map_state_ptr_idx"). + Column("ptr"). + Exec(ctx); err != nil { + return err + } + if _, err := db.NewCreateIndex(). + Model((*bigmapdiff.BigMapState)(nil)). + IfNotExists(). + Index("big_map_state_contract_idx"). + Column("contract"). + Exec(ctx); err != nil { + return err + } + if _, err := db.NewCreateIndex(). + Model((*bigmapdiff.BigMapState)(nil)). + IfNotExists(). + Index("big_map_state_last_update_level_idx"). + Column("last_update_level"). + Exec(ctx); err != nil { return err } - } - return nil -} -const tableExistsQuery = `SELECT EXISTS( - SELECT * - FROM information_schema.tables - WHERE - table_schema = ? AND - table_name = ? -) as flag;` + // Contracts + if _, err := db.NewCreateIndex(). + Model((*contract.Contract)(nil)). + IfNotExists(). + Index("contracts_account_id_idx"). + Column("account_id"). + Exec(ctx); err != nil { + return err + } + if _, err := db.NewCreateIndex(). + Model((*contract.Contract)(nil)). + IfNotExists(). + Index("contracts_alpha_id_idx"). + Column("alpha_id"). + Exec(ctx); err != nil { + return err + } + if _, err := db.NewCreateIndex(). + Model((*contract.Contract)(nil)). + IfNotExists(). + Index("contracts_babylon_id_idx"). + Column("babylon_id"). + Exec(ctx); err != nil { + return err + } + if _, err := db.NewCreateIndex(). + Model((*contract.Contract)(nil)). + IfNotExists(). + Index("contracts_jakarta_id_idx"). + Column("jakarta_id"). + Exec(ctx); err != nil { + return err + } -type existsResponse struct { - Flag bool `pg:"flag,use_zero"` -} + // Scripts + if _, err := db.NewCreateIndex(). + Model((*contract.Script)(nil)). + IfNotExists(). + Unique(). + Index("script_hash_idx"). + Column("hash"). + Exec(ctx); err != nil { + return err + } -// TablesExist - returns true if all tables exist otherwise false -func (p *Postgres) TablesExist() bool { - for _, table := range models.AllDocuments() { - var exists existsResponse - _, err := p.DB.QueryOne(&exists, tableExistsQuery, p.schema, table) - if !exists.Flag || err != nil { - return false + // Operations + if _, err := db.NewCreateIndex(). + Model((*operation.Operation)(nil)). + IfNotExists(). + Index("operations_destination_idx"). + Column("destination_id"). + Exec(ctx); err != nil { + return err } - } - return true + if _, err := db.NewCreateIndex(). + Model((*operation.Operation)(nil)). + IfNotExists(). + Index("operations_status_idx"). + Column("status"). + Exec(ctx); err != nil { + return err + } + + return nil + }) } diff --git a/internal/postgres/core/logger.go b/internal/postgres/core/logger.go index 3ed34dfa5..83f0f5d28 100644 --- a/internal/postgres/core/logger.go +++ b/internal/postgres/core/logger.go @@ -4,29 +4,23 @@ import ( "context" "time" - "github.com/baking-bad/bcdhub/internal/logger" - "github.com/go-pg/pg/v10" + "github.com/rs/zerolog/log" + "github.com/uptrace/bun" ) type logQueryHook struct{} // BeforeQuery - -func (h *logQueryHook) BeforeQuery(ctx context.Context, event *pg.QueryEvent) (context.Context, error) { +func (h *logQueryHook) BeforeQuery(ctx context.Context, event *bun.QueryEvent) context.Context { event.StartTime = time.Now() - return ctx, nil + return ctx } -func (h *logQueryHook) AfterQuery(ctx context.Context, event *pg.QueryEvent) error { - query, err := event.FormattedQuery() - if err != nil { - return err - } - - // logger.Info().Interface("params", event.Params).Msg("") +// AfterQuery - +func (h *logQueryHook) AfterQuery(ctx context.Context, event *bun.QueryEvent) { if event.Err != nil { - logger.Info().Msgf("[%d ms] %s : %s", time.Since(event.StartTime).Milliseconds(), event.Err.Error(), string(query)) + log.Trace().Msgf("[%d mcs] %s : %s", time.Since(event.StartTime).Microseconds(), event.Err.Error(), event.Query) } else { - logger.Info().Msgf("[%d ms] %d rows | %s", time.Since(event.StartTime).Milliseconds(), event.Result.RowsReturned(), string(query)) + log.Trace().Msgf("[%d mcs] %s", time.Since(event.StartTime).Microseconds(), event.Query) } - return nil } diff --git a/internal/postgres/core/options.go b/internal/postgres/core/options.go index 56c14a3cf..bff74df5a 100644 --- a/internal/postgres/core/options.go +++ b/internal/postgres/core/options.go @@ -1,8 +1,6 @@ package core import ( - "time" - "github.com/baking-bad/bcdhub/internal/postgres/consts" ) @@ -19,32 +17,6 @@ func WithPageSize(pageSize int64) PostgresOption { } } -// WithMaxConnections - -func WithMaxConnections(count int) PostgresOption { - return func(pg *Postgres) { - if count == 0 { - count = consts.DefaultSize - } - if opts := pg.DB.Options(); opts != nil { - opts.PoolSize = count - opts.MaxConnAge = time.Hour - } - } -} - -// WithIdleConnections - -func WithIdleConnections(count int) PostgresOption { - return func(pg *Postgres) { - if count == 0 { - count = consts.DefaultSize - } - if opts := pg.DB.Options(); opts != nil { - opts.IdleTimeout = time.Minute * 30 - opts.MinIdleConns = count - } - } -} - // WithQueryLogging - func WithQueryLogging() PostgresOption { return func(pg *Postgres) { diff --git a/internal/postgres/core/postgres.go b/internal/postgres/core/postgres.go index 7208d63a5..2f1342b10 100644 --- a/internal/postgres/core/postgres.go +++ b/internal/postgres/core/postgres.go @@ -2,97 +2,104 @@ package core import ( "context" + "database/sql" "fmt" - "strings" + "runtime" "time" - bcdLogger "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models" - pg "github.com/go-pg/pg/v10" - "github.com/go-pg/pg/v10/orm" "github.com/pkg/errors" + "github.com/rs/zerolog/log" + "github.com/uptrace/bun" + "github.com/uptrace/bun/dialect/pgdialect" + "github.com/uptrace/bun/driver/pgdriver" ) // Postgres - type Postgres struct { - DB *pg.DB + DB *bun.DB + conn *sql.DB PageSize int64 schema string } -func parseConnectionString(connection, schemaName string) (*pg.Options, error) { - if len(connection) == 0 { - return nil, errors.New("invalid connection string") +func connectionOptions(cfg Config, schema string, appName string) ([]pgdriver.Option, error) { + opts := make([]pgdriver.Option, 0) + + if cfg.DBName != "" { + opts = append(opts, pgdriver.WithDatabase(cfg.DBName)) + } else { + return nil, errors.New("empty database name") } - items := strings.Split(connection, " ") - if len(items) == 0 { - return nil, errors.Errorf("invalid connection string: %s", connection) + if cfg.Host != "" && cfg.Port > 0 { + opts = append(opts, pgdriver.WithAddr(fmt.Sprintf("%s:%d", cfg.Host, cfg.Port))) + } else { + return nil, errors.Errorf("empty host or zero port: host=%s port=%d", cfg.Host, cfg.Port) } - opts := new(pg.Options) - var host string - var port string - for i := range items { - values := strings.Split(items[i], "=") - if len(values) != 2 { - return nil, errors.Errorf("invalid connection string: %s", connection) - } + if cfg.User != "" { + opts = append(opts, pgdriver.WithUser(cfg.User)) + } else { + return nil, errors.New("empty database user") + } - switch values[0] { - case "host": - host = values[1] - case "user": - opts.User = values[1] - case "password": - opts.Password = values[1] - case "port": - port = values[1] - case "dbname": - opts.Database = values[1] - } + if cfg.Password != "" { + opts = append(opts, pgdriver.WithPassword(cfg.Password)) + } else { + return nil, errors.New("empty database password") + } + + if appName != "" { + opts = append(opts, pgdriver.WithApplicationName(appName)) } - opts.Addr = fmt.Sprintf("%s:%s", host, port) - opts.IdleTimeout = time.Second * 15 - opts.IdleCheckFrequency = time.Second * 10 - opts.OnConnect = func(ctx context.Context, cn *pg.Conn) error { - schema := pg.Ident(schemaName) - if _, err := cn.Exec("create schema if not exists ?", schema); err != nil { - return err + if cfg.SslMode != "" { + switch cfg.SslMode { + case "disable": + opts = append(opts, pgdriver.WithInsecure(true)) + default: } - _, err := cn.Exec("set search_path = ?", schema) - return err } + if schema != "" { + opts = append(opts, pgdriver.WithConnParams(map[string]interface{}{ + "search_path": schema, + })) + } + + opts = append(opts, pgdriver.WithTimeout(time.Minute*10)) + return opts, nil } // New - -func New(connection, schemaName, appName string, opts ...PostgresOption) (*Postgres, error) { +func New(cfg Config, schemaName, appName string, opts ...PostgresOption) (*Postgres, error) { postgres := Postgres{ schema: schemaName, } - if appName != "" { - connection = fmt.Sprintf("%s application_name=%s", connection, appName) - } - opt, err := parseConnectionString(connection, schemaName) + connectionOptions, err := connectionOptions(cfg, schemaName, appName) if err != nil { return nil, err } - postgres.DB = pg.Connect(opt) + pgconn := pgdriver.NewConnector(connectionOptions...) + postgres.conn = sql.OpenDB(pgconn) + postgres.DB = bun.NewDB(postgres.conn, pgdialect.New()) + + maxOpenConns := 4 * runtime.GOMAXPROCS(0) + postgres.conn.SetMaxOpenConns(maxOpenConns) + postgres.conn.SetMaxIdleConns(maxOpenConns) for _, opt := range opts { opt(&postgres) } - for _, model := range models.ManyToMany() { - orm.RegisterTable(model) - } + // register many-to-many relationships + postgres.DB.RegisterModel(models.ManyToMany()...) return &postgres, nil } @@ -102,7 +109,7 @@ const ( ) // WaitNew - waiting for db up and creating connection -func WaitNew(connectionString, schemaName, appName string, timeout int, opts ...PostgresOption) *Postgres { +func WaitNew(cfg Config, schemaName, appName string, timeout int, opts ...PostgresOption) *Postgres { var db *Postgres var err error @@ -111,29 +118,48 @@ func WaitNew(connectionString, schemaName, appName string, timeout int, opts ... } for db == nil { - db, err = New(connectionString, schemaName, appName, opts...) + db, err = New(cfg, schemaName, appName, opts...) if err != nil { - bcdLogger.Warning().Msgf("Waiting postgres up %d seconds...", timeout) + log.Warn().Msgf("Waiting postgres up %d seconds...", timeout) time.Sleep(time.Second * time.Duration(timeout)) } } - for err := db.DB.Ping(context.Background()); err != nil; err = db.DB.Ping(context.Background()) { - bcdLogger.Warning().Msgf("Waiting postgres up %d seconds...", timeout) + for err := db.DB.Ping(); err != nil; err = db.DB.Ping() { + log.Warn().Msgf("Waiting postgres up %d seconds...", timeout) time.Sleep(time.Second * time.Duration(timeout)) } return db } +func (p *Postgres) InitDatabase(ctx context.Context) error { + if err := createSchema(ctx, p.DB, p.schema); err != nil { + return err + } + + if err := createTables(ctx, p.DB); err != nil { + return err + } + + if err := createBaseIndices(ctx, p.DB); err != nil { + return err + } + + return nil +} + // Close - func (p *Postgres) Close() error { - return p.DB.Close() + if err := p.conn.Close(); err != nil { + return err + } + return p.conn.Close() } // IsRecordNotFound - func (p *Postgres) IsRecordNotFound(err error) bool { - return err != nil && errors.Is(err, pg.ErrNoRows) + return err != nil && errors.Is(err, sql.ErrNoRows) } // Execute - diff --git a/internal/postgres/core/postgres_test.go b/internal/postgres/core/postgres_test.go deleted file mode 100644 index cdf1bd6fe..000000000 --- a/internal/postgres/core/postgres_test.go +++ /dev/null @@ -1,46 +0,0 @@ -package core - -import ( - "testing" - "time" - - pg "github.com/go-pg/pg/v10" - "github.com/stretchr/testify/assert" -) - -func Test_parseConncetionString(t *testing.T) { - tests := []struct { - name string - connection string - want *pg.Options - wantErr bool - }{ - { - name: "test 1", - connection: "host=127.0.0.1 port=5432 user=user dbname=indexer password=password sslmode=disable", - want: &pg.Options{ - Addr: "127.0.0.1:5432", - User: "user", - Password: "password", - Database: "indexer", - IdleTimeout: time.Second * 15, - IdleCheckFrequency: time.Second * 10, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got, err := parseConnectionString(tt.connection, "") - if (err != nil) != tt.wantErr { - t.Errorf("parseConncetionString() error = %v, wantErr %v", err, tt.wantErr) - return - } - assert.Equal(t, tt.want.Addr, got.Addr) - assert.Equal(t, tt.want.User, got.User) - assert.Equal(t, tt.want.Password, got.Password) - assert.Equal(t, tt.want.Database, got.Database) - assert.Equal(t, tt.want.IdleTimeout, got.IdleTimeout) - assert.Equal(t, tt.want.IdleCheckFrequency, got.IdleCheckFrequency) - }) - } -} diff --git a/internal/postgres/core/scopes.go b/internal/postgres/core/scopes.go index 8ec09858c..15bd87648 100644 --- a/internal/postgres/core/scopes.go +++ b/internal/postgres/core/scopes.go @@ -3,43 +3,36 @@ package core import ( "time" - "github.com/go-pg/pg/v10/orm" + "github.com/uptrace/bun" ) // Address - -func Address(address string) func(db *orm.Query) *orm.Query { - return func(db *orm.Query) *orm.Query { - return db.Where("address = ?", address) - } +func Address(query *bun.SelectQuery, address string) *bun.SelectQuery { + return query.Where("address = ?", address) } // Contract - -func Contract(address string) func(db *orm.Query) *orm.Query { - return func(db *orm.Query) *orm.Query { - return db.Where("contract = ?", address) - } +func Contract(query *bun.SelectQuery, address string) *bun.SelectQuery { + return query.Where("contract = ?", address) } // OrderByLevelDesc - -func OrderByLevelDesc(db *orm.Query) *orm.Query { +func OrderByLevelDesc(db *bun.SelectQuery) *bun.SelectQuery { return db.Order("level desc") } // IsApplied - -func IsApplied(db *orm.Query) *orm.Query { +func IsApplied(db *bun.SelectQuery) *bun.SelectQuery { return db.Where("status = 1") } // Token - -func Token(contract string, tokenID uint64) func(db *orm.Query) *orm.Query { - return func(db *orm.Query) *orm.Query { - return db.Where("contract = ?", contract). - Where("token_id = ?", tokenID) - } +func Token(query *bun.SelectQuery, contract string, tokenID uint64) *bun.SelectQuery { + return query.Where("contract = ?", contract).Where("token_id = ?", tokenID) } // EmptyRelation - -var EmptyRelation = func(q *orm.Query) (*orm.Query, error) { +var EmptyRelation = func(q *bun.Query) (*bun.Query, error) { return q, nil } @@ -52,7 +45,7 @@ type TimestampFilter struct { } // Apply - -func (tf TimestampFilter) Apply(q *orm.Query) *orm.Query { +func (tf TimestampFilter) Apply(q *bun.SelectQuery) *bun.SelectQuery { if q == nil { return q } diff --git a/internal/postgres/core/table.go b/internal/postgres/core/table.go new file mode 100644 index 000000000..c71f2f230 --- /dev/null +++ b/internal/postgres/core/table.go @@ -0,0 +1,129 @@ +package core + +import ( + "context" + "sync" + + "github.com/baking-bad/bcdhub/internal/models" + "github.com/baking-bad/bcdhub/internal/models/bigmapaction" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/block" + "github.com/baking-bad/bcdhub/internal/models/contract" + "github.com/baking-bad/bcdhub/internal/models/migration" + "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/ticket" + "github.com/rs/zerolog/log" + "github.com/uptrace/bun" +) + +func createTable(ctx context.Context, db bun.IDB, model models.Model) error { + if model == nil { + return nil + } + + query := db. + NewCreateTable(). + Model(model). + IfNotExists() + + _, err := query.Exec(ctx) + return err +} + +func createTables(ctx context.Context, db *bun.DB) error { + for _, model := range models.AllModels() { + if err := createTable(ctx, db, model); err != nil { + return err + } + } + return createHypertables(ctx, db) +} + +func createHypertables(ctx context.Context, db *bun.DB) error { + for _, model := range []models.Model{ + &block.Block{}, + &bigmapdiff.BigMapDiff{}, + &bigmapaction.BigMapAction{}, + &contract.Contract{}, + &migration.Migration{}, + &operation.Operation{}, + &ticket.TicketUpdate{}, + } { + if _, err := db.ExecContext(ctx, + `SELECT public.create_hypertable(?, 'timestamp', chunk_time_interval => INTERVAL '1 month', if_not_exists => TRUE);`, + model.TableName(), + ); err != nil { + return err + } + } + + return nil +} + +var createExtensionOnce sync.Once +var wg sync.WaitGroup + +func createSchema(ctx context.Context, db *bun.DB, schemaName string) error { + createExtensionOnce.Do(func() { + defer wg.Done() + wg.Add(1) + if _, err := db.NewRaw("set search_path = 'public'").Exec(ctx); err != nil { + log.Err(err).Msg("set search path to public") + return + } + if _, err := db.NewRaw("CREATE EXTENSION IF NOT EXISTS timescaledb;").Exec(ctx); err != nil { + log.Err(err).Msg("create timescale extension") + } + }) + + wg.Wait() + + schema := bun.Ident(schemaName) + if _, err := db.NewRaw("create schema if not exists ?", schema).Exec(ctx); err != nil { + return err + } + if _, err := db.NewRaw("set search_path = ?", schema).Exec(ctx); err != nil { + return err + } + return nil +} + +// Drop - drops full database +func (p *Postgres) Drop(ctx context.Context) error { + for _, table := range models.ManyToMany() { + if _, err := p.DB.NewDropTable().Model(table).IfExists().Cascade().Exec(ctx); err != nil { + return err + } + } + + for _, table := range models.AllModels() { + if _, err := p.DB.NewDropTable().Model(table).IfExists().Cascade().Exec(ctx); err != nil { + return err + } + } + return nil +} + +const tableExistsQuery = `SELECT EXISTS( + SELECT * + FROM information_schema.tables + WHERE + table_schema = ? AND + table_name = ? +) as flag;` + +type existsResponse struct { + Flag bool `bun:"flag"` +} + +// TablesExist - returns true if all tables exist otherwise false +func (p *Postgres) TablesExist(ctx context.Context) bool { + for _, table := range models.AllDocuments() { + var exists existsResponse + err := p.DB.QueryRow(tableExistsQuery, p.schema, table).Scan(&exists) + if !exists.Flag || err != nil { + return false + } + } + return true +} diff --git a/internal/postgres/core/transaction.go b/internal/postgres/core/transaction.go new file mode 100644 index 000000000..9de7d712e --- /dev/null +++ b/internal/postgres/core/transaction.go @@ -0,0 +1,291 @@ +package core + +import ( + "context" + + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/baking-bad/bcdhub/internal/models/bigmapaction" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/block" + "github.com/baking-bad/bcdhub/internal/models/contract" + "github.com/baking-bad/bcdhub/internal/models/migration" + "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/protocol" + smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" + "github.com/baking-bad/bcdhub/internal/models/stats" + "github.com/baking-bad/bcdhub/internal/models/ticket" + "github.com/uptrace/bun" +) + +type Transaction struct { + tx bun.Tx +} + +// NewTransaction - +func NewTransaction(ctx context.Context, db *bun.DB) (Transaction, error) { + tx, err := db.BeginTx(ctx, nil) + if err != nil { + return Transaction{}, err + } + return Transaction{tx}, nil +} + +func (t Transaction) Commit() error { + return t.tx.Commit() +} + +func (t Transaction) Rollback() error { + return t.tx.Rollback() +} + +func (t Transaction) Save(ctx context.Context, data any) error { + _, err := t.tx.NewInsert().Model(data).Returning("id").Exec(ctx) + return err +} + +func (t Transaction) Migrations(ctx context.Context, migrations ...*migration.Migration) error { + if len(migrations) == 0 { + return nil + } + return t.Save(ctx, &migrations) +} + +func (t Transaction) GlobalConstants(ctx context.Context, constants ...*contract.GlobalConstant) error { + if len(constants) == 0 { + return nil + } + return t.Save(ctx, &constants) +} + +func (t Transaction) BigMapStates(ctx context.Context, states ...*bigmapdiff.BigMapState) error { + if len(states) == 0 { + return nil + } + _, err := t.tx. + NewInsert(). + Model(&states). + On("CONFLICT ON CONSTRAINT big_map_state_unique DO UPDATE"). + Set("removed = EXCLUDED.removed"). + Set("last_update_level = EXCLUDED.last_update_level"). + Set("last_update_time = EXCLUDED.last_update_time"). + Set("count = big_map_state.count + 1"). + Set("value = CASE WHEN EXCLUDED.removed THEN big_map_state.value ELSE EXCLUDED.value END"). + Returning("id"). + Exec(ctx) + return err +} + +func (t Transaction) BigMapDiffs(ctx context.Context, bigmapdiffs ...*bigmapdiff.BigMapDiff) error { + if len(bigmapdiffs) == 0 { + return nil + } + return t.Save(ctx, &bigmapdiffs) +} + +func (t Transaction) BigMapActions(ctx context.Context, bigmapactions ...*bigmapaction.BigMapAction) error { + if len(bigmapactions) == 0 { + return nil + } + return t.Save(ctx, &bigmapactions) +} + +func (t Transaction) Accounts(ctx context.Context, accounts ...*account.Account) error { + if len(accounts) == 0 { + return nil + } + _, err := t.tx.NewInsert().Model(&accounts). + Column("address", "level", "type", "operations_count", "last_action", "events_count", "migrations_count", "ticket_updates_count"). + On("CONFLICT ON CONSTRAINT address_hash DO UPDATE"). + Set("operations_count = EXCLUDED.operations_count + account.operations_count"). + Set("events_count = EXCLUDED.events_count + account.events_count"). + Set("migrations_count = EXCLUDED.migrations_count + account.migrations_count"). + Set("ticket_updates_count = EXCLUDED.ticket_updates_count + account.ticket_updates_count"). + Set("last_action = EXCLUDED.last_action"). + Returning("id"). + Exec(ctx) + return err +} + +func (t Transaction) SmartRollups(ctx context.Context, rollups ...*smartrollup.SmartRollup) error { + if len(rollups) == 0 { + return nil + } + return t.Save(ctx, &rollups) +} + +func (t Transaction) Operations(ctx context.Context, operations ...*operation.Operation) error { + if len(operations) == 0 { + return nil + } + return t.Save(ctx, &operations) +} + +func (t Transaction) TickerUpdates(ctx context.Context, updates ...*ticket.TicketUpdate) error { + if len(updates) == 0 { + return nil + } + return t.Save(ctx, &updates) +} + +func (t Transaction) Contracts(ctx context.Context, contracts ...*contract.Contract) error { + if len(contracts) == 0 { + return nil + } + return t.Save(ctx, &contracts) +} + +func (t Transaction) Scripts(ctx context.Context, scripts ...*contract.Script) error { + if len(scripts) == 0 { + return nil + } + _, err := t.tx.NewInsert(). + Model(&scripts). + On("CONFLICT (hash) DO UPDATE"). + Set("tags = EXCLUDED.tags"). + Returning("id"). + Exec(ctx) + return err +} + +func (t Transaction) ScriptConstant(ctx context.Context, relations ...*contract.ScriptConstants) error { + if len(relations) == 0 { + return nil + } + _, err := t.tx.NewInsert().Model(&relations).Exec(ctx) + return err +} + +func (t Transaction) Block(ctx context.Context, block *block.Block) error { + if block == nil { + return nil + } + return t.Save(ctx, block) +} + +func (t Transaction) Protocol(ctx context.Context, proto *protocol.Protocol) error { + if proto == nil { + return nil + } + _, err := t.tx.NewInsert(). + Model(proto). + On("CONFLICT ON CONSTRAINT protocol_hash_idx DO UPDATE"). + Set("end_level = ?", proto.EndLevel). + Returning("id"). + Exec(ctx) + return err +} + +func (t Transaction) BabylonUpdateNonDelegator(ctx context.Context, contract *contract.Contract) error { + _, err := t.tx.NewUpdate(). + Model(contract). + Set("babylon_id = ?babylon_id"). + Where("id = ?id"). + Exec(ctx) + return err +} + +func (t Transaction) JakartaVesting(ctx context.Context, contract *contract.Contract) error { + _, err := t.tx.NewUpdate(). + Model(contract). + Set("jakarta_id = babylon_id"). + Where("id = ?id"). + Exec(ctx) + return err +} + +func (t Transaction) JakartaUpdateNonDelegator(ctx context.Context, contract *contract.Contract) error { + _, err := t.tx.NewUpdate(). + Model(contract). + Set("jakarta_id = ?jakarta_id"). + Where("id = ?id"). + Exec(ctx) + return err +} + +func (t Transaction) ToBabylon(ctx context.Context) error { + _, err := t.tx.NewUpdate().Model((*contract.Contract)(nil)). + Set("babylon_id = alpha_id"). + Where("tags & 4 > 0"). + Exec(ctx) + return err +} + +func (t Transaction) ToJakarta(ctx context.Context) error { + _, err := t.tx.NewUpdate().Model((*contract.Contract)(nil)). + Set("jakarta_id = babylon_id"). + Where("tags & 4 > 0"). + Exec(ctx) + return err +} + +func (t Transaction) UpdateStats(ctx context.Context, stats stats.Stats) error { + _, err := t.tx.NewInsert(). + Model(&stats). + On("CONFLICT (id) DO UPDATE"). + Set("contracts_count = EXCLUDED.contracts_count + stats.contracts_count"). + Set("operations_count = EXCLUDED.operations_count + stats.operations_count"). + Set("events_count = EXCLUDED.events_count + stats.events_count"). + Set("tx_count = EXCLUDED.tx_count + stats.tx_count"). + Set("originations_count = EXCLUDED.originations_count + stats.originations_count"). + Set("sr_originations_count = EXCLUDED.sr_originations_count + stats.sr_originations_count"). + Set("register_global_constants_count = EXCLUDED.register_global_constants_count + stats.register_global_constants_count"). + Set("sr_executes_count = EXCLUDED.sr_executes_count + stats.sr_executes_count"). + Set("transfer_tickets_count = EXCLUDED.transfer_tickets_count + stats.transfer_tickets_count"). + Set("global_constants_count = EXCLUDED.global_constants_count + stats.global_constants_count"). + Set("smart_rollups_count = EXCLUDED.smart_rollups_count + stats.smart_rollups_count"). + Returning("id"). + Exec(ctx) + return err +} + +func (t Transaction) Tickets(ctx context.Context, tickets ...*ticket.Ticket) error { + if len(tickets) == 0 { + return nil + } + + _, err := t.tx.NewInsert().Model(&tickets). + Column("ticketer_id", "content", "content_type", "updates_count", "level"). + On("CONFLICT ON CONSTRAINT ticket_key DO UPDATE"). + Set("updates_count = ticket.updates_count + EXCLUDED.updates_count"). + Returning("id"). + Exec(ctx) + return err +} + +func (t Transaction) TicketBalances(ctx context.Context, balances ...*ticket.Balance) error { + if len(balances) == 0 { + return nil + } + + _, err := t.tx.NewInsert().Model(&balances). + Column("ticket_id", "account_id", "amount"). + On("CONFLICT (ticket_id, account_id) DO UPDATE"). + Set("amount = balance.amount + EXCLUDED.amount"). + Exec(ctx) + return err +} + +func (t Transaction) DeleteBigMapStatesByContract(ctx context.Context, contract string) (states []bigmapdiff.BigMapState, err error) { + _, err = t.tx.NewDelete(). + Model((*bigmapdiff.BigMapState)(nil)). + Where("contract = ?", contract). + Returning("*"). + Exec(ctx, &states) + return +} + +func (t Transaction) BabylonUpdateBigMapDiffs(ctx context.Context, contract string, ptr int64) (int, error) { + res, err := t.tx.NewUpdate(). + Model((*bigmapdiff.BigMapDiff)(nil)). + Where("contract = ?", contract). + Set("ptr = ?", ptr). + Exec(ctx) + if err != nil { + return 0, err + } + count, err := res.RowsAffected() + if err != nil { + return 0, err + } + return int(count), nil +} diff --git a/internal/postgres/core/update.go b/internal/postgres/core/update.go index 8860e0afd..28377ac9d 100644 --- a/internal/postgres/core/update.go +++ b/internal/postgres/core/update.go @@ -4,17 +4,9 @@ import ( "reflect" "strings" - "github.com/baking-bad/bcdhub/internal/models" "github.com/iancoleman/strcase" ) -// UpdateDoc - -func (p *Postgres) UpdateDoc(model models.Model) error { - el := reflect.ValueOf(model).Interface() - _, err := p.DB.Model().Table(model.GetIndex()).Where("id = ?", model.GetID()).Update(el) - return err -} - // GetFieldsForModel - func GetFieldsForModel(data interface{}, fields ...string) map[string]interface{} { t := reflect.TypeOf(data) diff --git a/internal/postgres/domains/storage.go b/internal/postgres/domains/storage.go index 7ea7dae66..b34867cfb 100644 --- a/internal/postgres/domains/storage.go +++ b/internal/postgres/domains/storage.go @@ -1,14 +1,15 @@ package domains import ( + "context" + "database/sql" "errors" - "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/domains" "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/postgres/core" - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // Storage - @@ -21,29 +22,8 @@ func NewStorage(pg *core.Postgres) *Storage { return &Storage{pg} } -// BigMapDiffs - -func (storage *Storage) BigMapDiffs(lastID, size int64) (result []domains.BigMapDiff, err error) { - var ids []int64 - query := storage.DB.Model((*bigmapdiff.BigMapDiff)(nil)).Column("id").Order("id asc") - if lastID > 0 { - query.Where("big_map_diff.id > ?", lastID) - } - if err = query.Limit(storage.GetPageSize(size)).Select(&ids); err != nil { - return - } - - if len(ids) == 0 { - return - } - - err = storage.DB.Model((*domains.BigMapDiff)(nil)).WhereIn("big_map_diff.id IN (?)", ids). - Relation("Operation").Relation("Protocol"). - Select(&result) - return -} - // Same - -func (storage *Storage) Same(network string, c contract.Contract, limit, offset int, availiableNetworks ...string) ([]domains.Same, error) { +func (storage *Storage) Same(ctx context.Context, network string, c contract.Contract, limit, offset int, availiableNetworks ...string) ([]domains.Same, error) { if limit < 1 || limit > 10 { limit = 10 } @@ -61,22 +41,25 @@ func (storage *Storage) Same(network string, c contract.Contract, limit, offset return nil, errors.New("invalid contract script") } - var union *pg.Query + var union *bun.SelectQuery for i, value := range availiableNetworks { - schema := pg.Safe(value) + schema := bun.Safe(value) - query := storage.DB.Model(). + query := storage.DB.NewSelect(). TableExpr("?.contracts", schema). ColumnExpr("? as network", value). ColumnExpr("contracts.*"). - ColumnExpr("accounts.address as account__address"). + ColumnExpr("accounts.address as account__address, accounts.last_action as account__last_action"). Join("LEFT JOIN ?.accounts on contracts.account_id = accounts.id", schema). Join("LEFT JOIN ?.scripts as alpha on alpha.id = contracts.alpha_id", schema). Join("LEFT JOIN ?.scripts as babylon on babylon.id = contracts.babylon_id", schema). Join("LEFT JOIN ?.scripts as jakarta on jakarta.id = contracts.jakarta_id", schema). - Where("alpha.hash = ?", script.Hash). - WhereOr("babylon.hash = ?", script.Hash). - WhereOr("jakarta.hash = ?", script.Hash) + WhereGroup(" AND ", func(sq *bun.SelectQuery) *bun.SelectQuery { + return sq. + Where("alpha.hash = ?", script.Hash). + WhereOr("babylon.hash = ?", script.Hash). + WhereOr("jakarta.hash = ?", script.Hash) + }) if value == network { query.Where("contracts.id != ?", c.ID) @@ -90,16 +73,16 @@ func (storage *Storage) Same(network string, c contract.Contract, limit, offset } var same []domains.Same - err := storage.DB.Model(). + err := storage.DB.NewSelect(). TableExpr("(?) as same", union). Limit(limit). Offset(offset). - Select(&same) + Scan(ctx, &same) return same, err } // SameCount - -func (storage *Storage) SameCount(c contract.Contract, availiableNetworks ...string) (int, error) { +func (storage *Storage) SameCount(ctx context.Context, c contract.Contract, availiableNetworks ...string) (int, error) { if len(availiableNetworks) == 0 { return 0, nil } @@ -109,11 +92,11 @@ func (storage *Storage) SameCount(c contract.Contract, availiableNetworks ...str return 0, errors.New("invalid contract script") } - var union *pg.Query + var union *bun.SelectQuery for i, value := range availiableNetworks { - schema := pg.Safe(value) + schema := bun.Safe(value) - query := storage.DB.Model(). + query := storage.DB.NewSelect(). TableExpr("?.contracts", schema). ColumnExpr("count(*) as c"). Join("LEFT JOIN ?.scripts as alpha on alpha.id = contracts.alpha_id", schema). @@ -131,8 +114,8 @@ func (storage *Storage) SameCount(c contract.Contract, availiableNetworks ...str } var count int - if err := storage.DB.Model().ColumnExpr("sum(c)").TableExpr("(?) as same", union).Select(&count); err != nil { - if errors.Is(err, pg.ErrNoRows) { + if err := storage.DB.NewSelect().ColumnExpr("sum(c)").TableExpr("(?) as same", union).Scan(ctx, &count); err != nil { + if errors.Is(err, sql.ErrNoRows) { return 0, nil } return 0, err diff --git a/internal/postgres/global_constant/storage.go b/internal/postgres/global_constant/storage.go index 84229c788..eeb92efea 100644 --- a/internal/postgres/global_constant/storage.go +++ b/internal/postgres/global_constant/storage.go @@ -1,14 +1,15 @@ package global_constant import ( + "context" "fmt" "strings" + "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/postgres/consts" "github.com/baking-bad/bcdhub/internal/postgres/core" - "github.com/go-pg/pg/v10" - "github.com/go-pg/pg/v10/orm" + "github.com/uptrace/bun" ) // Storage - @@ -22,25 +23,25 @@ func NewStorage(pg *core.Postgres) *Storage { } // Get - -func (storage *Storage) Get(address string) (response contract.GlobalConstant, err error) { - query := storage.DB.Model(&response) - core.Address(address)(query) - err = query.First() +func (storage *Storage) Get(ctx context.Context, address string) (response contract.GlobalConstant, err error) { + query := storage.DB.NewSelect().Model(&response) + query = core.Address(query, address) + err = query.Limit(1).Scan(ctx) return } // All - -func (storage *Storage) All(addresses ...string) (response []contract.GlobalConstant, err error) { +func (storage *Storage) All(ctx context.Context, addresses ...string) (response []contract.GlobalConstant, err error) { if len(addresses) == 0 { return } - err = storage.DB.Model((*contract.GlobalConstant)(nil)).Where("address IN (?)", pg.In(addresses)).Select(&response) + err = storage.DB.NewSelect().Model(&response).Where("address IN (?)", bun.In(addresses)).Scan(ctx) return } // List - -func (storage *Storage) List(size, offset int64, orderBy, sort string) ([]contract.ListGlobalConstantItem, error) { +func (storage *Storage) List(ctx context.Context, size, offset int64, orderBy, sort string) ([]contract.ListGlobalConstantItem, error) { if offset < 0 { return nil, nil } @@ -63,14 +64,14 @@ func (storage *Storage) List(size, offset int64, orderBy, sort string) ([]contra } var constants []contract.ListGlobalConstantItem - _, err := storage.DB.Query(&constants, + err := storage.DB.NewRaw( `select global_constants.timestamp, global_constants.level, global_constants.address, count(contracts.id) as links_count from global_constants left join script_constants as t on global_constants.id = t.global_constant_id - left join contracts on t.script_id = contracts.babylon_id or t.script_id = contracts.jakarta_id + left join contracts on t.script_id = contracts.jakarta_id group by global_constants.id order by ? limit ? - offset ?`, pg.Safe(orderBy), size, offset) + offset ?`, bun.Safe(orderBy), size, offset).Scan(ctx, &constants) if err != nil { return nil, err } @@ -83,7 +84,7 @@ func (storage *Storage) List(size, offset int64, orderBy, sort string) ([]contra } // ForContract - -func (storage *Storage) ForContract(address string, size, offset int64) (response []contract.GlobalConstant, err error) { +func (storage *Storage) ForContract(ctx context.Context, address string, size, offset int64) (response []contract.GlobalConstant, err error) { if offset < 0 || address == "" { return nil, nil } @@ -91,22 +92,52 @@ func (storage *Storage) ForContract(address string, size, offset int64) (respons size = consts.DefaultSize } - err = storage.DB.Model((*contract.Contract)(nil)). + var accountID int64 + if err = storage.DB. + NewSelect(). + Model((*account.Account)(nil)). + Column("id"). + Where("address = ?", address). + Scan(ctx, &accountID); err != nil { + return + } + + var contr contract.Contract + if err = storage.DB. + NewSelect(). + Column("id", "alpha_id", "babylon_id", "jakarta_id"). + Model(&contr). + Column("id"). + Where("account_id = ?", accountID). + Scan(ctx); err != nil { + return + } + + ids := make([]int64, 0) + if contr.BabylonID > 0 { + ids = append(ids, contr.BabylonID) + } + if contr.JakartaID > 0 { + ids = append(ids, contr.JakartaID) + } + if len(ids) == 0 { + return nil, nil + } + + err = storage.DB.NewSelect().Model((*contract.ScriptConstants)(nil)). ColumnExpr("global_constants.*"). - Join("LEFT JOIN accounts on account_id = accounts.id"). - Join("LEFT JOIN script_constants as t on t.script_id = jakarta_id or t.script_id = babylon_id"). - Join("LEFT JOIN global_constants on t.global_constant_id = global_constants.id"). - Where("accounts.address = ?", address). + Join("LEFT JOIN global_constants on global_constant_id = global_constants.id"). Where("global_constant_id is not null"). + Where("script_id IN (?)", bun.In(ids)). Limit(int(size)). Offset(int(offset)). - Order("id desc"). - Select(&response) + Order("global_constants.id desc"). + Scan(ctx, &response) return } // ContractList - -func (storage *Storage) ContractList(address string, size, offset int64) ([]contract.Contract, error) { +func (storage *Storage) ContractList(ctx context.Context, address string, size, offset int64) ([]contract.Contract, error) { if offset < 0 || address == "" { return nil, nil } @@ -115,19 +146,19 @@ func (storage *Storage) ContractList(address string, size, offset int64) ([]cont } var id uint64 - if err := storage.DB.Model((*contract.GlobalConstant)(nil)). + if err := storage.DB.NewSelect().Model((*contract.GlobalConstant)(nil)). Column("id"). Where("address = ?", address). - Select(&id); err != nil { + Scan(ctx, &id); err != nil { return nil, err } var scriptIDs []uint64 - if err := storage.DB.Model(new(contract.ScriptConstants)). + if err := storage.DB.NewSelect().Model(new(contract.ScriptConstants)). DistinctOn("script_id"). Column("script_id"). Where("global_constant_id = ?", id). - Select(&scriptIDs); err != nil { + Scan(ctx, &scriptIDs); err != nil { return nil, err } if len(scriptIDs) == 0 { @@ -135,19 +166,16 @@ func (storage *Storage) ContractList(address string, size, offset int64) ([]cont } var contracts []contract.Contract - if err := storage.DB.Model(&contracts). + if err := storage.DB.NewSelect().Model(&contracts). ColumnExpr("contract.*"). - ColumnExpr("accounts.address as account__address, accounts.alias as account__alias"). - WhereIn("contract.babylon_id IN (?)", scriptIDs). - WhereOrGroup(func(q *orm.Query) (*orm.Query, error) { - q.WhereIn("contract.jakarta_id IN (?)", scriptIDs) - return q, nil - }). + ColumnExpr("accounts.address as account__address"). + Where("contract.babylon_id IN (?)", bun.In(scriptIDs)). + WhereOr("contract.jakarta_id IN (?)", bun.In(scriptIDs)). Join("LEFT JOIN accounts on contract.account_id = accounts.id"). Order("contract.id desc"). Limit(int(size)). Offset(int(offset)). - Select(&contracts); err != nil { + Scan(ctx); err != nil { return nil, err } return contracts, nil diff --git a/internal/postgres/migration/storage.go b/internal/postgres/migration/storage.go index 355f996f7..5fd3a54ba 100644 --- a/internal/postgres/migration/storage.go +++ b/internal/postgres/migration/storage.go @@ -1,6 +1,8 @@ package migration import ( + "context" + "github.com/baking-bad/bcdhub/internal/models/migration" "github.com/baking-bad/bcdhub/internal/postgres/core" ) @@ -16,7 +18,12 @@ func NewStorage(pg *core.Postgres) *Storage { } // Get - -func (storage *Storage) Get(contractID int64) (migrations []migration.Migration, err error) { - err = storage.DB.Model(&migrations).Where("contract_id = ?", contractID).Order("id desc").Select(&migrations) +func (storage *Storage) Get(ctx context.Context, contractID int64) (migrations []migration.Migration, err error) { + err = storage.DB. + NewSelect(). + Model(&migrations). + Where("contract_id = ?", contractID). + Order("id desc"). + Scan(ctx) return } diff --git a/internal/postgres/operation/storage.go b/internal/postgres/operation/storage.go index 9ab7f1029..046ecdf5f 100644 --- a/internal/postgres/operation/storage.go +++ b/internal/postgres/operation/storage.go @@ -1,21 +1,16 @@ package operation import ( - "fmt" + "context" + "database/sql" "time" - "github.com/baking-bad/bcdhub/internal/bcd" "github.com/baking-bad/bcdhub/internal/bcd/consts" "github.com/baking-bad/bcdhub/internal/helpers" - "github.com/baking-bad/bcdhub/internal/models" "github.com/baking-bad/bcdhub/internal/models/account" - "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/operation" - "github.com/baking-bad/bcdhub/internal/models/types" "github.com/baking-bad/bcdhub/internal/postgres/core" - "github.com/go-pg/pg/v10" - "github.com/go-pg/pg/v10/orm" - "github.com/pkg/errors" + "github.com/uptrace/bun" ) // Storage - @@ -28,104 +23,8 @@ func NewStorage(es *core.Postgres) *Storage { return &Storage{es} } -type opgForContract struct { - Counter int64 - Hash *string - ID int64 -} - -func (storage *Storage) getContractOPG(accountID int64, size uint64, filters map[string]interface{}) (response []opgForContract, err error) { - subQuery := storage.DB.Model().Table(models.DocOperations).Column("hash", "counter", "id") - - if _, ok := filters["entrypoints"]; !ok { - subQuery.Where("source_id = ? OR destination_id = ?", accountID, accountID) - } else { - subQuery.Where("destination_id = ?", accountID) - } - - if err := prepareOperationFilters(subQuery, filters); err != nil { - return nil, err - } - - query := storage.DB.Model().TableExpr("(?) as foo", subQuery.Order("id desc").Limit(1000)). - ColumnExpr("foo.hash, foo.counter, max(id) as id") - - limit := storage.GetPageSize(int64(size)) - query.GroupExpr("foo.hash, foo.counter").Order("id desc").Limit(limit) - - err = query.Select(&response) - return -} - -func prepareOperationFilters(query *orm.Query, filters map[string]interface{}) error { - for k, v := range filters { - if v != "" { - switch k { - case "from": - query.Where("timestamp >= to_timestamp(?)", v) - case "to": - query.Where("timestamp <= to_timestamp(?)", v) - case "entrypoints": - query.WhereIn("entrypoint IN (?)", v) - case "last_id": - query.Where("id < ?", v) - case "status": - query.WhereIn("status IN (?)", v) - default: - return errors.Errorf("Unknown operation filter: %s %v", k, v) - } - } - } - return nil -} - -// GetByContract - -func (storage *Storage) GetByAccount(acc account.Account, size uint64, filters map[string]interface{}) (po operation.Pageable, err error) { - opg, err := storage.getContractOPG(acc.ID, size, filters) - if err != nil { - return - } - if len(opg) == 0 { - return - } - - query := storage.DB.Model((*operation.Operation)(nil)).WhereGroup(func(q *orm.Query) (*orm.Query, error) { - for i := range opg { - q.WhereOrGroup(func(q *orm.Query) (*orm.Query, error) { - if opg[i].Hash == nil { - q.Where("operation.hash is null") - } else { - q.Where("operation.hash = ?", opg[i].Hash) - } - return q.Where("operation.counter = ?", opg[i].Counter), nil - }) - } - return q, nil - }).Relation("Destination").Relation("Source").Relation("Initiator").Relation("Delegate") - - addOperationSorting(query) - - if err = query.Select(&po.Operations); err != nil { - return - } - - if len(po.Operations) == 0 { - return - } - - lastID := po.Operations[0].ID - for _, op := range po.Operations[1:] { - if op.ID > lastID { - continue - } - lastID = op.ID - } - po.LastID = fmt.Sprintf("%d", lastID) - return -} - // Last - get last operation by `filters` with not empty deffated_storage -func (storage *Storage) Last(filters map[string]interface{}, lastID int64) (operation.Operation, error) { +func (storage *Storage) Last(ctx context.Context, filters map[string]interface{}, lastID int64) (operation.Operation, error) { var ( current = time.Now() endTime = consts.BeginningOfTime @@ -150,16 +49,16 @@ func (storage *Storage) Last(filters map[string]interface{}, lastID int64) (oper } for current.After(endTime) { - query := storage.DB.Model((*operation.Operation)(nil)). + query := storage.DB.NewSelect().Model((*operation.Operation)(nil)). Where("deffated_storage is not null"). - OrderExpr("operation.id desc") + OrderExpr("operation.timestamp desc, operation.id desc") for key, value := range filters { switch val := value.(type) { case core.TimestampFilter: query = val.Apply(query) default: - query.Where("? = ?", pg.Ident(key), value) + query.Where("? = ?", bun.Ident(key), value) } } @@ -175,13 +74,13 @@ func (storage *Storage) Last(filters map[string]interface{}, lastID int64) (oper query.Limit(1) var ops []operation.Operation - if err := storage.DB.Model().TableExpr("(?) as operation", query). + if err := storage.DB.NewSelect().TableExpr("(?) as operation", query). ColumnExpr("operation.*"). ColumnExpr("source.address as source__address"). ColumnExpr("destination.address as destination__address"). Join("LEFT JOIN accounts as source ON source.id = operation.source_id"). Join("LEFT JOIN accounts as destination ON destination.id = operation.destination_id"). - Select(&ops); err != nil { + Scan(ctx, &ops); err != nil { return operation.Operation{}, err } if len(ops) > 0 { @@ -191,88 +90,28 @@ func (storage *Storage) Last(filters map[string]interface{}, lastID int64) (oper current = lowCurrent } - return operation.Operation{}, pg.ErrNoRows -} - -// Get - -func (storage *Storage) Get(filters map[string]interface{}, size int64, sort bool) (operations []operation.Operation, err error) { - query := storage.DB.Model((*operation.Operation)(nil)).Relation("Destination.address") - - for key, value := range filters { - query.Where("? = ?", pg.Ident(key), value) - } - - if sort { - addOperationSorting(query) - } - - if size > 0 { - query.Limit(storage.GetPageSize(size)) - } - - err = query.Select(&operations) - return operations, err -} - -// GetByHash - -func (storage *Storage) GetByHash(hash []byte) (operations []operation.Operation, err error) { - query := storage.DB.Model((*operation.Operation)(nil)).Where("hash = ?", hash) - addOperationSorting(query) - err = storage.DB.Model().TableExpr("(?) as operation", query). - ColumnExpr("operation.*"). - ColumnExpr("source.address as source__address, source.alias as source__alias, source.type as source__type,source.id as source__id"). - ColumnExpr("destination.address as destination__address, destination.alias as destination__alias, destination.type as destination__type, destination.id as destination__id"). - Join("LEFT JOIN accounts as source ON source.id = operation.source_id"). - Join("LEFT JOIN accounts as destination ON destination.id = operation.destination_id"). - Select(&operations) - return operations, err -} - -// GetContract24HoursVolume - -func (storage *Storage) GetContract24HoursVolume(address string, entrypoints []string) (float64, error) { - aDayAgo := time.Now().UTC().AddDate(0, 0, -1) - var destinationID int64 - if err := storage.DB.Model((*account.Account)(nil)). - Column("id"). - Where("address = ?", address). - Select(&destinationID); err != nil { - return 0, err - } - - var volume float64 - query := storage.DB.Model((*operation.Operation)(nil)). - ColumnExpr("COALESCE(SUM(amount), 0)"). - Where("destination_id = ?", destinationID). - Where("status = ?", types.OperationStatusApplied). - Where("timestamp > ?", aDayAgo) - - if len(entrypoints) > 0 { - query.WhereIn("entrypoint IN (?)", entrypoints) - } - - err := query.Select(&volume) - return volume, err -} - -// GetByIDs - -func (storage *Storage) GetByIDs(ids ...int64) (result []operation.Operation, err error) { - err = storage.DB.Model((*operation.Operation)(nil)).Where("id IN (?)", pg.In(ids)).Order("id asc").Select(&result) - return + return operation.Operation{}, sql.ErrNoRows } // GetByID - -func (storage *Storage) GetByID(id int64) (result operation.Operation, err error) { - err = storage.DB.Model(&result).Relation("Destination").Where("operation.id = ?", id).First() +func (storage *Storage) GetByID(ctx context.Context, id int64) (result operation.Operation, err error) { + err = storage.DB.NewSelect(). + Model(&result). + Relation("Destination"). + Where("operation.id = ?", id). + Limit(1). + Scan(ctx) return } // OPG - -func (storage *Storage) OPG(address string, size, lastID int64) ([]operation.OPG, error) { +func (storage *Storage) OPG(ctx context.Context, address string, size, lastID int64) ([]operation.OPG, error) { var accountID int64 - if err := storage.DB.Model((*account.Account)(nil)). + if err := storage.DB.NewSelect(). + Model((*account.Account)(nil)). Column("id"). Where("address = ?", address). - Select(&accountID); err != nil { + Scan(ctx, &accountID); err != nil { return nil, err } @@ -285,7 +124,7 @@ func (storage *Storage) OPG(address string, size, lastID int64) ([]operation.OPG lastActionSet := false if lastID > 0 { - op, err := storage.GetByID(lastID) + op, err := storage.GetByID(ctx, lastID) if err != nil { if !storage.IsRecordNotFound(err) { return nil, err @@ -295,11 +134,12 @@ func (storage *Storage) OPG(address string, size, lastID int64) ([]operation.OPG lastActionSet = true } } - if !lastActionSet && bcd.IsContractLazy(address) { - if err := storage.DB.Model((*contract.Contract)(nil)). + if !lastActionSet { + if err := storage.DB.NewSelect(). + Model((*account.Account)(nil)). Column("last_action"). - Where("account_id = ?", accountID). - Select(&lastAction); err != nil { + Where("id = ?", accountID). + Scan(ctx, &lastAction); err != nil { return nil, err } } @@ -310,11 +150,11 @@ func (storage *Storage) OPG(address string, size, lastID int64) ([]operation.OPG return nil, err } - subQuery := storage.DB.Model(new(operation.Operation)). + subQuery := storage.DB.NewSelect().Model(new(operation.Operation)). Column("id", "hash", "counter", "status", "kind", "level", "timestamp", "content_index", "entrypoint"). - WhereGroup( - func(q *orm.Query) (*orm.Query, error) { - return q.Where("destination_id = ?", accountID).WhereOr("source_id = ?", accountID), nil + WhereGroup(" AND ", + func(q *bun.SelectQuery) *bun.SelectQuery { + return q.Where("destination_id = ?", accountID).WhereOr("source_id = ?", accountID) }, ). Where("timestamp < ?", endTime). @@ -327,7 +167,7 @@ func (storage *Storage) OPG(address string, size, lastID int64) ([]operation.OPG } var opg []operation.OPG - if _, err := storage.DB.Query(&opg, ` + if err := storage.DB.NewRaw(` with opg as (?0) select ta.last_id, @@ -368,7 +208,7 @@ func (storage *Storage) OPG(address string, size, lastID int64) ([]operation.OPG limit ?2 ) as ta order by last_id desc - `, subQuery, accountID, limit, startTime, endTime); err != nil { + `, subQuery, accountID, limit, startTime, endTime).Scan(ctx, &opg); err != nil { return nil, err } @@ -392,33 +232,42 @@ func (storage *Storage) OPG(address string, size, lastID int64) ([]operation.OPG return result, nil } -// GetByHashAndCounter - -func (storage *Storage) GetByHashAndCounter(hash []byte, counter int64) ([]operation.Operation, error) { - var operations []operation.Operation - err := storage.DB.Model((*operation.Operation)(nil)). - Where("hash = ?", hash). - Where("counter = ?", counter). - Relation("Destination").Relation("Source").Relation("Initiator").Relation("Delegate"). - Order("id asc"). - Select(&operations) +// GetByHash - +func (storage *Storage) GetByHash(ctx context.Context, hash []byte) (operations []operation.Operation, err error) { + query := storage.DB.NewSelect().Model((*operation.Operation)(nil)). + Where("hash = ?", hash) + + addOperationSorting(query) + err = storage.DB.NewSelect().TableExpr("(?) as operation", query). + ColumnExpr("operation.*"). + ColumnExpr("source.address as source__address, source.type as source__type,source.id as source__id"). + ColumnExpr("destination.address as destination__address, destination.type as destination__type, destination.id as destination__id"). + Join("LEFT JOIN accounts as source ON source.id = operation.source_id"). + Join("LEFT JOIN accounts as destination ON destination.id = operation.destination_id"). + Scan(ctx, &operations) return operations, err } -// GetImplicitOperation - -func (storage *Storage) GetImplicitOperation(counter int64) (operation.Operation, error) { - var op operation.Operation - err := storage.DB.Model((*operation.Operation)(nil)). - Where("hash is null"). - Where("counter = ?", counter). +// GetByHashAndCounter - +func (storage *Storage) GetByHashAndCounter(ctx context.Context, hash []byte, counter int64) (operations []operation.Operation, err error) { + query := storage.DB.NewSelect().Model(&operations) + + if hash == nil { + query = query.Where("hash is null") + } else { + query = query.Where("hash = ?", hash) + } + + err = query.Where("counter = ?", counter). Relation("Destination").Relation("Source").Relation("Initiator").Relation("Delegate"). Order("id asc"). - Select(&op) - return op, err + Scan(ctx) + return } // ListEvents - -func (storage *Storage) ListEvents(accountID int64, size, offset int64) ([]operation.Operation, error) { - query := storage.DB.Model((*operation.Operation)(nil)). +func (storage *Storage) ListEvents(ctx context.Context, accountID int64, size, offset int64) (operations []operation.Operation, err error) { + query := storage.DB.NewSelect().Model(&operations). Where("source_id = ?", accountID). Where("kind = 7"). Order("id desc") @@ -432,89 +281,21 @@ func (storage *Storage) ListEvents(accountID int64, size, offset int64) ([]opera query.Limit(10) } - var op []operation.Operation - err := query.Select(&op) - return op, err -} - -// EventsCount - -func (storage *Storage) EventsCount(accountID int64) (int, error) { - return storage.DB.Model((*operation.Operation)(nil)). - Where("source_id = ?", accountID). - Where("kind = 7").Count() -} - -// ContractStats - -func (storage *Storage) ContractStats(address string) (stats operation.ContractStats, err error) { - var accountID int64 - if err = storage.DB.Model((*account.Account)(nil)). - Column("id"). - Where("address = ?", address). - Select(&accountID); err != nil { - return - } - - if bcd.IsContractLazy(address) { - if err := storage.DB.Model((*contract.Contract)(nil)). - Column("last_action"). - Where("account_id = ?", accountID). - Select(&stats.LastAction); err != nil { - return stats, err - } - } else { - if err := storage.DB.Model((*operation.Operation)(nil)). - Column("timestamp"). - Where("destination_id = ?", accountID). - Order("timestamp desc"). - Limit(1). - Select(&stats.LastAction); err != nil { - if !storage.IsRecordNotFound(err) { - return stats, err - } - } - - var sourceLastAction time.Time - if err := storage.DB.Model((*operation.Operation)(nil)). - Column("timestamp"). - Where("source_id = ?", accountID). - Order("timestamp desc"). - Limit(1). - Select(&sourceLastAction); err != nil { - if !storage.IsRecordNotFound(err) { - return stats, err - } - } - - if sourceLastAction.After(stats.LastAction) { - stats.LastAction = sourceLastAction - } - } - - count, err := storage.DB.Model((*operation.Operation)(nil)).WhereGroup( - func(q *orm.Query) (*orm.Query, error) { - return q.Where("destination_id = ?", accountID).WhereOr("source_id = ?", accountID), nil - }, - ).CountEstimate(100000) - if err != nil { - return - } - - stats.Count = int64(count) - + err = query.Scan(ctx) return } // Origination - -func (storage *Storage) Origination(accountID int64) (operation.Operation, error) { - var result operation.Operation - err := storage.DB.Model((*operation.Operation)(nil)). +func (storage *Storage) Origination(ctx context.Context, accountID int64) (result operation.Operation, err error) { + err = storage.DB.NewSelect(). + Model(&result). Where("destination_id = ?", accountID). - Where("kind = ?", types.OperationKindOrigination). + Where("kind = 2"). Limit(1). - Select(&result) + Scan(ctx) return result, err } -func addOperationSorting(query *orm.Query) { +func addOperationSorting(query *bun.SelectQuery) { query.OrderExpr("operation.level desc, operation.counter desc, operation.id asc") } diff --git a/internal/postgres/partition_manager.go b/internal/postgres/partition_manager.go deleted file mode 100644 index ebf6ef5d9..000000000 --- a/internal/postgres/partition_manager.go +++ /dev/null @@ -1,67 +0,0 @@ -package postgres - -import ( - "context" - "fmt" - "time" - - "github.com/baking-bad/bcdhub/internal/helpers" - "github.com/baking-bad/bcdhub/internal/models" - "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" - "github.com/baking-bad/bcdhub/internal/models/operation" - "github.com/baking-bad/bcdhub/internal/postgres/core" - "github.com/go-pg/pg/v10" -) - -// PartitionManager - -type PartitionManager struct { - conn *core.Postgres - - lastId string -} - -// NewPartitionManager - -func NewPartitionManager(conn *core.Postgres) *PartitionManager { - return &PartitionManager{ - conn: conn, - } -} - -const createPartitionTemplate = `CREATE TABLE IF NOT EXISTS ? PARTITION OF ? FOR VALUES FROM (?) TO (?);` - -func (pm *PartitionManager) partitionId(currentTime time.Time) string { - return fmt.Sprintf("%dQ%d", currentTime.Year(), helpers.QuarterOf(currentTime.Month())) -} - -// CreatePartitions - -func (pm *PartitionManager) CreatePartitions(ctx context.Context, currentTime time.Time) error { - id := pm.partitionId(currentTime) - if id == pm.lastId { - return nil - } - - start, end, err := helpers.QuarterBoundaries(currentTime) - if err != nil { - return err - } - - for _, model := range []models.Model{ - &operation.Operation{}, - &bigmapdiff.BigMapDiff{}, - } { - partitionName := fmt.Sprintf("%s_%s", model.GetIndex(), id) - if _, err := pm.conn.DB.ExecContext( - ctx, - createPartitionTemplate, - pg.Ident(partitionName), - pg.Ident(model.GetIndex()), - start.Format(time.RFC3339Nano), - end.Format(time.RFC3339Nano), - ); err != nil { - return err - } - } - - pm.lastId = id - return nil -} diff --git a/internal/postgres/protocol/storage.go b/internal/postgres/protocol/storage.go index fcebc0cdb..4180bbb04 100644 --- a/internal/postgres/protocol/storage.go +++ b/internal/postgres/protocol/storage.go @@ -1,7 +1,7 @@ package protocol import ( - "fmt" + "context" "github.com/baking-bad/bcdhub/internal/models/protocol" "github.com/baking-bad/bcdhub/internal/postgres/core" @@ -18,8 +18,8 @@ func NewStorage(pg *core.Postgres) *Storage { } // Get - returns current protocol for `level` (`hash` is optional, leave empty string for default) -func (storage *Storage) Get(hash string, level int64) (p protocol.Protocol, err error) { - query := storage.DB.Model(&p) +func (storage *Storage) Get(ctx context.Context, hash string, level int64) (p protocol.Protocol, err error) { + query := storage.DB.NewSelect().Model(&p) if level > -1 { query = query.Where("start_level <= ?", level) } @@ -27,25 +27,12 @@ func (storage *Storage) Get(hash string, level int64) (p protocol.Protocol, err query = query.Where("hash = ?", hash) } - err = query.Order("start_level DESC").First() - return -} - -// GetByNetworkWithSort - -func (storage *Storage) GetByNetworkWithSort(sortField, order string) (response []protocol.Protocol, err error) { - orderValue := fmt.Sprintf("%s %s", sortField, order) - err = storage.DB.Model((*protocol.Protocol)(nil)).Order(orderValue).Select(&response) - return -} - -// GetAll - returns all protocol`s entities -func (storage *Storage) GetAll() (response []protocol.Protocol, err error) { - err = storage.DB.Model((*protocol.Protocol)(nil)).Select(&response) + err = query.Order("start_level DESC").Limit(1).Scan(ctx) return } // GetByID - returns protocol by id -func (storage *Storage) GetByID(id int64) (response protocol.Protocol, err error) { - err = storage.DB.Model(&response).Where("id = ?", id).First() +func (storage *Storage) GetByID(ctx context.Context, id int64) (response protocol.Protocol, err error) { + err = storage.DB.NewSelect().Model(&response).Where("id = ?", id).Limit(1).Scan(ctx) return } diff --git a/internal/postgres/rollback.go b/internal/postgres/rollback.go new file mode 100644 index 000000000..43d437f42 --- /dev/null +++ b/internal/postgres/rollback.go @@ -0,0 +1,253 @@ +package postgres + +import ( + "context" + "database/sql" + "errors" + + "github.com/baking-bad/bcdhub/internal/models" + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/contract" + "github.com/baking-bad/bcdhub/internal/models/migration" + "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/protocol" + "github.com/baking-bad/bcdhub/internal/models/stats" + "github.com/baking-bad/bcdhub/internal/models/ticket" + "github.com/uptrace/bun" +) + +type Rollback struct { + tx bun.Tx +} + +func NewRollback(db *bun.DB) (Rollback, error) { + tx, err := db.Begin() + if err != nil { + return Rollback{}, err + } + return Rollback{tx}, nil +} + +func (r Rollback) Commit() error { + return r.tx.Commit() +} + +func (r Rollback) Rollback() error { + return r.tx.Rollback() +} + +func (r Rollback) DeleteAll(ctx context.Context, model any, level int64) (int, error) { + result, err := r.tx.NewDelete(). + Model(model). + Where("level = ?", level). + Exec(ctx) + if err != nil { + return 0, err + } + count, err := result.RowsAffected() + if err != nil { + return 0, err + } + return int(count), nil +} + +func (r Rollback) StatesChangedAtLevel(ctx context.Context, level int64) (states []bigmapdiff.BigMapState, err error) { + err = r.tx.NewSelect().Model(&states). + Where("last_update_level = ?", level). + Scan(ctx) + return +} + +func (r Rollback) DeleteBigMapState(ctx context.Context, state bigmapdiff.BigMapState) error { + _, err := r.tx.NewDelete().Model(&state).WherePK().Exec(ctx) + return err +} + +func (r Rollback) LastDiff(ctx context.Context, ptr int64, keyHash string, skipRemoved bool) (diff bigmapdiff.BigMapDiff, err error) { + query := r.tx.NewSelect().Model(&diff). + Where("key_hash = ?", keyHash). + Where("ptr = ?", ptr) + + if skipRemoved { + query.Where("value is not null") + } + + err = query.Order("id desc").Limit(1).Scan(ctx) + return +} + +func (r Rollback) SaveBigMapState(ctx context.Context, state bigmapdiff.BigMapState) error { + _, err := r.tx.NewUpdate(). + Column("last_update_level", "last_update_time", "removed", "value"). + Model(&state). + WherePK(). + Exec(ctx) + return err +} + +func (r Rollback) GetOperations(ctx context.Context, level int64) (ops []operation.Operation, err error) { + err = r.tx.NewSelect().Model(&ops). + Where("level = ?", level). + Scan(ctx) + return +} + +func (r Rollback) GetLastAction(ctx context.Context, addressIds ...int64) (actions []models.LastAction, err error) { + actions = make([]models.LastAction, 0) + for i := range addressIds { + var action models.LastAction + _, err = r.tx.NewRaw(`select max(foo.ts) as time, address from ( + (select "timestamp" as ts, source_id as address from operations where source_id = ?0 order by timestamp desc limit 1) + union all + (select "timestamp" as ts, destination_id as address from operations where destination_id = ?0 order by timestamp desc limit 1) + ) as foo + group by address`, addressIds[i]). + Exec(ctx, &action) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + err = nil + continue + } + return nil, err + } + actions = append(actions, action) + } + return +} + +func (r Rollback) UpdateAccountStats(ctx context.Context, account account.Account) error { + _, err := r.tx.NewUpdate().Model(&account). + Where("id = ?id"). + Set("operations_count = operations_count - ?operations_count"). + Set("migrations_count = migrations_count - ?migrations_count"). + Set("events_count = events_count - ?events_count"). + Set("ticket_updates_count = ticket_updates_count - ?ticket_updates_count"). + Set("last_action = ?last_action"). + Exec(ctx) + return err +} + +func (r Rollback) GlobalConstants(ctx context.Context, level int64) (constants []contract.GlobalConstant, err error) { + err = r.tx.NewSelect().Model(&constants). + Where("level = ?", level). + Scan(ctx) + return +} + +func (r Rollback) Scripts(ctx context.Context, level int64) (scripts []contract.Script, err error) { + err = r.tx.NewSelect().Model(&scripts). + Where("level = ?", level). + Scan(ctx) + return +} + +func (r Rollback) DeleteScriptsConstants(ctx context.Context, scriptIds []int64, constantsIds []int64) error { + if len(scriptIds) == 0 && len(constantsIds) == 0 { + return nil + } + + query := r.tx.NewDelete(). + Model((*contract.ScriptConstants)(nil)). + Where("script_id IN (?)", bun.In(scriptIds)). + WhereOr("global_constant_id IN (?)", bun.In(constantsIds)) + + _, err := query.Exec(ctx) + return err +} + +func (r Rollback) Protocols(ctx context.Context, level int64) error { + result, err := r.tx.NewDelete().Model((*protocol.Protocol)(nil)).Where("start_level >= ?", level).Exec(ctx) + if err != nil { + return err + } + count, err := result.RowsAffected() + if err != nil { + return err + } + if count == 0 { + return nil + } + + _, err = r.tx.NewUpdate(). + Model((*protocol.Protocol)(nil)). + Where("start_level < ?", level). + Set("end_level = 0"). + Exec(ctx) + return err +} + +func (r Rollback) UpdateStats(ctx context.Context, stats stats.Stats) error { + _, err := r.tx.NewUpdate(). + Model(&stats). + Where("id = ?id"). + Set("contracts_count = ?contracts_count"). + Set("operations_count = ?operations_count"). + Set("events_count = ?events_count"). + Set("tx_count = ?tx_count"). + Set("originations_count = ?originations_count"). + Set("sr_originations_count = ?sr_originations_count"). + Set("register_global_constants_count = ?register_global_constants_count"). + Set("sr_executes_count = ?sr_executes_count"). + Set("transfer_tickets_count = ?transfer_tickets_count"). + Set("global_constants_count = ?global_constants_count"). + Set("smart_rollups_count = ?smart_rollups_count"). + Exec(ctx) + return err +} + +func (r Rollback) GetMigrations(ctx context.Context, level int64) (migrations []migration.Migration, err error) { + err = r.tx.NewSelect().Model(&migrations). + ColumnExpr("account_id AS contract__account_id, migration.*"). + Where("migration.level = ?", level). + Join("LEFT JOIN contracts ON contracts.id = contract_id"). + Scan(ctx) + return +} + +func (r Rollback) GetTicketUpdates(ctx context.Context, level int64) (updates []ticket.TicketUpdate, err error) { + err = r.tx.NewSelect().Model(&updates). + Where("ticket_update.level = ?", level). + Relation("Ticket"). + Scan(ctx) + return +} + +func (r Rollback) UpdateTicket(ctx context.Context, ticket ticket.Ticket) error { + _, err := r.tx.NewUpdate(). + Model(&ticket). + Where("id = ?id"). + Set("updates_count = updates_count - ?updates_count"). + Exec(ctx) + return err +} + +func (r Rollback) TicketBalances(ctx context.Context, balances ...*ticket.Balance) error { + if len(balances) == 0 { + return nil + } + + _, err := r.tx.NewInsert().Model(&balances). + Column("ticket_id", "account_id", "amount"). + On("CONFLICT (ticket_id, account_id) DO UPDATE"). + Set("amount = balance.amount - EXCLUDED.amount"). + Exec(ctx) + return err +} + +func (r Rollback) DeleteTickets(ctx context.Context, level int64) (ids []int64, err error) { + _, err = r.tx.NewDelete(). + Model((*ticket.Ticket)(nil)). + Where("level = ?", level). + Returning("id"). + Exec(ctx, &ids) + return +} + +func (r Rollback) DeleteTicketBalances(ctx context.Context, ticketIds []int64) (err error) { + _, err = r.tx.NewDelete(). + Model((*ticket.Balance)(nil)). + Where("ticket_id IN (?)", bun.In(ticketIds)). + Exec(ctx) + return +} diff --git a/internal/postgres/smart_rollup/storage.go b/internal/postgres/smart_rollup/storage.go index 9b9292ac9..8355ce355 100644 --- a/internal/postgres/smart_rollup/storage.go +++ b/internal/postgres/smart_rollup/storage.go @@ -1,12 +1,13 @@ package smartrollup import ( + "context" "strings" "github.com/baking-bad/bcdhub/internal/models/account" smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" "github.com/baking-bad/bcdhub/internal/postgres/core" - "github.com/go-pg/pg/v10" + "github.com/uptrace/bun" ) // Storage - @@ -20,19 +21,28 @@ func NewStorage(pg *core.Postgres) *Storage { } // Get - -func (storage *Storage) Get(address string) (response smartrollup.SmartRollup, err error) { +func (storage *Storage) Get(ctx context.Context, address string) (response smartrollup.SmartRollup, err error) { var accountID int64 - if err = storage.DB.Model((*account.Account)(nil)).Column("id").Where("address = ?", address).Select(&accountID); err != nil { + if err = storage.DB.NewSelect(). + Model((*account.Account)(nil)). + Column("id"). + Where("address = ?", address). + Scan(ctx, &accountID); err != nil { return } - err = storage.DB.Model(&response).Where("address_id = ?", accountID).Relation("Address").Select() + err = storage.DB.NewSelect(). + Model(&response). + Where("address_id = ?", accountID). + Relation("Address"). + Scan(ctx) return } // List - -func (storage *Storage) List(limit, offset int64, sort string) (response []smartrollup.SmartRollup, err error) { - query := storage.DB.Model((*smartrollup.SmartRollup)(nil)). +func (storage *Storage) List(ctx context.Context, limit, offset int64, sort string) (response []smartrollup.SmartRollup, err error) { + query := storage.DB.NewSelect(). + Model(&response). Limit(storage.GetPageSize(limit)) if offset > 0 { @@ -42,8 +52,8 @@ func (storage *Storage) List(limit, offset int64, sort string) (response []smart if lowerSort != "asc" && lowerSort != "desc" { lowerSort = "desc" } - query.OrderExpr("id ?", pg.Safe(lowerSort)) + query.OrderExpr("id ?", bun.Safe(lowerSort)) - err = query.Relation("Address").Select(&response) + err = query.Relation("Address").Scan(ctx) return } diff --git a/internal/postgres/stats/storage.go b/internal/postgres/stats/storage.go new file mode 100644 index 000000000..6c460a417 --- /dev/null +++ b/internal/postgres/stats/storage.go @@ -0,0 +1,28 @@ +package stats + +import ( + "context" + + "github.com/baking-bad/bcdhub/internal/models/stats" + "github.com/baking-bad/bcdhub/internal/postgres/core" +) + +// Storage - +type Storage struct { + *core.Postgres +} + +// NewStorage - +func NewStorage(pg *core.Postgres) *Storage { + return &Storage{pg} +} + +// Get - +func (storage *Storage) Get(ctx context.Context) (stats stats.Stats, err error) { + err = storage.DB. + NewSelect(). + Model(&stats). + Limit(1). + Scan(ctx) + return +} diff --git a/internal/postgres/store.go b/internal/postgres/store.go deleted file mode 100644 index 970fe9ad1..000000000 --- a/internal/postgres/store.go +++ /dev/null @@ -1,377 +0,0 @@ -package postgres - -import ( - "context" - "time" - - "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" - "github.com/baking-bad/bcdhub/internal/models/contract" - "github.com/baking-bad/bcdhub/internal/models/migration" - "github.com/baking-bad/bcdhub/internal/models/operation" - smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" - "github.com/baking-bad/bcdhub/internal/models/types" - - "github.com/go-pg/pg/v10" -) - -// Store - -type Store struct { - BigMapState []*bigmapdiff.BigMapState - Contracts []*contract.Contract - Migrations []*migration.Migration - Operations []*operation.Operation - GlobalConstants []*contract.GlobalConstant - SmartRollups []*smartrollup.SmartRollup - - partitions *PartitionManager - tx pg.DBI -} - -// NewStore - -func NewStore(tx pg.DBI, pm *PartitionManager) *Store { - return &Store{ - BigMapState: make([]*bigmapdiff.BigMapState, 0), - Contracts: make([]*contract.Contract, 0), - Migrations: make([]*migration.Migration, 0), - Operations: make([]*operation.Operation, 0), - GlobalConstants: make([]*contract.GlobalConstant, 0), - SmartRollups: make([]*smartrollup.SmartRollup, 0), - - partitions: pm, - tx: tx, - } -} - -// AddBigMapStates - -func (store *Store) AddBigMapStates(states ...*bigmapdiff.BigMapState) { - store.BigMapState = append(store.BigMapState, states...) -} - -// AddContracts - -func (store *Store) AddContracts(contracts ...*contract.Contract) { - store.Contracts = append(store.Contracts, contracts...) -} - -// AddMigrations - -func (store *Store) AddMigrations(migrations ...*migration.Migration) { - store.Migrations = append(store.Migrations, migrations...) -} - -// AddOperations - -func (store *Store) AddOperations(operations ...*operation.Operation) { - store.Operations = append(store.Operations, operations...) -} - -// AddGlobalConstants - -func (store *Store) AddGlobalConstants(constants ...*contract.GlobalConstant) { - store.GlobalConstants = append(store.GlobalConstants, constants...) -} - -// AddSmartRollups - -func (store *Store) AddSmartRollups(rollups ...*smartrollup.SmartRollup) { - store.SmartRollups = append(store.SmartRollups, rollups...) -} - -// ListContracts - -func (store *Store) ListContracts() []*contract.Contract { - return store.Contracts -} - -// ListOperations - -func (store *Store) ListOperations() []*operation.Operation { - return store.Operations -} - -// Save - -func (store *Store) Save(ctx context.Context) error { - if err := store.saveOperations(ctx, store.tx); err != nil { - return err - } - - if err := store.saveContracts(store.tx); err != nil { - return err - } - - if err := store.saveMigrations(store.tx); err != nil { - return err - } - - for i := range store.BigMapState { - if err := store.BigMapState[i].Save(store.tx); err != nil { - return err - } - } - - if len(store.GlobalConstants) > 0 { - if _, err := store.tx.Model(&store.GlobalConstants).Returning("id").Insert(); err != nil { - return err - } - } - - if err := store.saveSmartRollups(store.tx); err != nil { - return err - } - - return nil -} - -func (store *Store) saveMigrations(tx pg.DBI) error { - if len(store.Migrations) == 0 { - return nil - } - - for i := range store.Migrations { - if store.Migrations[i].ContractID == 0 { - store.Migrations[i].ContractID = store.Migrations[i].Contract.ID - } - } - - _, err := tx.Model(&store.Migrations).Returning("id").Insert() - return err -} - -func (store *Store) saveSmartRollups(tx pg.DBI) error { - if len(store.SmartRollups) == 0 { - return nil - } - - for i := range store.SmartRollups { - if !store.SmartRollups[i].Address.IsEmpty() { - if err := store.SmartRollups[i].Address.Save(tx); err != nil { - return err - } - store.SmartRollups[i].AddressId = store.SmartRollups[i].Address.ID - } - } - - _, err := tx.Model(&store.SmartRollups).Returning("id").Insert() - return err -} - -func (store *Store) saveOperations(ctx context.Context, tx pg.DBI) error { - if len(store.Operations) == 0 { - return nil - } - - for i := range store.Operations { - if !store.Operations[i].Source.IsEmpty() { - if err := store.Operations[i].Source.Save(tx); err != nil { - return err - } - store.Operations[i].SourceID = store.Operations[i].Source.ID - } - if !store.Operations[i].Destination.IsEmpty() { - if err := store.Operations[i].Destination.Save(tx); err != nil { - return err - } - store.Operations[i].DestinationID = store.Operations[i].Destination.ID - } - if !store.Operations[i].Initiator.IsEmpty() { - if err := store.Operations[i].Initiator.Save(tx); err != nil { - return err - } - store.Operations[i].InitiatorID = store.Operations[i].Initiator.ID - } - if !store.Operations[i].Delegate.IsEmpty() { - if err := store.Operations[i].Delegate.Save(tx); err != nil { - return err - } - store.Operations[i].DelegateID = store.Operations[i].Delegate.ID - } - } - - if err := store.partitions.CreatePartitions(ctx, store.Operations[0].Timestamp); err != nil { - return err - } - - if _, err := tx.Model(&store.Operations).Returning("id").Insert(); err != nil { - return err - } - - for i := range store.Operations { - for j := range store.Operations[i].BigMapDiffs { - store.Operations[i].BigMapDiffs[j].OperationID = store.Operations[i].ID - } - for j := range store.Operations[i].BigMapActions { - store.Operations[i].BigMapActions[j].OperationID = store.Operations[i].ID - } - for j := range store.Operations[i].TickerUpdates { - if !store.Operations[i].TickerUpdates[j].Account.IsEmpty() { - if err := store.Operations[i].TickerUpdates[j].Account.Save(tx); err != nil { - return err - } - store.Operations[i].TickerUpdates[j].AccountID = store.Operations[i].TickerUpdates[j].Account.ID - } - if !store.Operations[i].TickerUpdates[j].Ticketer.IsEmpty() { - if err := store.Operations[i].TickerUpdates[j].Ticketer.Save(tx); err != nil { - return err - } - store.Operations[i].TickerUpdates[j].TicketerID = store.Operations[i].TickerUpdates[j].Ticketer.ID - } - store.Operations[i].TickerUpdates[j].OperationID = store.Operations[i].ID - } - - if len(store.Operations[i].BigMapDiffs) > 0 { - if _, err := tx.Model(&store.Operations[i].BigMapDiffs).Returning("id").Insert(); err != nil { - return err - } - } - - if len(store.Operations[i].BigMapActions) > 0 { - if _, err := tx.Model(&store.Operations[i].BigMapActions).Returning("id").Insert(); err != nil { - return err - } - } - - if len(store.Operations[i].TickerUpdates) > 0 { - if _, err := tx.Model(&store.Operations[i].TickerUpdates).Returning("id").Insert(); err != nil { - return err - } - } - } - return store.updateContracts(tx) -} - -func (store *Store) saveContracts(tx pg.DBI) error { - if len(store.Contracts) == 0 { - return nil - } - - for i := range store.Contracts { - if store.Contracts[i].Alpha.Code != nil { - if err := store.Contracts[i].Alpha.Save(tx); err != nil { - return err - } - store.Contracts[i].AlphaID = store.Contracts[i].Alpha.ID - } - if store.Contracts[i].Babylon.Code != nil { - if store.Contracts[i].Alpha.Hash != store.Contracts[i].Babylon.Hash { - if err := store.Contracts[i].Babylon.Save(tx); err != nil { - return err - } - store.Contracts[i].BabylonID = store.Contracts[i].Babylon.ID - - if len(store.Contracts[i].Babylon.Constants) > 0 { - for j := range store.Contracts[i].Babylon.Constants { - relation := contract.ScriptConstants{ - ScriptId: store.Contracts[i].BabylonID, - GlobalConstantId: store.Contracts[i].Babylon.Constants[j].ID, - } - if _, err := tx.Model(&relation).Insert(); err != nil { - return err - } - } - } - - } else { - store.Contracts[i].BabylonID = store.Contracts[i].Alpha.ID - } - } - if store.Contracts[i].Jakarta.Code != nil { - if store.Contracts[i].Babylon.Hash != store.Contracts[i].Jakarta.Hash { - if err := store.Contracts[i].Jakarta.Save(tx); err != nil { - return err - } - store.Contracts[i].JakartaID = store.Contracts[i].Jakarta.ID - - if len(store.Contracts[i].Jakarta.Constants) > 0 { - for j := range store.Contracts[i].Jakarta.Constants { - relation := contract.ScriptConstants{ - ScriptId: store.Contracts[i].JakartaID, - GlobalConstantId: store.Contracts[i].Jakarta.Constants[j].ID, - } - if _, err := tx.Model(&relation).Insert(); err != nil { - return err - } - } - } - - } else { - store.Contracts[i].JakartaID = store.Contracts[i].Babylon.ID - } - } - - if err := store.Contracts[i].Account.Save(tx); err != nil { - return err - } - store.Contracts[i].AccountID = store.Contracts[i].Account.ID - - if !store.Contracts[i].Manager.IsEmpty() { - if err := store.Contracts[i].Manager.Save(tx); err != nil { - return err - } - store.Contracts[i].ManagerID = store.Contracts[i].Manager.ID - } - - if !store.Contracts[i].Delegate.IsEmpty() { - if err := store.Contracts[i].Delegate.Save(tx); err != nil { - return err - } - store.Contracts[i].DelegateID = store.Contracts[i].Delegate.ID - } - } - - if _, err := tx.Model(&store.Contracts).Returning("id").Insert(); err != nil { - return err - } - - return store.updateContracts(tx) -} - -type contractUpdates struct { - //nolint - tableName struct{} `pg:"contracts"` - - AccountID int64 - LastAction time.Time - TxCount uint64 -} - -func (store *Store) updateContracts(tx pg.DBI) error { - if len(store.Operations) == 0 { - return nil - } - count := make(map[int64]uint64) - for i := range store.Operations { - destination := store.Operations[i].Destination - if destination.Type != types.AccountTypeContract { - continue - } - - if value, ok := count[destination.ID]; ok { - count[destination.ID] = value + 1 - } else { - count[destination.ID] = 1 - } - - source := store.Operations[i].Source - if source.Type != types.AccountTypeContract { - continue - } - - if value, ok := count[source.ID]; ok { - count[source.ID] = value + 1 - } else { - count[source.ID] = 1 - } - } - - if len(count) == 0 { - return nil - } - - contracts := make([]*contractUpdates, 0, len(count)) - for accountID, txCount := range count { - contracts = append(contracts, &contractUpdates{ - LastAction: store.Operations[0].Timestamp, - AccountID: accountID, - TxCount: txCount, - }) - } - - _, err := tx.Model(&contracts). - Set("last_action = ?last_action, tx_count = contract_updates.tx_count + ?tx_count"). - Where("contract_updates.account_id = ?account_id"). - Update() - return err -} diff --git a/internal/postgres/store/operations.go b/internal/postgres/store/operations.go new file mode 100644 index 000000000..bd1e02ef1 --- /dev/null +++ b/internal/postgres/store/operations.go @@ -0,0 +1,29 @@ +package store + +import ( + "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/types" +) + +// AddOperations - +func (store *Store) AddOperations(operations ...*operation.Operation) { + store.Operations = append(store.Operations, operations...) + + store.Stats.OperationsCount += len(operations) + for i := range operations { + switch operations[i].Kind { + case types.OperationKindEvent: + store.Stats.EventsCount += 1 + case types.OperationKindOrigination, types.OperationKindOriginationNew: + store.Stats.OriginationsCount += 1 + case types.OperationKindSrOrigination: + store.Stats.SrOriginationsCount += 1 + case types.OperationKindTransaction: + store.Stats.TransactionsCount += 1 + case types.OperationKindRegisterGlobalConstant: + store.Stats.RegisterGlobalConstantCount += 1 + case types.OperationKindSrExecuteOutboxMessage: + store.Stats.SrExecutesCount += 1 + } + } +} diff --git a/internal/postgres/store/save.go b/internal/postgres/store/save.go new file mode 100644 index 000000000..22a5a3aa7 --- /dev/null +++ b/internal/postgres/store/save.go @@ -0,0 +1,381 @@ +package store + +import ( + "context" + + "github.com/baking-bad/bcdhub/internal/models" + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/baking-bad/bcdhub/internal/models/bigmapaction" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/contract" + "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/ticket" + "github.com/baking-bad/bcdhub/internal/postgres/core" + "github.com/pkg/errors" +) + +// Save - +func (store *Store) Save(ctx context.Context) error { + stats, err := store.stats.Get(ctx) + if err != nil { + return err + } + store.Stats.ID = stats.ID + + tx, err := core.NewTransaction(ctx, store.db) + if err != nil { + return err + } + + if err := tx.Block(ctx, store.Block); err != nil { + return errors.Wrap(err, "saving block") + } + + if err := store.saveAccounts(ctx, tx); err != nil { + return errors.Wrap(err, "saving accounts") + } + + if err := store.saveTickets(ctx, tx); err != nil { + return errors.Wrap(err, "saving tickets") + } + + if err := store.saveTicketBalances(ctx, tx); err != nil { + return errors.Wrap(err, "saving ticket balances") + } + + if err := store.saveOperations(ctx, tx); err != nil { + return errors.Wrap(err, "saving operations") + } + + if err := store.saveContracts(ctx, tx); err != nil { + return errors.Wrap(err, "saving contracts") + } + + if err := store.saveMigrations(ctx, tx); err != nil { + return errors.Wrap(err, "saving migrations") + } + + if err := tx.BigMapStates(ctx, store.bigMapStates()...); err != nil { + return errors.Wrap(err, "saving bigmap states") + } + + if err := tx.GlobalConstants(ctx, store.GlobalConstants...); err != nil { + return errors.Wrap(err, "saving bigmap states") + } + + if err := store.saveSmartRollups(ctx, tx); err != nil { + return errors.Wrap(err, "saving smart rollups") + } + + if err := tx.UpdateStats(ctx, store.Stats); err != nil { + return errors.Wrap(err, "saving stats") + } + + return tx.Commit() +} + +func (store *Store) saveAccounts(ctx context.Context, tx models.Transaction) error { + if len(store.Accounts) == 0 { + return nil + } + + arr := make([]*account.Account, 0, len(store.Accounts)) + for _, acc := range store.Accounts { + if acc.IsEmpty() { + continue + } + arr = append(arr, acc) + } + + if err := tx.Accounts(ctx, arr...); err != nil { + return err + } + + for i := range arr { + store.accIds[arr[i].Address] = arr[i].ID + } + + return nil +} + +func (store *Store) saveTickets(ctx context.Context, tx models.Transaction) error { + if len(store.Tickets) == 0 { + return nil + } + + arr := make([]*ticket.Ticket, 0, len(store.Tickets)) + for _, t := range store.Tickets { + if id, ok := store.getAccountId(t.Ticketer); ok { + t.TicketerID = id + } else { + return errors.Errorf("unknown ticketer account: %s", t.Ticketer.Address) + } + arr = append(arr, t) + } + + if err := tx.Tickets(ctx, arr...); err != nil { + return err + } + + for i := range arr { + store.ticketIds[arr[i].Hash()] = arr[i].ID + } + + return nil +} + +func (store *Store) saveTicketBalances(ctx context.Context, tx models.Transaction) error { + if len(store.TicketBalances) == 0 { + return nil + } + + balances := make([]*ticket.Balance, 0, len(store.TicketBalances)) + for _, balance := range store.TicketBalances { + if id, ok := store.getAccountId(balance.Account); ok { + balance.AccountId = id + } else { + return errors.Errorf("unknown ticket balance account: %s", balance.Account.Address) + } + if id, ok := store.getAccountId(balance.Ticket.Ticketer); ok { + balance.Ticket.TicketerID = id + } else { + return errors.Errorf("unknown ticket balance ticketer: %s", balance.Ticket.Ticketer.Address) + } + + if id, ok := store.ticketIds[balance.Ticket.Hash()]; ok { + balance.TicketId = id + } else { + return errors.Errorf("unknown ticket of balance: %s", balance.Ticket.Ticketer.Address) + } + balances = append(balances, balance) + } + + return tx.TicketBalances(ctx, balances...) +} + +func (store *Store) saveMigrations(ctx context.Context, tx models.Transaction) error { + if len(store.Migrations) == 0 { + return nil + } + + for i := range store.Migrations { + if store.Migrations[i].ContractID == 0 { + store.Migrations[i].ContractID = store.Migrations[i].Contract.ID + } + } + + return tx.Migrations(ctx, store.Migrations...) +} + +func (store *Store) saveSmartRollups(ctx context.Context, tx models.Transaction) error { + if len(store.SmartRollups) == 0 { + return nil + } + + for i, rollup := range store.SmartRollups { + if id, ok := store.getAccountId(rollup.Address); ok { + store.SmartRollups[i].AddressId = id + } else { + return errors.Errorf("unknown smart rollup account: %s", rollup.Address.Address) + } + } + + return tx.SmartRollups(ctx, store.SmartRollups...) +} + +func (store *Store) saveOperations(ctx context.Context, tx models.Transaction) error { + if len(store.Operations) == 0 { + return nil + } + + for i := range store.Operations { + if err := store.setOperationAccountsId(store.Operations[i]); err != nil { + return err + } + } + + if err := tx.Operations(ctx, store.Operations...); err != nil { + return errors.Wrap(err, "saving operations") + } + + var ( + bigMapDiffs = make([]*bigmapdiff.BigMapDiff, 0) + bigMapActions = make([]*bigmapaction.BigMapAction, 0) + ticketUpdates = make([]*ticket.TicketUpdate, 0) + ) + + for _, operation := range store.Operations { + for j := range operation.BigMapDiffs { + operation.BigMapDiffs[j].OperationID = operation.ID + } + bigMapDiffs = append(bigMapDiffs, operation.BigMapDiffs...) + + for j := range operation.BigMapActions { + operation.BigMapActions[j].OperationID = operation.ID + } + bigMapActions = append(bigMapActions, operation.BigMapActions...) + + for j, update := range operation.TicketUpdates { + if id, ok := store.getAccountId(update.Account); ok { + operation.TicketUpdates[j].AccountId = id + } else { + return errors.Errorf("unknown ticket update account: %s", update.Account.Address) + } + + if id, ok := store.getAccountId(update.Ticket.Ticketer); ok { + operation.TicketUpdates[j].Ticket.TicketerID = id + } else { + return errors.Errorf("unknown ticket update ticketer account: %s", update.Ticket.Ticketer.Address) + } + + operation.TicketUpdates[j].OperationId = operation.ID + + hash := operation.TicketUpdates[j].Ticket.Hash() + if id, ok := store.ticketIds[hash]; ok { + operation.TicketUpdates[j].TicketId = id + } else { + return errors.Errorf("unknown ticket: ticketer_id=%d content_type=%s content=%s", + operation.TicketUpdates[j].Ticket.TicketerID, + operation.TicketUpdates[j].Ticket.ContentType, + operation.TicketUpdates[j].Ticket.Content, + ) + } + } + + ticketUpdates = append(ticketUpdates, operation.TicketUpdates...) + } + + if err := tx.BigMapDiffs(ctx, bigMapDiffs...); err != nil { + return errors.Wrap(err, "saving bigmap diffs") + } + if err := tx.BigMapActions(ctx, bigMapActions...); err != nil { + return errors.Wrap(err, "saving bigmap actions") + } + if err := tx.TickerUpdates(ctx, ticketUpdates...); err != nil { + return errors.Wrap(err, "saving ticket updates") + } + return nil +} + +func (store *Store) setOperationAccountsId(operation *operation.Operation) error { + if id, ok := store.getAccountId(operation.Source); ok { + operation.SourceID = id + } else { + return errors.Errorf("unknown source account: %s", operation.Source.Address) + } + + if !(operation.IsOrigination() && !operation.IsApplied()) { + if id, ok := store.getAccountId(operation.Destination); ok { + operation.DestinationID = id + } else { + return errors.Errorf("unknown destination account: %s", operation.Destination.Address) + } + } + + if id, ok := store.getAccountId(operation.Initiator); ok { + operation.InitiatorID = id + } else { + return errors.Errorf("unknown initiator account: %s", operation.Initiator.Address) + } + + if id, ok := store.getAccountId(operation.Delegate); ok { + operation.DelegateID = id + } else { + return errors.Errorf("unknown delegate account: %s", operation.Delegate.Address) + } + + return nil +} + +func (store *Store) getAccountId(acc account.Account) (int64, bool) { + if acc.IsEmpty() { + return 0, true + } + id, ok := store.accIds[acc.Address] + return id, ok +} + +func (store *Store) saveContracts(ctx context.Context, tx models.Transaction) error { + if len(store.Contracts) == 0 { + return nil + } + + for i := range store.Contracts { + if store.Contracts[i].Alpha.Code != nil { + if err := tx.Scripts(ctx, &store.Contracts[i].Alpha); err != nil { + return err + } + store.Contracts[i].AlphaID = store.Contracts[i].Alpha.ID + } + if store.Contracts[i].Babylon.Code != nil { + if store.Contracts[i].Alpha.Hash != store.Contracts[i].Babylon.Hash { + if err := tx.Scripts(ctx, &store.Contracts[i].Babylon); err != nil { + return err + } + store.Contracts[i].BabylonID = store.Contracts[i].Babylon.ID + + if len(store.Contracts[i].Babylon.Constants) > 0 { + for j := range store.Contracts[i].Babylon.Constants { + relation := contract.ScriptConstants{ + ScriptId: store.Contracts[i].BabylonID, + GlobalConstantId: store.Contracts[i].Babylon.Constants[j].ID, + } + if err := tx.ScriptConstant(ctx, &relation); err != nil { + return err + } + } + } + + } else { + store.Contracts[i].BabylonID = store.Contracts[i].Alpha.ID + } + } + if store.Contracts[i].Jakarta.Code != nil { + if store.Contracts[i].Babylon.Hash != store.Contracts[i].Jakarta.Hash { + if err := tx.Scripts(ctx, &store.Contracts[i].Jakarta); err != nil { + return err + } + store.Contracts[i].JakartaID = store.Contracts[i].Jakarta.ID + + if len(store.Contracts[i].Jakarta.Constants) > 0 { + for j := range store.Contracts[i].Jakarta.Constants { + relation := contract.ScriptConstants{ + ScriptId: store.Contracts[i].JakartaID, + GlobalConstantId: store.Contracts[i].Jakarta.Constants[j].ID, + } + if err := tx.ScriptConstant(ctx, &relation); err != nil { + return err + } + } + } + + } else { + store.Contracts[i].JakartaID = store.Contracts[i].Babylon.ID + } + } + + if id, ok := store.getAccountId(store.Contracts[i].Account); ok { + store.Contracts[i].AccountID = id + } else { + return errors.Errorf("unknown contract account: %s", store.Contracts[i].Account.Address) + } + + if id, ok := store.getAccountId(store.Contracts[i].Manager); ok { + store.Contracts[i].ManagerID = id + } else { + return errors.Errorf("unknown manager account: %s", store.Contracts[i].Manager.Address) + } + + if id, ok := store.getAccountId(store.Contracts[i].Delegate); ok { + store.Contracts[i].DelegateID = id + } else { + return errors.Errorf("unknown delegate account: %s", store.Contracts[i].Delegate.Address) + } + } + + if err := tx.Contracts(ctx, store.Contracts...); err != nil { + return err + } + + return nil +} diff --git a/internal/postgres/store/store.go b/internal/postgres/store/store.go new file mode 100644 index 000000000..6a2918b78 --- /dev/null +++ b/internal/postgres/store/store.go @@ -0,0 +1,166 @@ +package store + +import ( + "fmt" + + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/block" + "github.com/baking-bad/bcdhub/internal/models/contract" + "github.com/baking-bad/bcdhub/internal/models/migration" + "github.com/baking-bad/bcdhub/internal/models/operation" + smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" + "github.com/baking-bad/bcdhub/internal/models/stats" + "github.com/baking-bad/bcdhub/internal/models/ticket" + "github.com/uptrace/bun" +) + +// Store - +type Store struct { + Block *block.Block + BigMapState map[string]*bigmapdiff.BigMapState + Contracts []*contract.Contract + Migrations []*migration.Migration + Operations []*operation.Operation + GlobalConstants []*contract.GlobalConstant + SmartRollups []*smartrollup.SmartRollup + Tickets map[string]*ticket.Ticket + TicketBalances map[string]*ticket.Balance + Accounts map[string]*account.Account + Stats stats.Stats + + stats stats.Repository + db *bun.DB + accIds map[string]int64 + ticketIds map[string]int64 +} + +// NewStore - +func NewStore(db *bun.DB, statsRepo stats.Repository) *Store { + return &Store{ + BigMapState: make(map[string]*bigmapdiff.BigMapState), + Contracts: make([]*contract.Contract, 0), + Migrations: make([]*migration.Migration, 0), + Operations: make([]*operation.Operation, 0), + GlobalConstants: make([]*contract.GlobalConstant, 0), + SmartRollups: make([]*smartrollup.SmartRollup, 0), + Tickets: make(map[string]*ticket.Ticket), + TicketBalances: make(map[string]*ticket.Balance), + Accounts: make(map[string]*account.Account), + Stats: stats.Stats{}, + stats: statsRepo, + db: db, + accIds: make(map[string]int64), + ticketIds: make(map[string]int64), + } +} + +func (store *Store) SetBlock(block *block.Block) { + store.Block = block +} + +// AddBigMapStates - +func (store *Store) AddBigMapStates(states ...*bigmapdiff.BigMapState) { + for i := range states { + key := states[i].String() + if state, ok := store.BigMapState[key]; ok { + state.Count += 1 + state.Value = states[i].Value + state.Removed = states[i].Removed + } else { + store.BigMapState[key] = states[i] + } + } +} + +func (store *Store) bigMapStates() []*bigmapdiff.BigMapState { + arr := make([]*bigmapdiff.BigMapState, 0, len(store.BigMapState)) + for _, state := range store.BigMapState { + arr = append(arr, state) + } + return arr +} + +// AddContracts - +func (store *Store) AddContracts(contracts ...*contract.Contract) { + store.Contracts = append(store.Contracts, contracts...) + + store.Stats.ContractsCount += len(contracts) +} + +// AddMigrations - +func (store *Store) AddMigrations(migrations ...*migration.Migration) { + store.Migrations = append(store.Migrations, migrations...) + + for i := range migrations { + if migrations[i].Contract.Account.IsEmpty() { + continue + } + + if account, ok := store.Accounts[migrations[i].Contract.Account.Address]; !ok { + store.Accounts[migrations[i].Contract.Account.Address] = &migrations[i].Contract.Account + } else { + account.MigrationsCount += 1 + } + } +} + +// AddGlobalConstants - +func (store *Store) AddGlobalConstants(constants ...*contract.GlobalConstant) { + store.GlobalConstants = append(store.GlobalConstants, constants...) + store.Stats.GlobalConstantsCount += len(constants) +} + +// AddSmartRollups - +func (store *Store) AddSmartRollups(rollups ...*smartrollup.SmartRollup) { + store.SmartRollups = append(store.SmartRollups, rollups...) + store.Stats.SmartRollupsCount += len(rollups) +} + +// AddAccounts - +func (store *Store) AddAccounts(accounts ...account.Account) { + for i := range accounts { + if account, ok := store.Accounts[accounts[i].Address]; !ok { + store.Accounts[accounts[i].Address] = &accounts[i] + } else { + account.OperationsCount += accounts[i].OperationsCount + account.EventsCount += accounts[i].EventsCount + account.MigrationsCount += accounts[i].MigrationsCount + account.TicketUpdatesCount += accounts[i].TicketUpdatesCount + } + } +} + +// AddTickets - +func (store *Store) AddTickets(tickets ...ticket.Ticket) { + for i := range tickets { + hash := tickets[i].Hash() + if t, ok := store.Tickets[hash]; !ok { + store.Tickets[hash] = &tickets[i] + } else { + t.UpdatesCount += tickets[i].UpdatesCount + } + } +} + +// AddTicketBalances - +func (store *Store) AddTicketBalances(balance ...ticket.Balance) { + for i := range balance { + key := fmt.Sprintf("%s_%s", balance[i].Ticket.Hash(), balance[i].Account.Address) + if t, ok := store.TicketBalances[key]; !ok { + store.TicketBalances[key] = &balance[i] + } else { + t.Amount = t.Amount.Add(balance[i].Amount) + } + } +} + +// ListContracts - +func (store *Store) ListContracts() []*contract.Contract { + return store.Contracts +} + +// ListOperations - +func (store *Store) ListOperations() []*operation.Operation { + return store.Operations +} diff --git a/internal/postgres/tests/accounts_test.go b/internal/postgres/tests/accounts_test.go new file mode 100644 index 000000000..69da9f140 --- /dev/null +++ b/internal/postgres/tests/accounts_test.go @@ -0,0 +1,27 @@ +package tests + +import ( + "context" + "time" +) + +func (s *StorageTestSuite) TestAccountsGet() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + account, err := s.accounts.Get(ctx, "KT1CMJQmuwwJopNnLhSDHXT3zQVUrNPLA8br") + s.Require().NoError(err) + + s.Require().EqualValues(45, account.ID) + s.Require().EqualValues(1, account.Type) + s.Require().EqualValues("KT1CMJQmuwwJopNnLhSDHXT3zQVUrNPLA8br", account.Address) +} + +func (s *StorageTestSuite) TestRecentlyCalledContracts() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + data, err := s.accounts.RecentlyCalledContracts(ctx, 0, 3) + s.Require().NoError(err) + s.Require().Len(data, 3) +} diff --git a/internal/postgres/tests/big_map_actions_test.go b/internal/postgres/tests/big_map_actions_test.go new file mode 100644 index 000000000..9a15b89b2 --- /dev/null +++ b/internal/postgres/tests/big_map_actions_test.go @@ -0,0 +1,25 @@ +package tests + +import ( + "context" + "time" +) + +func (s *StorageTestSuite) TestBigMpActionsGet() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + actions, err := s.bigMapActions.Get(ctx, 4, 10, 0) + s.Require().NoError(err) + s.Require().Len(actions, 1) + + action := actions[0] + s.Require().EqualValues(1, action.ID) + s.Require().EqualValues(1, action.Action) + s.Require().EqualValues(34, action.OperationID) + s.Require().EqualValues(33, action.Level) + s.Require().NotNil(action.SourcePtr) + s.Require().EqualValues(4, *action.SourcePtr) + s.Require().Nil(action.DestinationPtr) + s.Require().EqualValues("KT1W3fGSo8XfRSESPAg3Jngzt3D8xpPqW64i", action.Address) +} diff --git a/internal/postgres/tests/big_map_diffs_test.go b/internal/postgres/tests/big_map_diffs_test.go new file mode 100644 index 000000000..4c11d28c9 --- /dev/null +++ b/internal/postgres/tests/big_map_diffs_test.go @@ -0,0 +1,140 @@ +package tests + +import ( + "context" + "time" + + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/testsuite" +) + +func (s *StorageTestSuite) TestBigMapDiffsCurrent() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + diff, err := s.bigMapDiffs.Current(ctx, "expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo", 4) + s.Require().NoError(err) + + s.Require().EqualValues(1, diff.ID) + s.Require().EqualValues(4, diff.Ptr) + s.Require().EqualValues(0, diff.Count) + s.Require().EqualValues(33, diff.LastUpdateLevel) + s.Require().EqualValues("KT1W3fGSo8XfRSESPAg3Jngzt3D8xpPqW64i", diff.Contract) + s.Require().False(diff.Removed) + s.Require().Equal(testsuite.MustHexDecode("7b22737472696e67223a22227d"), []byte(diff.Key)) +} + +func (s *StorageTestSuite) TestBigMapDiffsGetForAddress() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + diffs, err := s.bigMapDiffs.GetForAddress(ctx, "KT1W3fGSo8XfRSESPAg3Jngzt3D8xpPqW64i") + s.Require().NoError(err) + s.Require().Len(diffs, 1) + + diff := diffs[0] + s.Require().EqualValues(1, diff.ID) + s.Require().EqualValues(4, diff.Ptr) + s.Require().EqualValues(0, diff.Count) + s.Require().EqualValues(33, diff.LastUpdateLevel) + s.Require().EqualValues("KT1W3fGSo8XfRSESPAg3Jngzt3D8xpPqW64i", diff.Contract) + s.Require().False(diff.Removed) + s.Require().Equal(testsuite.MustHexDecode("7b22737472696e67223a22227d"), []byte(diff.Key)) +} + +func (s *StorageTestSuite) TestBigMapDiffsCount() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + count, err := s.bigMapDiffs.Count(ctx, 4) + s.Require().NoError(err) + s.Require().EqualValues(1, count) +} + +func (s *StorageTestSuite) TestBigMapDiffsPrevious() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + previous, err := s.bigMapDiffs.Previous(ctx, []bigmapdiff.BigMapDiff{ + { + ID: 55, + Ptr: 41, + KeyHash: "exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX", + Contract: "KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1", + }, + }) + s.Require().NoError(err) + s.Require().Len(previous, 1) + + diff := previous[0] + s.Require().EqualValues(54, diff.ID) + s.Require().EqualValues(41, diff.Ptr) + s.Require().EqualValues(40, diff.Level) + s.Require().EqualValues(3, diff.ProtocolID) + s.Require().EqualValues(109, diff.OperationID) + s.Require().EqualValues("KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1", diff.Contract) + s.Require().Equal("exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX", diff.KeyHash) + s.Require().Equal([]byte(`{"prim":"Pair","args":[[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"}],{"int":"50"}]}`), []byte(diff.Value)) +} + +func (s *StorageTestSuite) TestBigMapDiffsGetForOperation() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + diffs, err := s.bigMapDiffs.GetForOperation(ctx, 109) + s.Require().NoError(err) + s.Require().Len(diffs, 4) +} + +func (s *StorageTestSuite) TestBigMapDiffsGetByPtrAndKeyHash() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + diffs, count, err := s.bigMapDiffs.GetByPtrAndKeyHash(ctx, 41, "exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX", 10, 0) + s.Require().NoError(err) + s.Require().Len(diffs, 1) + s.Require().EqualValues(1, count) +} + +func (s *StorageTestSuite) TestBigMapDiffsGetByPtr() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + states, err := s.bigMapDiffs.GetByPtr(ctx, "KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1", 41) + s.Require().NoError(err) + s.Require().Len(states, 2) +} + +func (s *StorageTestSuite) TestBigMapDiffsGet() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + diffs, err := s.bigMapDiffs.Get(ctx, bigmapdiff.GetContext{ + Ptr: testsuite.Ptr[int64](41), + Size: 10, + }) + s.Require().NoError(err) + s.Require().Len(diffs, 2) +} + +func (s *StorageTestSuite) TestBigMapDiffsGetStats() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + stats, err := s.bigMapDiffs.GetStats(ctx, 41) + s.Require().NoError(err) + s.Require().EqualValues(2, stats.Total) + s.Require().EqualValues(2, stats.Active) + s.Require().EqualValues("KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1", stats.Contract) +} + +func (s *StorageTestSuite) TestBigMapDiffsKeys() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + states, err := s.bigMapDiffs.Keys(ctx, bigmapdiff.GetContext{ + Ptr: testsuite.Ptr[int64](41), + }) + s.Require().NoError(err) + s.Require().Len(states, 2) +} diff --git a/internal/postgres/tests/blocks_test.go b/internal/postgres/tests/blocks_test.go new file mode 100644 index 000000000..be53db7a2 --- /dev/null +++ b/internal/postgres/tests/blocks_test.go @@ -0,0 +1,36 @@ +package tests + +import ( + "context" + "time" +) + +func (s *StorageTestSuite) TestBlocksGet() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + block, err := s.blocks.Get(ctx, 47) + s.Require().NoError(err) + + s.Require().EqualValues(47, block.ID) + s.Require().EqualValues(47, block.Level) + s.Require().EqualValues(3, block.ProtocolID) + s.Require().Equal("BLwSEbi7iNcW8Cu6wMzN93aHasWudPFL3An62k52SzfH4gHaXf4", block.Hash) + s.Require().Equal("2022-01-25T17:17:47Z", block.Timestamp.Format(time.RFC3339)) + s.Require().Equal("PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx", block.Protocol.Hash) +} + +func (s *StorageTestSuite) TestBlocksLast() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + block, err := s.blocks.Last(ctx) + s.Require().NoError(err) + + s.Require().EqualValues(47, block.ID) + s.Require().EqualValues(47, block.Level) + s.Require().EqualValues(3, block.ProtocolID) + s.Require().Equal("BLwSEbi7iNcW8Cu6wMzN93aHasWudPFL3An62k52SzfH4gHaXf4", block.Hash) + s.Require().Equal("2022-01-25T17:17:47Z", block.Timestamp.Format(time.RFC3339)) + s.Require().Equal("PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx", block.Protocol.Hash) +} diff --git a/internal/postgres/tests/contracts_test.go b/internal/postgres/tests/contracts_test.go new file mode 100644 index 000000000..2d75d0b3d --- /dev/null +++ b/internal/postgres/tests/contracts_test.go @@ -0,0 +1,106 @@ +package tests + +import ( + "context" + "time" + + "github.com/baking-bad/bcdhub/internal/bcd" + "github.com/baking-bad/bcdhub/internal/bcd/consts" + "github.com/baking-bad/bcdhub/internal/models/types" +) + +func (s *StorageTestSuite) TestContractGet() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + contract, err := s.contracts.Get(ctx, "KT1CMJQmuwwJopNnLhSDHXT3zQVUrNPLA8br") + s.Require().NoError(err) + + s.Require().EqualValues(4, contract.ID) + s.Require().EqualValues(33, contract.Level) + s.Require().EqualValues(45, contract.Account.ID) + s.Require().EqualValues(1, contract.Account.Type) + s.Require().EqualValues("KT1CMJQmuwwJopNnLhSDHXT3zQVUrNPLA8br", contract.Account.Address) +} + +func (s *StorageTestSuite) TestContractByHash() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + script, err := s.contracts.ByHash(ctx, "95d118c83ad81586ba4a39c07a47ff7804f5e6d1ebe1a943016d0c61b4940fb6") + s.Require().NoError(err) + + s.Require().EqualValues(21, script.ID) + s.Require().NotEmpty(script.Parameter) + s.Require().NotEmpty(script.Code) + s.Require().NotEmpty(script.Storage) + s.Require().NotEmpty(script.Entrypoints) +} + +func (s *StorageTestSuite) TestContractScript() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + script, err := s.contracts.Script(ctx, "KT1CMJQmuwwJopNnLhSDHXT3zQVUrNPLA8br", bcd.SymLinkBabylon) + s.Require().NoError(err) + + s.Require().EqualValues(7, script.ID) + s.Require().NotEmpty(script.Parameter) + s.Require().NotEmpty(script.Code) + s.Require().NotEmpty(script.Storage) + s.Require().NotEmpty(script.Entrypoints) +} + +func (s *StorageTestSuite) TestContractParameter() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + data, err := s.contracts.Parameter(ctx, 4) + s.Require().NoError(err) + s.Require().NotEmpty(data) +} + +func (s *StorageTestSuite) TestContractStorage() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + data, err := s.contracts.Storage(ctx, 4) + s.Require().NoError(err) + s.Require().NotEmpty(data) +} + +func (s *StorageTestSuite) TestContractCode() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + data, err := s.contracts.Code(ctx, 4) + s.Require().NoError(err) + s.Require().NotEmpty(data) +} + +func (s *StorageTestSuite) TestContractViews() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + data, err := s.contracts.Views(ctx, 20) + s.Require().NoError(err) + s.Require().NotEmpty(data) +} + +func (s *StorageTestSuite) TestContractScriptPart() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + data, err := s.contracts.ScriptPart(ctx, "KT1CMJQmuwwJopNnLhSDHXT3zQVUrNPLA8br", bcd.SymLinkBabylon, consts.STORAGE) + s.Require().NoError(err) + s.Require().NotEmpty(data) +} + +func (s *StorageTestSuite) TestContractFindOne() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + contract, err := s.contracts.FindOne(ctx, types.FA2Tag) + s.Require().NoError(err) + s.Require().Positive(contract.ID) +} diff --git a/internal/postgres/tests/domains_test.go b/internal/postgres/tests/domains_test.go new file mode 100644 index 000000000..8fbdc55fe --- /dev/null +++ b/internal/postgres/tests/domains_test.go @@ -0,0 +1,42 @@ +package tests + +import ( + "context" + "time" + + "github.com/baking-bad/bcdhub/internal/models/contract" +) + +func (s *StorageTestSuite) TestSame() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + contracts, err := s.domains.Same(ctx, "public", contract.Contract{ + ID: 25, + BabylonID: 8, + AccountID: 132, + Babylon: contract.Script{ + ID: 5, + Hash: "621506fddbe82712919f68b8b52bcc684cff7bdc650409f4b038cffd2da1e018", + }, + }, 2, 0, "public") + s.Require().NoError(err) + s.Require().Len(contracts, 2) +} + +func (s *StorageTestSuite) TestSameCount() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + count, err := s.domains.SameCount(ctx, contract.Contract{ + ID: 25, + BabylonID: 5, + AccountID: 132, + Babylon: contract.Script{ + ID: 5, + Hash: "621506fddbe82712919f68b8b52bcc684cff7bdc650409f4b038cffd2da1e018", + }, + }, "public") + s.Require().NoError(err) + s.Require().EqualValues(31, count) +} diff --git a/internal/postgres/tests/fixtures/accounts.yml b/internal/postgres/tests/fixtures/accounts.yml new file mode 100644 index 000000000..aa7a3e552 --- /dev/null +++ b/internal/postgres/tests/fixtures/accounts.yml @@ -0,0 +1,1071 @@ +- address: KT1VqarPDicMFn1ejmQqqshUkUXTCTXwmkCN + id: 1 + last_action: 0001-01-01T00:00:00Z + level: 1 + operations_count: 0 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo + id: 3 + last_action: 0001-01-01T00:00:00Z + level: 1 + operations_count: 0 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1TxqZ8QtKvLu3V3JH7Gx58n7Co8pgtpQU5 + id: 2 + last_action: 2022-01-25T17:01:51Z + level: 1 + operations_count: 39 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz28zXKvosLUdFyYZKQU1vPxcedWzjRypApr + id: 35 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2EeYh11ZkpkaY7CxqhVGRygcwbEQZZHmF3 + id: 36 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2Gw352Tj8pdu3EPrd8K9jDh4JmndbDGYVx + id: 38 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2DTRTbhRx6Yp1pVXpwSZPiHZwudpEaYYyU + id: 39 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1Bc3T8ZcYPTTZHLTrAh2exfw6hyaTriMpQ + id: 40 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1W3fGSo8XfRSESPAg3Jngzt3D8xpPqW64i + id: 41 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2WFEmgnWqFY6FWBMFgrS4MW4c3pJRS8nzU + id: 42 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + id: 43 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2VK6tUXWA6y4QGNEVW4FPDiPu4nHNAabzj + id: 44 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1CMJQmuwwJopNnLhSDHXT3zQVUrNPLA8br + id: 45 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2JJACvm6AzjV7m313kRJie5ZwY74EKTRiT + id: 46 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + id: 47 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + id: 48 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT18cv2aErkY6yf6SspaK9koxiDKJKfuacrD + id: 49 + last_action: 2022-01-25T16:45:09Z + level: 33 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2PkJNxRVc7fFnjTRrtyxWTLRf4buUCjPM5 + id: 50 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1Gv5StW6rsCfuMW8kXN6XcZbbnxJP1SjKs + id: 51 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2CSAMfsuGQYtYoSZHsXkgDpbzSkyVyuMKZ + id: 53 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1L6qnSbi7gCqbwKzGBqzbepxHNC5zR9Egj + id: 54 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1BNS3XGWDJM2Yghm3CYosKStE9reNscbfE + id: 55 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2DjmnH4NawbMmaJfBiqnDPUjAkv8Wtoc6A + id: 56 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1N2EjRy5vmT6if7c6rx5g9BSsx3iUnTD4U + id: 57 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1M1HSELdzFjFdrea4xAwzG1bG3pNtWLcjc + id: 58 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1QyWsqRDsucjbjYvDa3Yr122oecdu3DEiC + id: 59 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2FdYpfM1bv5R9N36tbov96nco7pH3G4ZfP + id: 60 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2LGccCpDMTbDB3RVABT2kp93H4ayvmWqKL + id: 61 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2P3CUbKHsKUWTnhGGYFCXFnB1WAr41TEhN + id: 62 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2L7g8Mbi25WjF7Rgc1YqUZUToqQkqgyTQa + id: 63 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1WTSLx8VnUNFMJGegUELLdg54zpvt82trD + id: 64 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2McXsY5sJk8aupG53MT8VoG8XkS4QhjGLE + id: 65 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + id: 66 + last_action: 2022-01-25T16:47:37Z + level: 34 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2GtWZf4emNRmcmQNsKu7XmAWMXhSyjc4qm + id: 67 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1PH3UK1BFzYYCbSrarpai9wnVMGr57A6fn + id: 68 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1BZJFEifWnscmwTPQonMufy7WZGKvzVhza + id: 69 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1J8Ar7hfJEbbao4MfYhegTCgjtNaKTNTAx + id: 71 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1KBbnu8MKKMmaH7i2VPZAB6PYZ7LGAMak9 + id: 72 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2NgBSz3K3waxZoRSBjY8VtnWdtztRQotKX + id: 73 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2UH4fxCq1Lq5GyzBmgye4pxXSTU7Qr5crU + id: 74 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2NGd6dy3RHrLc8UkGAC2YaouPebutRpPz3 + id: 75 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2XP666xYuWttBWJLT1RnfniAL2hgLDsgmj + id: 76 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1EtstqV7RgirhbB25uJruV83pGkZkEFQCe + id: 77 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2CUyGyhjS5A4SJoRiJBFrTCNgtCwuAcvUf + id: 78 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1XKhK1QZWLrLntWhaDpaqEkuR57CYuWKk3 + id: 79 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2Ka219QMSec5qq5nYP7FcTju55Dqz3iSNu + id: 80 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1H59QHJgqmiZ2Cfvw3MUUaPFxjWcowFVhY + id: 81 + last_action: 2022-01-25T16:49:57Z + level: 35 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1Cpif3AepmaRe17AQtHiQ1Bt6P1CwzgX1j + id: 82 + last_action: 2022-01-25T16:52:19Z + level: 36 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2FyXQJyBKxn5zmpcbczWskW6nhkmQto5sF + id: 83 + last_action: 2022-01-25T16:52:19Z + level: 36 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz28tMBu8yTiRukhnjJE6g5VMXWKdMbZ4XH2 + id: 84 + last_action: 2022-01-25T16:52:19Z + level: 36 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1S1k4CKmLn6Bz95NT6HmeRzzJwaaRyCY7Q + id: 85 + last_action: 2022-01-25T16:52:19Z + level: 36 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2WKMzRRFrsWzi5MUH4bhx2ZBwu2y36hQhJ + id: 86 + last_action: 2022-01-25T16:52:19Z + level: 36 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1F6hdHeL6ceJtKHGnWj397SMqP4x4v3Mas + id: 87 + last_action: 2022-01-25T16:52:19Z + level: 36 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1EM1ae3RznqNYjvuRvepdrveogsq2SoPpF + id: 89 + last_action: 2022-01-25T16:52:19Z + level: 36 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2H48i7m5BBFZddm1Ek6dUYcjKzXcU7SzLe + id: 90 + last_action: 2022-01-25T16:52:19Z + level: 36 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1MpEYtKWzgmpjFxryKvBC3dMuvD64Bt7pv + id: 93 + last_action: 2022-01-25T16:52:19Z + level: 36 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1RPs9iqAj4rRDyecoDz6RqhF2dVfRtWi78 + id: 95 + last_action: 2022-01-25T16:54:35Z + level: 37 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz3SCFL6gjXrSAzT2cvN9bemgPBdJCpf9r6B + id: 96 + last_action: 2022-01-25T16:54:35Z + level: 37 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1JHuz6B6HC5gaot8AGHd2UhkUd9Z2BgYW5 + id: 97 + last_action: 2022-01-25T16:54:35Z + level: 37 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1UjbtbMAXR29QgyRus71pniSjL4R7c1EML + id: 98 + last_action: 2022-01-25T16:54:35Z + level: 37 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1JNf4bXhbz8WZTATQvmdTxGE5k5qBV9q82 + id: 99 + last_action: 2022-01-25T16:54:35Z + level: 37 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz3iiAKWuACM7DDXZ3kDnRh6vkF2Sx2rQLNF + id: 100 + last_action: 2022-01-25T16:54:35Z + level: 37 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT19WNvB1Wt6XRevhDNQ9vNTUN4A8Jqx16w4 + id: 101 + last_action: 2022-01-25T16:54:35Z + level: 37 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2CMxYEv6PY2asiihtoSF8a1Hbi95wtHGbQ + id: 92 + last_action: 2022-01-25T16:54:35Z + level: 36 + operations_count: 2 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT18sWFGnjvobw9BiHrm9bjpWr3AFAAVas9w + id: 88 + last_action: 2022-01-25T16:54:35Z + level: 36 + operations_count: 3 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2M6ERPpdK2xpgZahXTF99MV5Bw8DmUg56M + id: 104 + last_action: 2022-01-25T16:54:35Z + level: 37 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2MQ4tKVdEYxN69FcATE6cUgv9nfRHYxRva + id: 105 + last_action: 2022-01-25T16:54:35Z + level: 37 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2P74gV25xGQrrLA9yru2RLDPpciirJ94Qv + id: 94 + last_action: 2022-01-25T16:54:35Z + level: 36 + operations_count: 2 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz28nwcXsECuhiRwNR5cT83Shj75WszMpKFK + id: 108 + last_action: 2022-01-25T16:54:35Z + level: 37 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1LBiP4VgzuV9BV62wHiGhetE6saTbs4XSk + id: 109 + last_action: 2022-01-25T16:54:35Z + level: 37 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1K4FMgPePdryt7g4vh4ckFWuwbVQYMDLLL + id: 111 + last_action: 2022-01-25T16:56:47Z + level: 38 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2V2gbEzZUJ4orVzw74BdLTXGXJc1y8vxK4 + id: 112 + last_action: 2022-01-25T16:56:47Z + level: 38 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1RzNBqpENY1D8cKXvbAA2G1oavw49J8pYG + id: 113 + last_action: 2022-01-25T16:56:47Z + level: 38 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2M3Jt5X57D7i6v6QNJ6ZipdnRjnRM3pPyh + id: 114 + last_action: 2022-01-25T16:56:47Z + level: 38 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1WfndvipjhvmJ7XoHTHJYDvTncPkgdEGWm + id: 118 + last_action: 2022-01-25T16:56:47Z + level: 38 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2FgaxCo6yfLSuFRQ1bEy1zSntv9wKWX1b6 + id: 119 + last_action: 2022-01-25T16:56:47Z + level: 38 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1MXcocFTwXV2emtgHAC7tCUt4Zc3EPPZAE + id: 120 + last_action: 2022-01-25T16:56:47Z + level: 38 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2AGpSkHSMKw7G1q7roseheDVYmmRjNCkb5 + id: 126 + last_action: 2022-01-25T16:59:07Z + level: 39 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1PA9pnZvJRHRxNhw1KqofBRBSTsgt6NeMz + id: 122 + last_action: 2022-01-25T16:59:07Z + level: 38 + operations_count: 7 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2GGf91VB3gK7MaaP8Xua6ohhHAhH4hTCvm + id: 124 + last_action: 2022-01-25T16:59:07Z + level: 38 + operations_count: 5 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1SnnGQTcQFv55Bkw7CKnVmr1rrvN4ZRkve + id: 129 + last_action: 2022-01-25T16:59:07Z + level: 39 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1MWHRFxLq7gnToNvhKCCsiiic5BypKzkmW + id: 116 + last_action: 2022-01-25T16:59:07Z + level: 38 + operations_count: 3 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2GGf91VB3gK7MaaP8Xua6ohhHAhH4hTC11 + id: 131 + last_action: 2022-01-25T16:59:07Z + level: 39 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1BrG24EYvtYGeGgd615Yzhvoa14BNPLZzu + id: 132 + last_action: 2022-01-25T16:59:07Z + level: 39 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1SM849krq9FFxGWCZyc7X5GvAz8XnRmXnf + id: 133 + last_action: 2022-01-25T16:59:07Z + level: 39 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2Ciu1uCBQDgeBM1HSzzeWzihzxZ1RRADpy + id: 123 + last_action: 2022-01-25T16:59:07Z + level: 38 + operations_count: 5 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2CA5QvX5UyFkxkW5ySXT8gLoyyBdhJ8h2f + id: 135 + last_action: 2022-01-25T16:59:07Z + level: 39 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2X3jvMNLAwU54d1UWkJX1ntQNpCuT4Uexk + id: 117 + last_action: 2022-01-25T16:59:07Z + level: 38 + operations_count: 2 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2QYqyuBciQWA6nH2pB4XU9zyg1bREnorzc + id: 139 + last_action: 2022-01-25T16:59:07Z + level: 39 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1Cec7gww3sHZZ9zHFMPi5U5HqKdi5ytL13 + id: 110 + last_action: 2022-01-25T16:59:07Z + level: 38 + operations_count: 7 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1EcQVhDC7izqW3uiGVrqbus6qBt78btyHv + id: 141 + last_action: 2022-01-25T16:59:07Z + level: 39 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2W7qKNpsUDLs64KenWdt9HsgXigHvtMDT6 + id: 115 + last_action: 2022-01-25T16:59:07Z + level: 38 + operations_count: 2 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1FwXdpRRQstV7XWweSKLReB3C5Fy52dLvE + id: 137 + last_action: 2022-01-25T17:01:51Z + level: 39 + operations_count: 7 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2SKuR2hfqMFo7gKuzFSL9jUXefsucj28Zp + id: 144 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1TYdptHAspE8JSB2XmzVrNze4gbCA2AuDN + id: 145 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1UF6hwuvFAxwcwLsXJyiu1q1T1KDZ3yZez + id: 146 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2FizizmVED2T4D5y5wn4B9kpZLaE66zSAp + id: 147 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1DWPyUzA7z2iDKrFpVvRdWPZKEEYueRoAg + id: 148 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2BauU3guWNGbn2qCQWK2UaAE74AdSMRwnX + id: 149 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1 + id: 150 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2KJHRduQNH3fBrmywJ3HWHqPHMu3fmaKc5 + id: 151 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2MeNdvFPELDgbnmhLdiKHh9196gTfruEdy + id: 130 + last_action: 2022-01-25T17:01:51Z + level: 39 + operations_count: 5 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz1eY5Aqa1kXDFoiebL28emyXFoneAoVg1zh + id: 125 + last_action: 2022-01-25T17:01:51Z + level: 39 + operations_count: 3 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1FEMzUropmcrhNJ3Zw1iduatxZxkLCiqCd + id: 154 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT18vZxXVGtyZWRHaka7hivkE14wBbYLXhVC + id: 156 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2JPf1WqpTd5MoSmyKtRL2UAZJ9mvjZabjp + id: 157 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2DBVWEam4raYjJR1bXpKyULNDz8RkyRmuw + id: 158 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: tz2LS1eviDvwKXoXAFn7cWrkc3uVW22cCimt + id: 159 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 1 + type: 2 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- address: KT1FQE7EtHEkmDTw5iRoUgeveVW6PiPUH9pC + id: 160 + last_action: 2022-01-25T17:01:51Z + level: 40 + operations_count: 2 + type: 1 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 +- id: 344 + type: 4 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 + address: sr1BP9kkXc1T4sRpX4kZuQoWKauLkMjijEDv + level: 48 + operations_count: 2 + last_action: '2022-01-25T17:19:59.000Z' +- id: 345 + type: 4 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 + address: sr1EAHRyUgVPp2zaXXfth9fMKUBYKv3x9cLQ + level: 48 + operations_count: 2 + last_action: '2022-01-25T17:19:59.000Z' +- id: 346 + type: 4 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 + address: sr17vi6kNWjJu1U5kHzoiBwZR5ycjmnArLRy + level: 48 + operations_count: 2 + last_action: '2022-01-25T17:19:59.000Z' +- id: 347 + type: 4 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 + address: sr1UnsiEmcERkhXeFZubggtsUdjhmyoFpHdd + level: 48 + operations_count: 2 + last_action: '2022-01-25T17:19:59.000Z' +- id: 348 + type: 4 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 + address: sr1UW2LkwV7KvxAQ92N9BhJZDN1ktMEy7LTq + level: 48 + operations_count: 2 + last_action: '2022-01-25T17:19:59.000Z' +- id: 349 + type: 4 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 + address: sr1JjAGxzcDkUbsrm1uzn2FoddJKFZPD6EYQ + level: 48 + operations_count: 2 + last_action: '2022-01-25T17:19:59.000Z' +- id: 350 + type: 4 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 + address: sr195QGbURK29Jn5RojRaE198B8F4XvM7KBD + level: 48 + operations_count: 2 + last_action: '2022-01-25T17:19:59.000Z' +- id: 351 + type: 4 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 + address: sr1J21xQ1mP2npCmJuYnX3pvxZ7G3Axacyt6 + level: 48 + operations_count: 2 + last_action: '2022-01-25T17:19:59.000Z' +- id: 352 + type: 4 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 + address: sr1Nw5X1t6X7hWAdZrsgnPGF8VSQTXPMP983 + level: 48 + operations_count: 2 + last_action: '2022-01-25T17:19:59.000Z' +- id: 353 + type: 4 + events_count: 0 + migrations_count: 0 + ticket_updates_count: 0 + address: sr1EWwrq1qm6irxkE9Ti18sL2qgvgDPhanWH + level: 48 + operations_count: 2 + last_action: '2022-01-25T17:19:59.000Z' diff --git a/internal/postgres/tests/fixtures/big_map_actions.yml b/internal/postgres/tests/fixtures/big_map_actions.yml new file mode 100644 index 000000000..f018b412a --- /dev/null +++ b/internal/postgres/tests/fixtures/big_map_actions.yml @@ -0,0 +1,832 @@ +- action: 1 + address: KT1W3fGSo8XfRSESPAg3Jngzt3D8xpPqW64i + destination_ptr: null + id: 1 + level: 33 + operation_id: 34 + source_ptr: 4 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1Bc3T8ZcYPTTZHLTrAh2exfw6hyaTriMpQ + destination_ptr: null + id: 2 + level: 33 + operation_id: 35 + source_ptr: 5 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + destination_ptr: null + id: 3 + level: 33 + operation_id: 36 + source_ptr: 11 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + destination_ptr: null + id: 4 + level: 33 + operation_id: 36 + source_ptr: 10 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + destination_ptr: null + id: 5 + level: 33 + operation_id: 36 + source_ptr: 9 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + destination_ptr: null + id: 6 + level: 33 + operation_id: 36 + source_ptr: 8 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + destination_ptr: null + id: 7 + level: 33 + operation_id: 36 + source_ptr: 7 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + destination_ptr: null + id: 8 + level: 33 + operation_id: 36 + source_ptr: 6 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT18cv2aErkY6yf6SspaK9koxiDKJKfuacrD + destination_ptr: null + id: 9 + level: 33 + operation_id: 37 + source_ptr: 12 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + destination_ptr: null + id: 10 + level: 33 + operation_id: 38 + source_ptr: 16 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + destination_ptr: null + id: 11 + level: 33 + operation_id: 38 + source_ptr: 15 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + destination_ptr: null + id: 12 + level: 33 + operation_id: 38 + source_ptr: 14 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + destination_ptr: null + id: 13 + level: 33 + operation_id: 38 + source_ptr: 13 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + destination_ptr: null + id: 14 + level: 33 + operation_id: 39 + source_ptr: 20 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + destination_ptr: null + id: 15 + level: 33 + operation_id: 39 + source_ptr: 19 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + destination_ptr: null + id: 16 + level: 33 + operation_id: 39 + source_ptr: 18 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + destination_ptr: null + id: 17 + level: 33 + operation_id: 39 + source_ptr: 17 + timestamp: 2022-01-25T16:45:09Z +- action: 1 + address: KT1L6qnSbi7gCqbwKzGBqzbepxHNC5zR9Egj + destination_ptr: null + id: 18 + level: 34 + operation_id: 43 + source_ptr: 21 + timestamp: 2022-01-25T16:47:37Z +- action: 1 + address: KT1QyWsqRDsucjbjYvDa3Yr122oecdu3DEiC + destination_ptr: null + id: 19 + level: 34 + operation_id: 44 + source_ptr: 22 + timestamp: 2022-01-25T16:47:37Z +- action: 1 + address: KT1BNS3XGWDJM2Yghm3CYosKStE9reNscbfE + destination_ptr: null + id: 20 + level: 34 + operation_id: 45 + source_ptr: 23 + timestamp: 2022-01-25T16:47:37Z +- action: 1 + address: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + destination_ptr: null + id: 21 + level: 34 + operation_id: 47 + source_ptr: 27 + timestamp: 2022-01-25T16:47:37Z +- action: 1 + address: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + destination_ptr: null + id: 22 + level: 34 + operation_id: 47 + source_ptr: 26 + timestamp: 2022-01-25T16:47:37Z +- action: 1 + address: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + destination_ptr: null + id: 23 + level: 34 + operation_id: 47 + source_ptr: 25 + timestamp: 2022-01-25T16:47:37Z +- action: 1 + address: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + destination_ptr: null + id: 24 + level: 34 + operation_id: 47 + source_ptr: 24 + timestamp: 2022-01-25T16:47:37Z +- action: 1 + address: KT1Gv5StW6rsCfuMW8kXN6XcZbbnxJP1SjKs + destination_ptr: null + id: 25 + level: 34 + operation_id: 48 + source_ptr: 28 + timestamp: 2022-01-25T16:47:37Z +- action: 1 + address: KT1XKhK1QZWLrLntWhaDpaqEkuR57CYuWKk3 + destination_ptr: null + id: 26 + level: 35 + operation_id: 54 + source_ptr: 29 + timestamp: 2022-01-25T16:49:57Z +- action: 1 + address: KT1H59QHJgqmiZ2Cfvw3MUUaPFxjWcowFVhY + destination_ptr: null + id: 27 + level: 35 + operation_id: 55 + source_ptr: 30 + timestamp: 2022-01-25T16:49:57Z +- action: 1 + address: KT1BZJFEifWnscmwTPQonMufy7WZGKvzVhza + destination_ptr: null + id: 28 + level: 35 + operation_id: 56 + source_ptr: 31 + timestamp: 2022-01-25T16:49:57Z +- action: 1 + address: KT1S1k4CKmLn6Bz95NT6HmeRzzJwaaRyCY7Q + destination_ptr: null + id: 29 + level: 36 + operation_id: 61 + source_ptr: 32 + timestamp: 2022-01-25T16:52:19Z +- action: 1 + address: KT1MpEYtKWzgmpjFxryKvBC3dMuvD64Bt7pv + destination_ptr: null + id: 30 + level: 36 + operation_id: 62 + source_ptr: 33 + timestamp: 2022-01-25T16:52:19Z +- action: 1 + address: KT1F6hdHeL6ceJtKHGnWj397SMqP4x4v3Mas + destination_ptr: null + id: 31 + level: 36 + operation_id: 63 + source_ptr: 34 + timestamp: 2022-01-25T16:52:19Z +- action: 1 + address: KT1RPs9iqAj4rRDyecoDz6RqhF2dVfRtWi78 + destination_ptr: null + id: 32 + level: 37 + operation_id: 70 + source_ptr: 35 + timestamp: 2022-01-25T16:54:35Z +- action: 1 + address: KT1LBiP4VgzuV9BV62wHiGhetE6saTbs4XSk + destination_ptr: null + id: 33 + level: 37 + operation_id: 71 + source_ptr: 36 + timestamp: 2022-01-25T16:54:35Z +- action: 1 + address: KT1WfndvipjhvmJ7XoHTHJYDvTncPkgdEGWm + destination_ptr: null + id: 34 + level: 38 + operation_id: 78 + source_ptr: 37 + timestamp: 2022-01-25T16:56:47Z +- action: 1 + address: KT1MXcocFTwXV2emtgHAC7tCUt4Zc3EPPZAE + destination_ptr: null + id: 35 + level: 38 + operation_id: 79 + source_ptr: 38 + timestamp: 2022-01-25T16:56:47Z +- action: 1 + address: KT1EcQVhDC7izqW3uiGVrqbus6qBt78btyHv + destination_ptr: null + id: 36 + level: 39 + operation_id: 96 + source_ptr: 39 + timestamp: 2022-01-25T16:59:07Z +- action: 1 + address: KT1FQE7EtHEkmDTw5iRoUgeveVW6PiPUH9pC + destination_ptr: null + id: 37 + level: 40 + operation_id: 107 + source_ptr: 40 + timestamp: 2022-01-25T17:01:51Z +- action: 1 + address: KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1 + destination_ptr: null + id: 38 + level: 40 + operation_id: 109 + source_ptr: 42 + timestamp: 2022-01-25T17:01:51Z +- action: 1 + address: KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1 + destination_ptr: null + id: 39 + level: 40 + operation_id: 109 + source_ptr: 41 + timestamp: 2022-01-25T17:01:51Z +- action: 1 + address: KT1SryiY3YiHrtfth14JDWAP83W2WbSo1y6o + destination_ptr: null + id: 40 + level: 41 + operation_id: 119 + source_ptr: 43 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1RhyRG4etPssUovWHapMsfDbQqwPGAHHuc + destination_ptr: null + id: 41 + level: 41 + operation_id: 120 + source_ptr: 44 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1D5LEDRjTeG4HcGyKKfnschdS3nTJEbqx7 + destination_ptr: null + id: 42 + level: 41 + operation_id: 121 + source_ptr: 45 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1Lgy1eDiJpiZ3NZZXEz4i5MVSy4wG9g9c8 + destination_ptr: null + id: 43 + level: 41 + operation_id: 124 + source_ptr: 47 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1Lgy1eDiJpiZ3NZZXEz4i5MVSy4wG9g9c8 + destination_ptr: null + id: 44 + level: 41 + operation_id: 124 + source_ptr: 46 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1R9BdHMfGTwKnbCHii8akcB7DqzfdnD9AD + destination_ptr: null + id: 45 + level: 41 + operation_id: 125 + source_ptr: 48 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + destination_ptr: null + id: 46 + level: 41 + operation_id: 126 + source_ptr: 54 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + destination_ptr: null + id: 47 + level: 41 + operation_id: 126 + source_ptr: 53 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + destination_ptr: null + id: 48 + level: 41 + operation_id: 126 + source_ptr: 52 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + destination_ptr: null + id: 49 + level: 41 + operation_id: 126 + source_ptr: 51 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + destination_ptr: null + id: 50 + level: 41 + operation_id: 126 + source_ptr: 50 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + destination_ptr: null + id: 51 + level: 41 + operation_id: 126 + source_ptr: 49 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1Dd1HZSwbikboLRzurVg5z6rfTVziusdUt + destination_ptr: null + id: 52 + level: 41 + operation_id: 127 + source_ptr: 55 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1TSsjjzoGbWLMgUwdDUw33CLz34sQs5jYX + destination_ptr: null + id: 53 + level: 41 + operation_id: 128 + source_ptr: 59 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1TSsjjzoGbWLMgUwdDUw33CLz34sQs5jYX + destination_ptr: null + id: 54 + level: 41 + operation_id: 128 + source_ptr: 58 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1TSsjjzoGbWLMgUwdDUw33CLz34sQs5jYX + destination_ptr: null + id: 55 + level: 41 + operation_id: 128 + source_ptr: 57 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1TSsjjzoGbWLMgUwdDUw33CLz34sQs5jYX + destination_ptr: null + id: 56 + level: 41 + operation_id: 128 + source_ptr: 56 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1RrexTzK8S2ecKsDZLB6BKMKUP1vVmg9Hh + destination_ptr: null + id: 57 + level: 41 + operation_id: 129 + source_ptr: 63 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1RrexTzK8S2ecKsDZLB6BKMKUP1vVmg9Hh + destination_ptr: null + id: 58 + level: 41 + operation_id: 129 + source_ptr: 62 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1RrexTzK8S2ecKsDZLB6BKMKUP1vVmg9Hh + destination_ptr: null + id: 59 + level: 41 + operation_id: 129 + source_ptr: 61 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT1RrexTzK8S2ecKsDZLB6BKMKUP1vVmg9Hh + destination_ptr: null + id: 60 + level: 41 + operation_id: 129 + source_ptr: 60 + timestamp: 2022-01-25T17:04:35Z +- action: 1 + address: KT18dyvjdq4gFuQuG1CnNZfd35Jk2UbiKcPB + destination_ptr: null + id: 61 + level: 42 + operation_id: 136 + source_ptr: 64 + timestamp: 2022-01-25T17:07:03Z +- action: 1 + address: KT1UJ5bYnGpkwZLTJpa2cUXUX3dz8St8qxNn + destination_ptr: null + id: 62 + level: 42 + operation_id: 137 + source_ptr: 65 + timestamp: 2022-01-25T17:07:03Z +- action: 1 + address: KT1Sd3BSdF5VKiU1oe6VqYifGe6TfqbkDDGZ + destination_ptr: null + id: 63 + level: 42 + operation_id: 138 + source_ptr: 66 + timestamp: 2022-01-25T17:07:03Z +- action: 1 + address: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + destination_ptr: null + id: 64 + level: 42 + operation_id: 140 + source_ptr: 70 + timestamp: 2022-01-25T17:07:03Z +- action: 1 + address: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + destination_ptr: null + id: 65 + level: 42 + operation_id: 140 + source_ptr: 69 + timestamp: 2022-01-25T17:07:03Z +- action: 1 + address: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + destination_ptr: null + id: 66 + level: 42 + operation_id: 140 + source_ptr: 68 + timestamp: 2022-01-25T17:07:03Z +- action: 1 + address: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + destination_ptr: null + id: 67 + level: 42 + operation_id: 140 + source_ptr: 67 + timestamp: 2022-01-25T17:07:03Z +- action: 1 + address: KT18jPdN1UAFvXppPh41PS5xZP3Xx7F6s91D + destination_ptr: null + id: 68 + level: 42 + operation_id: 141 + source_ptr: 71 + timestamp: 2022-01-25T17:07:03Z +- action: 1 + address: KT1SGb8wy8CPTWBTMYipFv5rDTBQnuyceL4Z + destination_ptr: null + id: 69 + level: 43 + operation_id: 147 + source_ptr: 72 + timestamp: 2022-01-25T17:09:21Z +- action: 1 + address: KT1A1euYzsXoqoVq6CFss6ofWgfbfev97FxT + destination_ptr: null + id: 70 + level: 43 + operation_id: 148 + source_ptr: 73 + timestamp: 2022-01-25T17:09:21Z +- action: 1 + address: KT1UnZaX82rgUBvaj3iA8D3W7T2Zxe6kxTiQ + destination_ptr: null + id: 71 + level: 43 + operation_id: 149 + source_ptr: 74 + timestamp: 2022-01-25T17:09:21Z +- action: 1 + address: KT1NDZJknffhfNhh46unvGopGppVmTem1HBG + destination_ptr: null + id: 72 + level: 44 + operation_id: 156 + source_ptr: 75 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1PZ4Qb4Q9NywpLpJBufR5nVUDDSbjH2D6j + destination_ptr: null + id: 73 + level: 44 + operation_id: 157 + source_ptr: 76 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1TFRwXwt1xNd8bLDEnbvZLd446TzT163Bd + destination_ptr: null + id: 74 + level: 44 + operation_id: 158 + source_ptr: 77 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1957qBZ6Qto5oSvqSZqkyTsBPcXFr4J6KM + destination_ptr: null + id: 75 + level: 44 + operation_id: 159 + source_ptr: 78 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1Q4KbVQZZiwgiQi5PWj7a8iVSeHvDLtrHd + destination_ptr: null + id: 76 + level: 44 + operation_id: 160 + source_ptr: 79 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1Gz8N3VwTriRD1VVPrrC5asYF2e1mPSDP9 + destination_ptr: null + id: 77 + level: 44 + operation_id: 161 + source_ptr: 83 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1Gz8N3VwTriRD1VVPrrC5asYF2e1mPSDP9 + destination_ptr: null + id: 78 + level: 44 + operation_id: 161 + source_ptr: 82 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1Gz8N3VwTriRD1VVPrrC5asYF2e1mPSDP9 + destination_ptr: null + id: 79 + level: 44 + operation_id: 161 + source_ptr: 81 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1Gz8N3VwTriRD1VVPrrC5asYF2e1mPSDP9 + destination_ptr: null + id: 80 + level: 44 + operation_id: 161 + source_ptr: 80 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1Tpdf4izXzLqafbQzcW1tfxfcH2ZU6ytVQ + destination_ptr: null + id: 81 + level: 44 + operation_id: 162 + source_ptr: 87 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1Tpdf4izXzLqafbQzcW1tfxfcH2ZU6ytVQ + destination_ptr: null + id: 82 + level: 44 + operation_id: 162 + source_ptr: 86 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1Tpdf4izXzLqafbQzcW1tfxfcH2ZU6ytVQ + destination_ptr: null + id: 83 + level: 44 + operation_id: 162 + source_ptr: 85 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1Tpdf4izXzLqafbQzcW1tfxfcH2ZU6ytVQ + destination_ptr: null + id: 84 + level: 44 + operation_id: 162 + source_ptr: 84 + timestamp: 2022-01-25T17:11:23Z +- action: 1 + address: KT1GCrzzHq2sHjNza1Q89JHHY8Xj2ASYqUJ7 + destination_ptr: null + id: 85 + level: 45 + operation_id: 170 + source_ptr: 88 + timestamp: 2022-01-25T17:13:29Z +- action: 1 + address: KT1DApJtz9Raw5VB2rMcoCewNJUvTdcUmxcW + destination_ptr: null + id: 86 + level: 45 + operation_id: 171 + source_ptr: 89 + timestamp: 2022-01-25T17:13:29Z +- action: 1 + address: KT1URpVU61u5ubaWKdXBfJC2rfmSazD7Tdo8 + destination_ptr: null + id: 87 + level: 45 + operation_id: 172 + source_ptr: 90 + timestamp: 2022-01-25T17:13:29Z +- action: 1 + address: KT1LnJ3F6eYTBnuCmJGEuDCmsZWQGzrav4Kt + destination_ptr: null + id: 88 + level: 45 + operation_id: 173 + source_ptr: 91 + timestamp: 2022-01-25T17:13:29Z +- action: 1 + address: KT1EVwPVd8B1eDEbfj9AQCtFTzQ2AAQ16C4g + destination_ptr: null + id: 89 + level: 45 + operation_id: 175 + source_ptr: 92 + timestamp: 2022-01-25T17:13:29Z +- action: 1 + address: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + destination_ptr: null + id: 90 + level: 45 + operation_id: 176 + source_ptr: 98 + timestamp: 2022-01-25T17:13:29Z +- action: 1 + address: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + destination_ptr: null + id: 91 + level: 45 + operation_id: 176 + source_ptr: 97 + timestamp: 2022-01-25T17:13:29Z +- action: 1 + address: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + destination_ptr: null + id: 92 + level: 45 + operation_id: 176 + source_ptr: 96 + timestamp: 2022-01-25T17:13:29Z +- action: 1 + address: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + destination_ptr: null + id: 93 + level: 45 + operation_id: 176 + source_ptr: 95 + timestamp: 2022-01-25T17:13:29Z +- action: 1 + address: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + destination_ptr: null + id: 94 + level: 45 + operation_id: 176 + source_ptr: 94 + timestamp: 2022-01-25T17:13:29Z +- action: 1 + address: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + destination_ptr: null + id: 95 + level: 45 + operation_id: 176 + source_ptr: 93 + timestamp: 2022-01-25T17:13:29Z +- action: 1 + address: KT1HKqSnRy9JDvdin2kftG5f8pL1KMenL455 + destination_ptr: null + id: 96 + level: 45 + operation_id: 177 + source_ptr: 99 + timestamp: 2022-01-25T17:13:29Z +- action: 1 + address: KT1WbQNVCyqq86XVsaD95L8XZf4D6SZEEmbv + destination_ptr: null + id: 97 + level: 47 + operation_id: 185 + source_ptr: 100 + timestamp: 2022-01-25T17:17:47Z +- action: 1 + address: KT1LAbdmU3YgRratLRomHaBfMGBbgW4TpzLz + destination_ptr: null + id: 98 + level: 47 + operation_id: 186 + source_ptr: 101 + timestamp: 2022-01-25T17:17:47Z +- action: 1 + address: KT1VuXpJtos2XEnGRBwioU83JceXD4JoVDpr + destination_ptr: null + id: 99 + level: 47 + operation_id: 187 + source_ptr: 102 + timestamp: 2022-01-25T17:17:47Z +- action: 1 + address: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + destination_ptr: null + id: 100 + level: 47 + operation_id: 189 + source_ptr: 106 + timestamp: 2022-01-25T17:17:47Z +- action: 1 + address: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + destination_ptr: null + id: 101 + level: 47 + operation_id: 189 + source_ptr: 105 + timestamp: 2022-01-25T17:17:47Z +- action: 1 + address: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + destination_ptr: null + id: 102 + level: 47 + operation_id: 189 + source_ptr: 104 + timestamp: 2022-01-25T17:17:47Z +- action: 1 + address: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + destination_ptr: null + id: 103 + level: 47 + operation_id: 189 + source_ptr: 103 + timestamp: 2022-01-25T17:17:47Z +- action: 1 + address: KT1EXfibFnDtpyZbUCAzWuy2QyeQ4bbtF7Ac + destination_ptr: null + id: 104 + level: 47 + operation_id: 190 + source_ptr: 107 + timestamp: 2022-01-25T17:17:47Z diff --git a/internal/postgres/tests/fixtures/big_map_diffs.yml b/internal/postgres/tests/fixtures/big_map_diffs.yml new file mode 100644 index 000000000..0099182e2 --- /dev/null +++ b/internal/postgres/tests/fixtures/big_map_diffs.yml @@ -0,0 +1,1420 @@ +- contract: KT1W3fGSo8XfRSESPAg3Jngzt3D8xpPqW64i + id: 1 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 33 + operation_id: 34 + protocol_id: 3 + ptr: 4 + timestamp: 2022-01-25T16:45:09Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d7074792d6d657461646174612e6a736f6e"}' +- contract: KT1Bc3T8ZcYPTTZHLTrAh2exfw6hyaTriMpQ + id: 2 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 33 + operation_id: 35 + protocol_id: 3 + ptr: 5 + timestamp: 2022-01-25T16:45:09Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d7074792d6d657461646174612e6a736f6e"}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + id: 3 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + level: 33 + operation_id: 36 + protocol_id: 3 + ptr: 11 + timestamp: 2022-01-25T16:45:09Z + value: '{"int":"10000000"}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + id: 4 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 33 + operation_id: 36 + protocol_id: 3 + ptr: 11 + timestamp: 2022-01-25T16:45:09Z + value: '{"int":"54000000"}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + id: 5 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + level: 33 + operation_id: 36 + protocol_id: 3 + ptr: 10 + timestamp: 2022-01-25T16:45:09Z + value: '{"prim":"Pair","args":[{"int":"2"},[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"30"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"416c696365546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"414c43"}]}]]}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + id: 6 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 33 + operation_id: 36 + protocol_id: 3 + ptr: 10 + timestamp: 2022-01-25T16:45:09Z + value: '{"prim":"Pair","args":[{"int":"1"},[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"36"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"77546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"77544b"}]}]]}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + id: 7 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + level: 33 + operation_id: 36 + protocol_id: 3 + ptr: 9 + timestamp: 2022-01-25T16:45:09Z + value: '{"prim":"Pair","args":[{"bytes":"000270d7a915d558743de0e7edb96aa1c6cc3f17355b"},{"prim":"True"}]}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + id: 8 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 33 + operation_id: 36 + protocol_id: 3 + ptr: 9 + timestamp: 2022-01-25T16:45:09Z + value: '{"prim":"Pair","args":[{"bytes":"0002928d0210a0fd4edc71beabbae6def736931862a9"},{"prim":"True"}]}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + id: 9 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 33 + operation_id: 36 + protocol_id: 3 + ptr: 7 + timestamp: 2022-01-25T16:45:09Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d746f6b656e2d666163746f72792e6a736f6e"}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + id: 10 + key: '{"prim":"Pair","args":[{"bytes":"000270d7a915d558743de0e7edb96aa1c6cc3f17355b"},{"int":"2"}]}' + key_hash: exprvKUeU1hp2XrpHco1C5SN6UpATb2swCBZjn3ChsG67dL5q5M3yP + level: 33 + operation_id: 36 + protocol_id: 3 + ptr: 6 + timestamp: 2022-01-25T16:45:09Z + value: '{"int":"9990000"}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + id: 11 + key: '{"prim":"Pair","args":[{"bytes":"0002928d0210a0fd4edc71beabbae6def736931862a9"},{"int":"1"}]}' + key_hash: expru2rxRxYK6nkgDG1Wysk9Qk8BxndCPRYbmddDYgry9GdyuNigtE + level: 33 + operation_id: 36 + protocol_id: 3 + ptr: 6 + timestamp: 2022-01-25T16:45:09Z + value: '{"int":"18000000"}' +- contract: KT18cv2aErkY6yf6SspaK9koxiDKJKfuacrD + id: 12 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + level: 33 + operation_id: 37 + protocol_id: 3 + ptr: 12 + timestamp: 2022-01-25T16:45:09Z + value: '{"bytes":"7b226465736372697074696f6e223a225468697320636f6e7472616374206861732062797465732d72657475726e696e67206f66662d636861696e2d76696577732e222c226c6963656e7365223a7b226e616d65223a224d4954222c2264657461696c73223a22546865204d4954204c6963656e7365227d2c22736f75726365223a7b22746f6f6c73223a5b22545a436f6d6574225d2c226c6f636174696f6e223a2268747470733a2f2f6769746875622e636f6d2f747174657a6f732f545a436f6d6574227d2c226572726f7273223a5b7b226572726f72223a7b22696e74223a223432227d2c22657870616e73696f6e223a7b22737472696e67223a2248656c6c6f2049276d206572726f72203432227d7d2c7b226572726f72223a7b22696e74223a223432227d2c22657870616e73696f6e223a7b226279746573223a2237313735363536633731373536353230363336383666373336353230366532373631323037303631373332303664363137323633363863336139227d2c226c616e677561676573223a5b226672225d7d2c7b2276696577223a22646f65734e6f744578697374227d2c7b2276696577223a226d756c7469706c795468654e6174496e53746f72616765222c226c616e677561676573223a5b5d7d5d2c227669657773223a5b7b226e616d65223a22656d7074794279746573222c22696d706c656d656e746174696f6e73223a5b7b226d696368656c736f6e53746f7261676556696577223a7b2272657475726e54797065223a7b227072696d223a226279746573222c2261726773223a5b5d2c22616e6e6f7473223a5b222572657475726e65644279746573225d7d2c22636f6465223a5b7b227072696d223a2244524f50222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250555348222c2261726773223a5b7b227072696d223a226279746573222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b226279746573223a22227d5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f746174696f6e73223a5b7b226e616d65223a222572657475726e65644279746573222c226465736372697074696f6e223a224120627974657320636f6e7374616e742e227d5d7d7d5d7d2c7b226e616d65223a22736f6d654a736f6e222c22696d706c656d656e746174696f6e73223a5b7b226d696368656c736f6e53746f7261676556696577223a7b2272657475726e54797065223a7b227072696d223a226279746573222c2261726773223a5b5d2c22616e6e6f7473223a5b222572657475726e65644279746573225d7d2c22636f6465223a5b7b227072696d223a2244524f50222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250555348222c2261726773223a5b7b227072696d223a226279746573222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b226279746573223a22376232323638363536633663366632323361323237373666373236633634323232633232366436663732363532323361376232323663366637323635366432323361333433323263323236393730373337353664323233613562323232323263323236663665363532323263323233323232356437643764227d5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f746174696f6e73223a5b7b226e616d65223a222572657475726e65644279746573222c226465736372697074696f6e223a224120627974657320636f6e7374616e742e227d5d7d7d5d7d2c7b226e616d65223a22736f6d6554657874222c22696d706c656d656e746174696f6e73223a5b7b226d696368656c736f6e53746f7261676556696577223a7b2272657475726e54797065223a7b227072696d223a226279746573222c2261726773223a5b5d2c22616e6e6f7473223a5b222572657475726e65644279746573225d7d2c22636f6465223a5b7b227072696d223a2244524f50222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250555348222c2261726773223a5b7b227072696d223a226279746573222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b226279746573223a223061343836353732363532303639373332303733366636643635323037343635373837343265306164303962643062656431383064306235643062633230643062386430626664313831643138336430626332306430623464306265643062626430626564313830323064313831643062386431383232306430623064306263643062356431383232633230643062306430626264306238643138666431383364306238643062343230643062386430626464313836643062656431383064313830643138336430626664313832643062353230643138326431383564306235643062656430626664313835643138306430623064313831643138326431383364313831323064306235643138333230643138316430623564306230326332306430623864306264306164306235643138336430626332306431383164306265643062626431383364313832643062303230643062656430626664313832643062386430626564306264323064306234643062356431383464306238643062646430623864313832643062386430626564306264643062356430626332653230643039306431383232306430626364306235643062303230643138316430623864306263643138336430626232306430626564313834643138346430623864313836643062386430623864313831323064306263643062656430626264306235643138316431383264306238643062306430623532633230643062356430626564313831306164313866643138336430623064306235643138666431383364306235323064306238643062646430623264306238643062346431383364306264643138323230643138366430626564306264643062326430623564306264643062386431383064306235323064306238643062343265323064303930643138323230643138316430626564306262643062356430623064313832323064306232643062656430626264313833643138326430626664306230643138323230643062326430623564306262326532306430613164306235643062343230643062356430623832306430623864306264643062356431383064306263643062386431383130616430623264306235643138306430623864313832643138336431383130613061656361373831656361303834656238633830656438366235656261306239656339646234323065633937383665633964383432306562393538636563393739306562386139343230656238633830656438366235656261306239656339646234323065636137383065626161383565643935396365623862613432633230656162376238323065636130393565636239393865636130383132306563613439316562613662646563383462316563396438303061656361343830656338383938656239303963656238626134326532306561623561646561623038306562386139343230656262323935656261356130656339646234323065636130393565643935393865623861393432306562623039346563393739303230656339643938656439353938656339376163323065636130393565623862623965633961623465633938383165633937393032306564393538346563396139346564393539633230656339653930656162383838656339643834306165626233623465636131623065643935613032306563383839383230656339653838656238626134326332306561623562306563383261636562623239356563396239306563396439383230656361316230656361373831633262376561623638636564393539633230656262303866323065633965616365643863393065616234383065633964393832306563396539306561623261396563396438303230656262323935656261356130656261313963323065636130393565643935396365623862613432653061227d5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f746174696f6e73223a5b7b226e616d65223a222572657475726e65644279746573222c226465736372697074696f6e223a224120627974657320636f6e7374616e742e227d5d7d7d5d7d2c7b226e616d65223a2232303052616e646f6d43686172616374657273222c22696d706c656d656e746174696f6e73223a5b7b226d696368656c736f6e53746f7261676556696577223a7b2272657475726e54797065223a7b227072696d223a226279746573222c2261726773223a5b5d2c22616e6e6f7473223a5b222572657475726e65644279746573225d7d2c22636f6465223a5b7b227072696d223a2244524f50222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250555348222c2261726773223a5b7b227072696d223a226279746573222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b226279746573223a2232383136636530396330373366393363313063646335656634393833313161636563303666623831383365396538346563646362363230383738333336316631373531613133323463326663656562623734356136316431393034313631656334376462376539313238366436646565643633663062353361313534326138356465643631663139376665663635363136313531353331303334353133353232613966353961393761616536653334303439313038613662346632343366346232373930653630353464653034356234313862343935366562343961313337653263613164373534336430366461313064626132386163373065616363363934646133323066376232323766646363333935323430633661383166336331376362333634636338323430313836383061323936656466353738653064343864616464616164646437306366353365633663376436626462616665396137663865313135633537346162643333386166323965663662636335376131666233363363616637346561356632303633303764227d5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f746174696f6e73223a5b7b226e616d65223a222572657475726e65644279746573222c226465736372697074696f6e223a224120627974657320636f6e7374616e742e227d5d7d7d5d7d2c7b226e616d65223a223130303052616e646f6d43686172616374657273222c22696d706c656d656e746174696f6e73223a5b7b226d696368656c736f6e53746f7261676556696577223a7b2272657475726e54797065223a7b227072696d223a226279746573222c2261726773223a5b5d2c22616e6e6f7473223a5b222572657475726e65644279746573225d7d2c22636f6465223a5b7b227072696d223a2244524f50222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250555348222c2261726773223a5b7b227072696d223a226279746573222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b226279746573223a223334383866323830376664396336373164303932343839366135383438343838653465646632366332396530303032333136633432363630616434313637323436313637303732343935616464646334626137343232333864393636323034653732656335616433656632303337343435333133663132623033326139653233666334376239336134613566353239613561303239663063346132353831393162663762343639643632623137336366383230633539393364653763653339666333663735663139646138356464626266386566653332613531616264313063393033616362376664616663666236653466313063663337643233623236313130346635333632326331376334376136353833346238626535353334646631643437323131363964363365623033316530643261343761666436666363346636663032633564313532633137633265313562386232663139326663663862393132666461633433613130323432653262323537336461616337313036623334653635313963303666336339356636623462343334396139306333393439643333666632316464646231326662316431376166323062343939313637633266623661666562376237323663373834366464663836326332643163396461356233373838616339343766303464303565323732363837306433623039326437323630306530366665343766666365313965613838386239386466633037303366333264633362313730353430383465356439383337383963383539366263333666623832633430646362613136313237316333313164356463393438393635373132626332383266346463333438336238343763386464333930383833386533306635363938613036386363356334666638356337326339396332643435653635393964633764643535653937333833666635646530353033356137306432633838623166363434313764656132313131336138303266306633393931616532303936306161656537316134363730386238366230356230366335313738366530353735313761323038656331303633333964666333346638393838373366376235613833336161363337663263353131316662666338363233316438393035313932393832303737653233353834653464366134636634326266303037363332323432356164306465613063663136373631303263336631373964383333616665356536303061623164323437663030653837613061373630333462393361333234663538313661653631323737393461633334363936636264303935353263346136663564366335343835653461643866643738323365313931353961313662393734366363653362386132326130656264613337303964643933326461336239623766333837623062383730343563633033313866303439323065623536313963363961613866336536666434363439363434363331623735333631393862663636613730613863666264643235333732353566363361623865393732353631613161326131336134393539333263623339313835386663663139636462366132306163333663633037616332666464316161643265373632343763326138363139343230313462393936626461396665666234353866623939363063303535346161393136653666343134366565616630366634316364303530643230313235616461643938396339313630623131313233303138346639646466393139346635353465653038613130393631323939323933333836643138666265316261316664323734303134366162373630633739306633373231653437306266303637343065643635363536613236633664636561306435633161333363366262326534356363306232656163363931396430336135626133343839356632656337353134303233316632646464313838646333346230333561343730323166356432633638323335666537303135336438393532323162626664313261663362663831393739306430393964326130623865383034616465313539666663393565656437646634633064303332383037366433356464663564663736626262613437333233316337313536383032356434306362313966363132316162353739333230346633303331346362343435333364346566366535313265366335646262373736393831396631666665323336393065313366313332356531383261373332633065366530336666396639383837313232623332653466633532353033346539633030663931353961393862396639333032653434626264326562363331376461633635306532643236353131396433333331333863303061333665333930323930653436386432333663316530333136343265376364643566333931313738353732343161633964313165626264336432336335393963653963373835323365613134356566346338353164653030393265626439373665613461376262613837313666616234666430353836383339303732336638313438663630353866643335626231363734613665373934613466663533656662623863356364366139343032653136366262636236363261633731646636303137363735353036353636393964653936356131343334383739636539396662353062623534643335653530303137333435316662646161613839313639393531623366613130363532663065313165323839303165227d5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f746174696f6e73223a5b7b226e616d65223a222572657475726e65644279746573222c226465736372697074696f6e223a224120627974657320636f6e7374616e742e227d5d7d7d5d7d5d7d"}' +- contract: KT18cv2aErkY6yf6SspaK9koxiDKJKfuacrD + id: 13 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 33 + operation_id: 37 + protocol_id: 3 + ptr: 12 + timestamp: 2022-01-25T16:45:09Z + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + id: 14 + key: '{"prim":"Pair","args":[{"bytes":"0002e63a8499e8e4e4efb97968b146ca642f0a942e5d"},{"bytes":"0002e0269b29d74638e31dbc79dd118347060252a3b1"}]}' + key_hash: expruyw8u644EyhfozymSjtnfmTdgEXTcYXjeb6adJqfWJ6okuff1L + level: 33 + operation_id: 38 + protocol_id: 3 + ptr: 15 + timestamp: 2022-01-25T16:45:09Z + value: '{"prim":"Unit"}' +- contract: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + id: 15 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 33 + operation_id: 38 + protocol_id: 3 + ptr: 14 + timestamp: 2022-01-25T16:45:09Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d6d657461646174612e6a736f6e"}' +- contract: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + id: 16 + key: '{"bytes":"0002e63a8499e8e4e4efb97968b146ca642f0a942e5d"}' + key_hash: expruQPyA9Lix6xVuPDHvZt514ksW1ZiStk5T4errxkbXpv9ZRig2z + level: 33 + operation_id: 38 + protocol_id: 3 + ptr: 13 + timestamp: 2022-01-25T16:45:09Z + value: '{"int":"5"}' +- contract: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + id: 17 + key: '{"bytes":"0002e0269b29d74638e31dbc79dd118347060252a3b1"}' + key_hash: expru3EJD6S8yuMv2fGiviQpmC5JKLcJP8LXjGvRMkTAcudCGkj5df + level: 33 + operation_id: 38 + protocol_id: 3 + ptr: 13 + timestamp: 2022-01-25T16:45:09Z + value: '{"int":"2"}' +- contract: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + id: 18 + key: '{"prim":"Pair","args":[{"bytes":"0002d320e7a6c88ad303246f7bd1e75df9a2dc1a2bb9"},{"bytes":"00020c2dee271eb9b0d774a3fdc68305efb37527fb14"}]}' + key_hash: exprugVF5LMB4DiUqs8PZnNH21ehzpTH76SJQnB4AqKZQeoGprxR53 + level: 33 + operation_id: 39 + protocol_id: 3 + ptr: 19 + timestamp: 2022-01-25T16:45:09Z + value: '{"prim":"Unit"}' +- contract: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + id: 19 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 33 + operation_id: 39 + protocol_id: 3 + ptr: 18 + timestamp: 2022-01-25T16:45:09Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d6d657461646174612e6a736f6e"}' +- contract: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + id: 20 + key: '{"bytes":"00020c2dee271eb9b0d774a3fdc68305efb37527fb14"}' + key_hash: exprujRoiGDdzgNck93Ua9SyM4hsaSw4pxXQ1VMK3j4GC6eto8vD7h + level: 33 + operation_id: 39 + protocol_id: 3 + ptr: 17 + timestamp: 2022-01-25T16:45:09Z + value: '{"int":"2"}' +- contract: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + id: 21 + key: '{"bytes":"0002d320e7a6c88ad303246f7bd1e75df9a2dc1a2bb9"}' + key_hash: exprudH4HFTWyVqUpEkyt31LTQsRrphxXKHFGyk7KEanm8KE4gGV98 + level: 33 + operation_id: 39 + protocol_id: 3 + ptr: 17 + timestamp: 2022-01-25T16:45:09Z + value: '{"int":"5"}' +- contract: KT1L6qnSbi7gCqbwKzGBqzbepxHNC5zR9Egj + id: 22 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 34 + operation_id: 43 + protocol_id: 3 + ptr: 21 + timestamp: 2022-01-25T16:47:37Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f7461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1QyWsqRDsucjbjYvDa3Yr122oecdu3DEiC + id: 23 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 34 + operation_id: 44 + protocol_id: 3 + ptr: 22 + timestamp: 2022-01-25T16:47:37Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f7461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1BNS3XGWDJM2Yghm3CYosKStE9reNscbfE + id: 24 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 34 + operation_id: 45 + protocol_id: 3 + ptr: 23 + timestamp: 2022-01-25T16:47:37Z + value: '{"bytes":"7368613235363a2f2f3078376539396563663361343439306533303434636364663331393839386437373338306132666332306161653336623665343033323764363738333939643137622f68747470733a25324625324673746f726167652e676f6f676c65617069732e636f6d253246747a69702d31362532467461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + id: 25 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + level: 34 + operation_id: 47 + protocol_id: 3 + ptr: 27 + timestamp: 2022-01-25T16:47:37Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":"name"},{"bytes":"496e76616c696420746f6b656e206d65746164617461"}]}],{"int":"20000"}]}' +- contract: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + id: 26 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 34 + operation_id: 47 + protocol_id: 3 + ptr: 27 + timestamp: 2022-01-25T16:47:37Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"30"}]},{"prim":"Elt","args":[{"string":"extra"},{"bytes":"416464206d6f72652064617461"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"416c696365546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"414c43"}]}],{"int":"20000"}]}' +- contract: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + id: 27 + key: '{"int":"0"}' + key_hash: exprtZBwZUeYYYfUs9B9Rg2ywHezVHnCCnmF9WsDQVrs582dSK63dC + level: 34 + operation_id: 47 + protocol_id: 3 + ptr: 27 + timestamp: 2022-01-25T16:47:37Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":""},{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f746f6b656e2d6d657461646174612e6a736f6e"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"4e616d652066726f6d20555249206973207072696f726974697a656421"}]}],{"int":"20000"}]}' +- contract: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + id: 28 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 34 + operation_id: 47 + protocol_id: 3 + ptr: 25 + timestamp: 2022-01-25T16:47:37Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d76696577732e6a736f6e"}' +- contract: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + id: 29 + key: '{"prim":"Pair","args":[{"bytes":"0002b76f65564daa6ac08a05d3a6f85f0c03369e41f2"},{"int":"1"}]}' + key_hash: exprvEtXmAStEn985nAkpPZWZjyKT1NLrmEk7frzoR27hm5fSMDfkr + level: 34 + operation_id: 47 + protocol_id: 3 + ptr: 24 + timestamp: 2022-01-25T16:47:37Z + value: '{"int":"20000"}' +- contract: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + id: 30 + key: '{"prim":"Pair","args":[{"bytes":"0002a5d55c090517bd98e04f18b46aa6a61b843fbd66"},{"int":"0"}]}' + key_hash: expruFJGEr7TdvRMvNYP22w6Rhf1WUztrx2nvxMU3wJsrZpxKKrNCZ + level: 34 + operation_id: 47 + protocol_id: 3 + ptr: 24 + timestamp: 2022-01-25T16:47:37Z + value: '{"int":"20000"}' +- contract: KT1Gv5StW6rsCfuMW8kXN6XcZbbnxJP1SjKs + id: 31 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + level: 34 + operation_id: 48 + protocol_id: 3 + ptr: 28 + timestamp: 2022-01-25T16:47:37Z + value: '{"bytes":"7b226465736372697074696f6e223a225468697320636f6e747261637420686173206120636f75706c65206f66206f66662d636861696e2d76696577732e222c226c6963656e7365223a7b226e616d65223a224d4954222c2264657461696c73223a22546865204d4954204c6963656e7365227d2c22736f75726365223a7b22746f6f6c73223a5b22545a436f6d6574225d2c226c6f636174696f6e223a2268747470733a2f2f6769746875622e636f6d2f747174657a6f732f545a436f6d6574227d2c226572726f7273223a5b7b226572726f72223a7b22696e74223a223432227d2c22657870616e73696f6e223a7b22737472696e67223a2248656c6c6f2049276d206572726f72203432227d7d2c7b226572726f72223a7b22696e74223a223432227d2c22657870616e73696f6e223a7b226279746573223a2237313735363536633731373536353230363336383666373336353230366532373631323037303631373332303664363137323633363863336139227d2c226c616e677561676573223a5b226672225d7d2c7b2276696577223a22646f65732d6e6f742d6578697374227d2c7b2276696577223a226d756c7469706c792d7468652d6e61742d696e2d73746f72616765222c226c616e677561676573223a5b5d7d5d2c227669657773223a5b7b226e616d65223a22616e2d656d7074792d7573656c6573732d76696577222c226465736372697074696f6e223a2254686973207669657720686173206e6f20696d706c656d656e746174696f6e73c2a0e280a65c6e5c6e576869636820697320696e64656564207573656c6573732e222c22696d706c656d656e746174696f6e73223a5b5d7d2c7b226e616d65223a226d756c7469706c792d6e656761746976652d6e756d6265722d6f722d63616c6c2d6661696c77697468222c22696d706c656d656e746174696f6e73223a5b7b226d696368656c736f6e53746f7261676556696577223a7b22706172616d65746572223a7b227072696d223a22696e74222c2261726773223a5b5d2c22616e6e6f7473223a5b22257468655f64656369736976655f617267756d656e74225d7d2c2272657475726e54797065223a7b227072696d223a22696e74222c2261726773223a5b5d2c22616e6e6f7473223a5b22256e656761746976655f6576656e5f6e756d626572225d7d2c22636f6465223a5b7b227072696d223a22434152222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250555348222c2261726773223a5b7b227072696d223a22696e74222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b22696e74223a2230227d5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22434f4d50415245222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a224c54222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a224946222c2261726773223a5b5b7b227072696d223a224641494c57495448222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d5d2c5b7b227072696d223a2250555348222c2261726773223a5b7b227072696d223a22696e74222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b22696e74223a2232227d5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a224d554c222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d5d5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f746174696f6e73223a5b7b226e616d65223a22257468655f64656369736976655f617267756d656e74222c226465736372697074696f6e223a2254686520696e746567657220617267756d656e74206966203e3020746869732077696c6c206661696c2e227d2c7b226e616d65223a22256e656761746976655f6576656e5f6e756d626572222c226465736372697074696f6e223a2254686520726573756c742c20696620616e792c2069732074776963652074686520617267756d656e742028257468655f64656369736976655f617267756d656e74292e227d5d7d7d5d7d2c7b2270757265223a747275652c226e616d65223a226d756c7469706c792d7468652d6e61742d696e2d73746f72616765222c226465736372697074696f6e223a2254686973206f6e6520697320707572652c206974206d756c7469706c69657320746865206e61747572616c206e756d62657220676976656e20617320617267756d656e74207769746820746865206f6e6520696e2073746f726167652e222c22696d706c656d656e746174696f6e73223a5b7b226d696368656c736f6e53746f7261676556696577223a7b22706172616d65746572223a7b227072696d223a226e6174222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c2272657475726e54797065223a7b227072696d223a226e6174222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c22636f6465223a5b7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22434452222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22434152222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2253574150222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22434152222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a224d554c222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d5d7d7d5d7d2c7b226e616d65223a226a7573742d63616c6c2d62616c616e6365222c22696d706c656d656e746174696f6e73223a5b7b226d696368656c736f6e53746f7261676556696577223a7b2272657475726e54797065223a7b227072696d223a226d7574657a222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c22636f6465223a5b7b227072696d223a2244524f50222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2242414c414e4345222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d5d7d7d5d7d2c7b226e616d65223a227468652d6964656e74697479222c22696d706c656d656e746174696f6e73223a5b7b226d696368656c736f6e53746f7261676556696577223a7b22706172616d65746572223a7b227072696d223a2270616972222c2261726773223a5b7b227072696d223a226e6174222c2261726773223a5b5d2c22616e6e6f7473223a5b22256172675f7a65726f225d7d2c7b227072696d223a2270616972222c2261726773223a5b7b227072696d223a22737472696e67222c2261726773223a5b5d2c22616e6e6f7473223a5b22256172675f6f6e65225d7d2c7b227072696d223a226d7574657a222c2261726773223a5b5d2c22616e6e6f7473223a5b22256172675f74776f225d7d5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f7473223a5b5d7d2c2272657475726e54797065223a7b227072696d223a2270616972222c2261726773223a5b7b227072696d223a226e6174222c2261726773223a5b5d2c22616e6e6f7473223a5b22256172675f7a65726f225d7d2c7b227072696d223a2270616972222c2261726773223a5b7b227072696d223a22737472696e67222c2261726773223a5b5d2c22616e6e6f7473223a5b22256172675f6f6e655f726573756c74225d7d2c7b227072696d223a226d7574657a222c2261726773223a5b5d2c22616e6e6f7473223a5b22256172675f74776f225d7d5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f7473223a5b5d7d2c22636f6465223a5b7b227072696d223a22434152222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f746174696f6e73223a5b7b226e616d65223a22256172675f7a65726f222c226465736372697074696f6e223a2254686973206973206f6276696f756c73792069676e6f7265642e227d2c7b226e616d65223a22256172675f6f6e65222c226465736372697074696f6e223a225468697320697320616c736f2069676e6f7265642c2062757420646966666572656e742e227d2c7b226e616d65223a22256172675f6f6e655f726573756c74222c226465736372697074696f6e223a225468697320697320256172675f6f6e65206f6e2074686520726573756c74696e6720736964652e227d2c7b226e616d65223a22256172675f74776f222c226465736372697074696f6e223a225468697320697320616c736f2069676e6f7265642c2062757420776974682061206c6f74206f6620646174615c6e5c6e4c6f72656d20697073756d696e6720616e6420616c6c2e227d5d7d7d5d7d2c7b226e616d65223a22616e2d656d7074792d7573656c6573732d76696577222c226465736372697074696f6e223a225468697320766965772068617320612062756e6368206f6620696d706c656d656e746174696f6e73c2a0e280a65c6e5c6e546865792061726520616c6c206d65616e696e676c6573732e222c22696d706c656d656e746174696f6e73223a5b7b226d696368656c736f6e53746f7261676556696577223a7b2272657475726e54797065223a7b227072696d223a226e6174222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c22636f6465223a5b7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22444950222c2261726773223a5b7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f7473223a5b5d7d5d7d7d2c7b226d696368656c736f6e53746f7261676556696577223a7b2272657475726e54797065223a7b227072696d223a226e6174222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c22636f6465223a5b7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22445550222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22444950222c2261726773223a5b7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a22444950222c2261726773223a5b7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2250414952222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f7473223a5b5d7d5d7d7d5d7d2c7b226e616d65223a226765742d636f6e74726163742d61646472657373222c22696d706c656d656e746174696f6e73223a5b7b226d696368656c736f6e53746f7261676556696577223a7b2272657475726e54797065223a7b227072696d223a2261646472657373222c2261726773223a5b5d2c22616e6e6f7473223a5b2225726574225d7d2c22636f6465223a5b7b227072696d223a2244524f50222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2253454c46222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d2c7b227072696d223a2241444452455353222c2261726773223a5b5d2c22616e6e6f7473223a5b5d7d5d2c22616e6e6f746174696f6e73223a5b7b226e616d65223a2225726574222c226465736372697074696f6e223a225468652061646472657373206f66207468652028616e792920636f6e74726163742c2072652d6f627461696e656420696e204d696368656c736f6e2e227d5d7d7d5d7d5d7d"}' +- contract: KT1Gv5StW6rsCfuMW8kXN6XcZbbnxJP1SjKs + id: 32 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 34 + operation_id: 48 + protocol_id: 3 + ptr: 28 + timestamp: 2022-01-25T16:47:37Z + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1XKhK1QZWLrLntWhaDpaqEkuR57CYuWKk3 + id: 33 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 35 + operation_id: 54 + protocol_id: 3 + ptr: 29 + timestamp: 2022-01-25T16:49:57Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d6f6a692d696e2d6d657461646174612e6a736f6e"}' +- contract: KT1H59QHJgqmiZ2Cfvw3MUUaPFxjWcowFVhY + id: 34 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 35 + operation_id: 55 + protocol_id: 3 + ptr: 30 + timestamp: 2022-01-25T16:49:57Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d6f6a692d696e2d6d657461646174612e6a736f6e"}' +- contract: KT1BZJFEifWnscmwTPQonMufy7WZGKvzVhza + id: 35 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 35 + operation_id: 56 + protocol_id: 3 + ptr: 31 + timestamp: 2022-01-25T16:49:57Z + value: '{"bytes":"7368613235363a2f2f3078376539396563663361343439316533303434636364663331393839386437373338306132666332306161653336623665343033323764363738333939643137622f68747470733a25324625324673746f726167652e676f6f676c65617069732e636f6d253246747a69702d31362532467461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1S1k4CKmLn6Bz95NT6HmeRzzJwaaRyCY7Q + id: 36 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 36 + operation_id: 61 + protocol_id: 3 + ptr: 32 + timestamp: 2022-01-25T16:52:19Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f696e76616c69642e6a736f6e"}' +- contract: KT1MpEYtKWzgmpjFxryKvBC3dMuvD64Bt7pv + id: 37 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 36 + operation_id: 62 + protocol_id: 3 + ptr: 33 + timestamp: 2022-01-25T16:52:19Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f696e76616c69642e6a736f6e"}' +- contract: KT1F6hdHeL6ceJtKHGnWj397SMqP4x4v3Mas + id: 38 + key: '{"bytes":"000081baf62ceef1633b95fef5d4908f15980e3c0a55"}' + key_hash: expruve3btzDkgS37mbEt6Q6D4CcRxUiwRPs3gyx2MmeaFsX3fLT6V + level: 36 + operation_id: 63 + protocol_id: 3 + ptr: 34 + timestamp: 2022-01-25T16:52:19Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1F6hdHeL6ceJtKHGnWj397SMqP4x4v3Mas + id: 39 + key: '{"bytes":"0000b3927e0567be9d769cbfc67ede18a1f040115136"}' + key_hash: exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX + level: 36 + operation_id: 63 + protocol_id: 3 + ptr: 34 + timestamp: 2022-01-25T16:52:19Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1RPs9iqAj4rRDyecoDz6RqhF2dVfRtWi78 + id: 40 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + level: 37 + operation_id: 70 + protocol_id: 3 + ptr: 35 + timestamp: 2022-01-25T16:54:35Z + value: '{"bytes":"7b226e616d65223a2274657374222c226465736372697074696f6e223a2241206d657461646174612074657374222c2276657273696f6e223a22302e31222c226c6963656e7365223a224d4954222c22617574686f7273223a5b225461717569746f203c68747470733a2f2f74657a6f737461717569746f2e696f2f3e225d2c22686f6d6570616765223a2268747470733a2f2f74657a6f737461717569746f2e696f2f227d"}' +- contract: KT1RPs9iqAj4rRDyecoDz6RqhF2dVfRtWi78 + id: 41 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 37 + operation_id: 70 + protocol_id: 3 + ptr: 35 + timestamp: 2022-01-25T16:54:35Z + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1LBiP4VgzuV9BV62wHiGhetE6saTbs4XSk + id: 42 + key: '{"bytes":"000081baf62ceef1633b95fef5d4908f15980e3c0a55"}' + key_hash: expruve3btzDkgS37mbEt6Q6D4CcRxUiwRPs3gyx2MmeaFsX3fLT6V + level: 37 + operation_id: 71 + protocol_id: 3 + ptr: 36 + timestamp: 2022-01-25T16:54:35Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1LBiP4VgzuV9BV62wHiGhetE6saTbs4XSk + id: 43 + key: '{"bytes":"0000b3927e0567be9d769cbfc67ede18a1f040115136"}' + key_hash: exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX + level: 37 + operation_id: 71 + protocol_id: 3 + ptr: 36 + timestamp: 2022-01-25T16:54:35Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1WfndvipjhvmJ7XoHTHJYDvTncPkgdEGWm + id: 44 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 38 + operation_id: 78 + protocol_id: 3 + ptr: 37 + timestamp: 2022-01-25T16:56:47Z + value: '{"bytes":"74657a6f732d73746f726167653a2f2f4b5431525073396971416a347252447965636f447a3652716846326456665274576937382f68657265"}' +- contract: KT1MXcocFTwXV2emtgHAC7tCUt4Zc3EPPZAE + id: 45 + key: '{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"}' + key_hash: exprvEVwRjW3or3tGBSmpyXeqxzzp6XSJGRiKdxV5W1m4s5CceC83b + level: 38 + operation_id: 79 + protocol_id: 3 + ptr: 38 + timestamp: 2022-01-25T16:56:47Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"prim":"Pair","args":[{"int":"50"},{"prim":"True"}]}]}' +- contract: KT1MXcocFTwXV2emtgHAC7tCUt4Zc3EPPZAE + id: 46 + key: '{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"}' + key_hash: expruzjfAwk3HCHuixaChF3Jdja7VghEFjtrz1qow3UuY4rdCRD1GH + level: 38 + operation_id: 79 + protocol_id: 3 + ptr: 38 + timestamp: 2022-01-25T16:56:47Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"prim":"Pair","args":[{"int":"50"},{"prim":"True"}]}]}' +- contract: KT1EcQVhDC7izqW3uiGVrqbus6qBt78btyHv + id: 47 + key: '{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"}' + key_hash: exprvEVwRjW3or3tGBSmpyXeqxzzp6XSJGRiKdxV5W1m4s5CceC83b + level: 39 + operation_id: 96 + protocol_id: 3 + ptr: 39 + timestamp: 2022-01-25T16:59:07Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"prim":"Pair","args":[{"int":"50"},{"prim":"True"}]}]}' +- contract: KT1EcQVhDC7izqW3uiGVrqbus6qBt78btyHv + id: 48 + key: '{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"}' + key_hash: expruzjfAwk3HCHuixaChF3Jdja7VghEFjtrz1qow3UuY4rdCRD1GH + level: 39 + operation_id: 96 + protocol_id: 3 + ptr: 39 + timestamp: 2022-01-25T16:59:07Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"prim":"Pair","args":[{"int":"50"},{"prim":"True"}]}]}' +- contract: KT1FQE7EtHEkmDTw5iRoUgeveVW6PiPUH9pC + id: 49 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + level: 40 + operation_id: 107 + protocol_id: 3 + ptr: 40 + timestamp: 2022-01-25T17:01:51Z + value: '{"bytes":"7b226e616d65223a2274657374222c226465736372697074696f6e223a2241206d657461646174612074657374222c2276657273696f6e223a22302e31222c226c6963656e7365223a224d4954222c22617574686f7273223a5b225461717569746f203c68747470733a2f2f74657a6f737461717569746f2e696f2f3e225d2c22686f6d6570616765223a2268747470733a2f2f74657a6f737461717569746f2e696f2f227d"}' +- contract: KT1FQE7EtHEkmDTw5iRoUgeveVW6PiPUH9pC + id: 50 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 40 + operation_id: 107 + protocol_id: 3 + ptr: 40 + timestamp: 2022-01-25T17:01:51Z + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1 + id: 51 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 40 + operation_id: 109 + protocol_id: 3 + ptr: 42 + timestamp: 2022-01-25T17:01:51Z + value: '[{"int":"1"},{"string":"world"},{"string":"test2"},{"int":"0"},[]]' +- contract: KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1 + id: 52 + key: '{"int":"0"}' + key_hash: exprtZBwZUeYYYfUs9B9Rg2ywHezVHnCCnmF9WsDQVrs582dSK63dC + level: 40 + operation_id: 109 + protocol_id: 3 + ptr: 42 + timestamp: 2022-01-25T17:01:51Z + value: '[{"int":"0"},{"string":"hello"},{"string":"test"},{"int":"0"},[]]' +- contract: KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1 + id: 53 + key: '{"bytes":"000081baf62ceef1633b95fef5d4908f15980e3c0a55"}' + key_hash: expruve3btzDkgS37mbEt6Q6D4CcRxUiwRPs3gyx2MmeaFsX3fLT6V + level: 40 + operation_id: 109 + protocol_id: 3 + ptr: 41 + timestamp: 2022-01-25T17:01:51Z + value: '{"prim":"Pair","args":[[{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"}],{"int":"50"}]}' +- contract: KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1 + id: 54 + key: '{"bytes":"0000b3927e0567be9d769cbfc67ede18a1f040115136"}' + key_hash: exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX + level: 40 + operation_id: 109 + protocol_id: 3 + ptr: 41 + timestamp: 2022-01-25T17:01:51Z + value: '{"prim":"Pair","args":[[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"}],{"int":"50"}]}' +- contract: KT1SryiY3YiHrtfth14JDWAP83W2WbSo1y6o + id: 55 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 41 + operation_id: 119 + protocol_id: 3 + ptr: 43 + timestamp: 2022-01-25T17:04:35Z + value: '{"bytes":"74657a6f732d73746f726167653a2f2f4b543146514537457448456b6d4454773569526f556765766556573650695055483970432f68657265"}' +- contract: KT1RhyRG4etPssUovWHapMsfDbQqwPGAHHuc + id: 56 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 41 + operation_id: 120 + protocol_id: 3 + ptr: 44 + timestamp: 2022-01-25T17:04:35Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d7074792d6d657461646174612e6a736f6e"}' +- contract: KT1D5LEDRjTeG4HcGyKKfnschdS3nTJEbqx7 + id: 57 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 41 + operation_id: 121 + protocol_id: 3 + ptr: 45 + timestamp: 2022-01-25T17:04:35Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d7074792d6d657461646174612e6a736f6e"}' +- contract: KT1Lgy1eDiJpiZ3NZZXEz4i5MVSy4wG9g9c8 + id: 58 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 41 + operation_id: 124 + protocol_id: 3 + ptr: 47 + timestamp: 2022-01-25T17:04:35Z + value: '[{"int":"1"},{"string":"world"},{"string":"test2"},{"int":"0"},[]]' +- contract: KT1Lgy1eDiJpiZ3NZZXEz4i5MVSy4wG9g9c8 + id: 59 + key: '{"int":"0"}' + key_hash: exprtZBwZUeYYYfUs9B9Rg2ywHezVHnCCnmF9WsDQVrs582dSK63dC + level: 41 + operation_id: 124 + protocol_id: 3 + ptr: 47 + timestamp: 2022-01-25T17:04:35Z + value: '[{"int":"0"},{"string":"hello"},{"string":"test"},{"int":"0"},[]]' +- contract: KT1Lgy1eDiJpiZ3NZZXEz4i5MVSy4wG9g9c8 + id: 60 + key: '{"bytes":"000081baf62ceef1633b95fef5d4908f15980e3c0a55"}' + key_hash: expruve3btzDkgS37mbEt6Q6D4CcRxUiwRPs3gyx2MmeaFsX3fLT6V + level: 41 + operation_id: 124 + protocol_id: 3 + ptr: 46 + timestamp: 2022-01-25T17:04:35Z + value: '{"prim":"Pair","args":[[{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"}],{"int":"50"}]}' +- contract: KT1Lgy1eDiJpiZ3NZZXEz4i5MVSy4wG9g9c8 + id: 61 + key: '{"bytes":"0000b3927e0567be9d769cbfc67ede18a1f040115136"}' + key_hash: exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX + level: 41 + operation_id: 124 + protocol_id: 3 + ptr: 46 + timestamp: 2022-01-25T17:04:35Z + value: '{"prim":"Pair","args":[[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"}],{"int":"50"}]}' +- contract: KT1R9BdHMfGTwKnbCHii8akcB7DqzfdnD9AD + id: 62 + key: '{"bytes":"00022165a26786121eff8203bed56ffaf85d6bb25e42"}' + key_hash: exprv5VFJ5n3TWvuA7eR1Z5FqLvwoynr4sy9sjL9MsBww2f4LpfaC9 + level: 41 + operation_id: 125 + protocol_id: 3 + ptr: -1 + timestamp: 2022-01-25T17:04:35Z + value: '{"prim":"Pair","args":[{"int":"2"},[]]}' +- contract: KT1R9BdHMfGTwKnbCHii8akcB7DqzfdnD9AD + id: 63 + key: '{"bytes":"00012ffebbf1560632ca767bc960ccdb84669d284c2c"}' + key_hash: expruTQ93tbn1ZXLFCL1UwUjFXxBo1M3vyiCmnYWQN66Upv2oDfXrN + level: 41 + operation_id: 125 + protocol_id: 3 + ptr: -1 + timestamp: 2022-01-25T17:04:35Z + value: '{"prim":"Pair","args":[{"int":"3"},[]]}' +- contract: KT1R9BdHMfGTwKnbCHii8akcB7DqzfdnD9AD + id: 64 + key: '{"bytes":"000288192929d5d89c8dfe0aafc95a80398bcd6dfef8"}' + key_hash: exprtzcGNDTzKEnM8qMgD38ZJH6kQSoHcowPDj19y5CfvmwsXWVNF6 + level: 41 + operation_id: 125 + protocol_id: 3 + ptr: -1 + timestamp: 2022-01-25T17:04:35Z + value: '{"prim":"Pair","args":[{"int":"4"},[]]}' +- contract: KT1R9BdHMfGTwKnbCHii8akcB7DqzfdnD9AD + id: 65 + key: '{"bytes":"0001754887431181a33bef2bf9989e67f8700268ec77"}' + key_hash: exprtiGf7yyfTbdfv4Qmw5CVLs6JFwPrUBNLxK3bt3uZwrvJFGx3pT + level: 41 + operation_id: 125 + protocol_id: 3 + ptr: -1 + timestamp: 2022-01-25T17:04:35Z + value: '{"prim":"Pair","args":[{"int":"1"},[]]}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + id: 66 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + level: 41 + operation_id: 126 + protocol_id: 3 + ptr: 54 + timestamp: 2022-01-25T17:04:35Z + value: '{"int":"10000000"}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + id: 67 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 41 + operation_id: 126 + protocol_id: 3 + ptr: 54 + timestamp: 2022-01-25T17:04:35Z + value: '{"int":"54000000"}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + id: 68 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + level: 41 + operation_id: 126 + protocol_id: 3 + ptr: 53 + timestamp: 2022-01-25T17:04:35Z + value: '{"prim":"Pair","args":[{"int":"2"},[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"30"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"416c696365546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"414c43"}]}]]}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + id: 69 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 41 + operation_id: 126 + protocol_id: 3 + ptr: 53 + timestamp: 2022-01-25T17:04:35Z + value: '{"prim":"Pair","args":[{"int":"1"},[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"36"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"77546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"77544b"}]}]]}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + id: 70 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + level: 41 + operation_id: 126 + protocol_id: 3 + ptr: 52 + timestamp: 2022-01-25T17:04:35Z + value: '{"prim":"Pair","args":[{"bytes":"00021b614ccc67da1f2f9b569260f8c54e86b479a99f"},{"prim":"True"}]}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + id: 71 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 41 + operation_id: 126 + protocol_id: 3 + ptr: 52 + timestamp: 2022-01-25T17:04:35Z + value: '{"prim":"Pair","args":[{"bytes":"0002f8b64c2fc9b122c4c66525f461a4453d1835f99d"},{"prim":"True"}]}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + id: 72 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 41 + operation_id: 126 + protocol_id: 3 + ptr: 50 + timestamp: 2022-01-25T17:04:35Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d746f6b656e2d666163746f72792e6a736f6e"}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + id: 73 + key: '{"prim":"Pair","args":[{"bytes":"0002f8b64c2fc9b122c4c66525f461a4453d1835f99d"},{"int":"1"}]}' + key_hash: exprvJwEJXcvrQjMxa8fEFgrDLS6zy6BTfp8uwuAmeAMEmc6NUEK7T + level: 41 + operation_id: 126 + protocol_id: 3 + ptr: 49 + timestamp: 2022-01-25T17:04:35Z + value: '{"int":"18000000"}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + id: 74 + key: '{"prim":"Pair","args":[{"bytes":"00021b614ccc67da1f2f9b569260f8c54e86b479a99f"},{"int":"2"}]}' + key_hash: expru9H6FoqTCVubB6otu3sgcP7V26Ew7ffvDdaVKb9VAkmncTygfi + level: 41 + operation_id: 126 + protocol_id: 3 + ptr: 49 + timestamp: 2022-01-25T17:04:35Z + value: '{"int":"9990000"}' +- contract: KT1Dd1HZSwbikboLRzurVg5z6rfTVziusdUt + id: 75 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + level: 41 + operation_id: 127 + protocol_id: 3 + ptr: 55 + timestamp: 2022-01-25T17:04:35Z + value: '{"bytes":"7b7d"}' +- contract: KT1Dd1HZSwbikboLRzurVg5z6rfTVziusdUt + id: 76 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 41 + operation_id: 127 + protocol_id: 3 + ptr: 55 + timestamp: 2022-01-25T17:04:35Z + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1TSsjjzoGbWLMgUwdDUw33CLz34sQs5jYX + id: 77 + key: '{"prim":"Pair","args":[{"bytes":"0002ca6e1d3ef54a05bddfef5fbe17d09786865e89be"},{"bytes":"0002ead21e7f311ca2411c73388ff0e843f9602f4909"}]}' + key_hash: exprvJvHXN9x7wUYxwLNK2oqUqzB5JQLnXpQafsyaWoynG6aHvY8qc + level: 41 + operation_id: 128 + protocol_id: 3 + ptr: 58 + timestamp: 2022-01-25T17:04:35Z + value: '{"prim":"Unit"}' +- contract: KT1TSsjjzoGbWLMgUwdDUw33CLz34sQs5jYX + id: 78 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 41 + operation_id: 128 + protocol_id: 3 + ptr: 57 + timestamp: 2022-01-25T17:04:35Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d6d657461646174612e6a736f6e"}' +- contract: KT1TSsjjzoGbWLMgUwdDUw33CLz34sQs5jYX + id: 79 + key: '{"bytes":"0002ead21e7f311ca2411c73388ff0e843f9602f4909"}' + key_hash: exprvCSQSQV4EAqbzVWVzbzdke38trBtBbGq4cPU94a115cqMedUke + level: 41 + operation_id: 128 + protocol_id: 3 + ptr: 56 + timestamp: 2022-01-25T17:04:35Z + value: '{"int":"2"}' +- contract: KT1TSsjjzoGbWLMgUwdDUw33CLz34sQs5jYX + id: 80 + key: '{"bytes":"0002ca6e1d3ef54a05bddfef5fbe17d09786865e89be"}' + key_hash: expru2mgufqqavCvYBFZY3NfQbHkNv28LZCKxMDy4ESeS3cKLzFVNR + level: 41 + operation_id: 128 + protocol_id: 3 + ptr: 56 + timestamp: 2022-01-25T17:04:35Z + value: '{"int":"5"}' +- contract: KT1RrexTzK8S2ecKsDZLB6BKMKUP1vVmg9Hh + id: 81 + key: '{"prim":"Pair","args":[{"bytes":"00021250b15c68a16f8efd59e879afbc89efb79921b7"},{"bytes":"00024850381eb4e9704d42218b1a00b5730a4225a18f"}]}' + key_hash: expruyKeUtiHeCBtsus6P397wL21s8KvChXrKeM1XVbEjMpwKn4s4Y + level: 41 + operation_id: 129 + protocol_id: 3 + ptr: 62 + timestamp: 2022-01-25T17:04:35Z + value: '{"prim":"Unit"}' +- contract: KT1RrexTzK8S2ecKsDZLB6BKMKUP1vVmg9Hh + id: 82 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 41 + operation_id: 129 + protocol_id: 3 + ptr: 61 + timestamp: 2022-01-25T17:04:35Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d6d657461646174612e6a736f6e"}' +- contract: KT1RrexTzK8S2ecKsDZLB6BKMKUP1vVmg9Hh + id: 83 + key: '{"bytes":"00024850381eb4e9704d42218b1a00b5730a4225a18f"}' + key_hash: exprvPWmUvWbb76ZtF4LkkiHJ3Jtp3qQasscFuBWZmf9pEL5w9keU6 + level: 41 + operation_id: 129 + protocol_id: 3 + ptr: 60 + timestamp: 2022-01-25T17:04:35Z + value: '{"int":"2"}' +- contract: KT1RrexTzK8S2ecKsDZLB6BKMKUP1vVmg9Hh + id: 84 + key: '{"bytes":"00021250b15c68a16f8efd59e879afbc89efb79921b7"}' + key_hash: expruiuSzuwvXug1tHisFzFaUBaKzuevtWtMtXRm764MCAERqXQ3Er + level: 41 + operation_id: 129 + protocol_id: 3 + ptr: 60 + timestamp: 2022-01-25T17:04:35Z + value: '{"int":"5"}' +- contract: KT18dyvjdq4gFuQuG1CnNZfd35Jk2UbiKcPB + id: 85 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 42 + operation_id: 136 + protocol_id: 3 + ptr: 64 + timestamp: 2022-01-25T17:07:03Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f7461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1UJ5bYnGpkwZLTJpa2cUXUX3dz8St8qxNn + id: 86 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 42 + operation_id: 137 + protocol_id: 3 + ptr: 65 + timestamp: 2022-01-25T17:07:03Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f7461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1Sd3BSdF5VKiU1oe6VqYifGe6TfqbkDDGZ + id: 87 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 42 + operation_id: 138 + protocol_id: 3 + ptr: 66 + timestamp: 2022-01-25T17:07:03Z + value: '{"bytes":"7368613235363a2f2f3078376539396563663361343439306533303434636364663331393839386437373338306132666332306161653336623665343033323764363738333939643137622f68747470733a25324625324673746f726167652e676f6f676c65617069732e636f6d253246747a69702d31362532467461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + id: 88 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + level: 42 + operation_id: 140 + protocol_id: 3 + ptr: 70 + timestamp: 2022-01-25T17:07:03Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":"name"},{"bytes":"496e76616c696420746f6b656e206d65746164617461"}]}],{"int":"20000"}]}' +- contract: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + id: 89 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 42 + operation_id: 140 + protocol_id: 3 + ptr: 70 + timestamp: 2022-01-25T17:07:03Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"30"}]},{"prim":"Elt","args":[{"string":"extra"},{"bytes":"416464206d6f72652064617461"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"416c696365546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"414c43"}]}],{"int":"20000"}]}' +- contract: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + id: 90 + key: '{"int":"0"}' + key_hash: exprtZBwZUeYYYfUs9B9Rg2ywHezVHnCCnmF9WsDQVrs582dSK63dC + level: 42 + operation_id: 140 + protocol_id: 3 + ptr: 70 + timestamp: 2022-01-25T17:07:03Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":""},{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f746f6b656e2d6d657461646174612e6a736f6e"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"4e616d652066726f6d20555249206973207072696f726974697a656421"}]}],{"int":"20000"}]}' +- contract: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + id: 91 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 42 + operation_id: 140 + protocol_id: 3 + ptr: 68 + timestamp: 2022-01-25T17:07:03Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d76696577732e6a736f6e"}' +- contract: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + id: 92 + key: '{"prim":"Pair","args":[{"bytes":"0002229ac298406cfffb889cf71779fc94b72d96293d"},{"int":"1"}]}' + key_hash: exprujSJMkRG4GSarzGN5vy9uFsgyRpLc6d3DdDpygZQHFJjHntCDd + level: 42 + operation_id: 140 + protocol_id: 3 + ptr: 67 + timestamp: 2022-01-25T17:07:03Z + value: '{"int":"20000"}' +- contract: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + id: 93 + key: '{"prim":"Pair","args":[{"bytes":"00022546581143cd99b47b60ee767874d30f2731cbaa"},{"int":"0"}]}' + key_hash: expruGTgtiQGef74HBKTdPG4ZsES9oJo82V3924iA2hv2fbh8GpbRg + level: 42 + operation_id: 140 + protocol_id: 3 + ptr: 67 + timestamp: 2022-01-25T17:07:03Z + value: '{"int":"20000"}' +- contract: KT18jPdN1UAFvXppPh41PS5xZP3Xx7F6s91D + id: 94 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + level: 42 + operation_id: 141 + protocol_id: 3 + ptr: 71 + timestamp: 2022-01-25T17:07:03Z + value: '{"bytes":"7b7d"}' +- contract: KT18jPdN1UAFvXppPh41PS5xZP3Xx7F6s91D + id: 95 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 42 + operation_id: 141 + protocol_id: 3 + ptr: 71 + timestamp: 2022-01-25T17:07:03Z + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1SGb8wy8CPTWBTMYipFv5rDTBQnuyceL4Z + id: 96 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 43 + operation_id: 147 + protocol_id: 3 + ptr: 72 + timestamp: 2022-01-25T17:09:21Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d6f6a692d696e2d6d657461646174612e6a736f6e"}' +- contract: KT1A1euYzsXoqoVq6CFss6ofWgfbfev97FxT + id: 97 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 43 + operation_id: 148 + protocol_id: 3 + ptr: 73 + timestamp: 2022-01-25T17:09:21Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d6f6a692d696e2d6d657461646174612e6a736f6e"}' +- contract: KT1UnZaX82rgUBvaj3iA8D3W7T2Zxe6kxTiQ + id: 98 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 43 + operation_id: 149 + protocol_id: 3 + ptr: 74 + timestamp: 2022-01-25T17:09:21Z + value: '{"bytes":"7368613235363a2f2f3078376539396563663361343439316533303434636364663331393839386437373338306132666332306161653336623665343033323764363738333939643137622f68747470733a25324625324673746f726167652e676f6f676c65617069732e636f6d253246747a69702d31362532467461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1NDZJknffhfNhh46unvGopGppVmTem1HBG + id: 99 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 44 + operation_id: 156 + protocol_id: 3 + ptr: 75 + timestamp: 2022-01-25T17:11:23Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f696e76616c69642e6a736f6e"}' +- contract: KT1PZ4Qb4Q9NywpLpJBufR5nVUDDSbjH2D6j + id: 100 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 44 + operation_id: 157 + protocol_id: 3 + ptr: 76 + timestamp: 2022-01-25T17:11:23Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f696e76616c69642e6a736f6e"}' +- contract: KT1TFRwXwt1xNd8bLDEnbvZLd446TzT163Bd + id: 101 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 44 + operation_id: 158 + protocol_id: 3 + ptr: 77 + timestamp: 2022-01-25T17:11:23Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d7074792d6d657461646174612e6a736f6e"}' +- contract: KT1957qBZ6Qto5oSvqSZqkyTsBPcXFr4J6KM + id: 102 + key: '{"bytes":"000081baf62ceef1633b95fef5d4908f15980e3c0a55"}' + key_hash: expruve3btzDkgS37mbEt6Q6D4CcRxUiwRPs3gyx2MmeaFsX3fLT6V + level: 44 + operation_id: 159 + protocol_id: 3 + ptr: 78 + timestamp: 2022-01-25T17:11:23Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1957qBZ6Qto5oSvqSZqkyTsBPcXFr4J6KM + id: 103 + key: '{"bytes":"0000b3927e0567be9d769cbfc67ede18a1f040115136"}' + key_hash: exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX + level: 44 + operation_id: 159 + protocol_id: 3 + ptr: 78 + timestamp: 2022-01-25T17:11:23Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1Q4KbVQZZiwgiQi5PWj7a8iVSeHvDLtrHd + id: 104 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + level: 44 + operation_id: 160 + protocol_id: 3 + ptr: 79 + timestamp: 2022-01-25T17:11:23Z + value: '{"bytes":"7b7d"}' +- contract: KT1Q4KbVQZZiwgiQi5PWj7a8iVSeHvDLtrHd + id: 105 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 44 + operation_id: 160 + protocol_id: 3 + ptr: 79 + timestamp: 2022-01-25T17:11:23Z + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1Gz8N3VwTriRD1VVPrrC5asYF2e1mPSDP9 + id: 106 + key: '{"prim":"Pair","args":[{"bytes":"00026e354627a6c2eb69386cd8def55ec3a0a4aa70eb"},{"bytes":"000265408e7ff3d4dcc3c0e746fa906fc2e5065f1aad"}]}' + key_hash: expruHwatDGtmpjcvu9GMnQTdKNCTBMDHfJuYqDELoLxCkk7DKJmwp + level: 44 + operation_id: 161 + protocol_id: 3 + ptr: 82 + timestamp: 2022-01-25T17:11:23Z + value: '{"prim":"Unit"}' +- contract: KT1Gz8N3VwTriRD1VVPrrC5asYF2e1mPSDP9 + id: 107 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 44 + operation_id: 161 + protocol_id: 3 + ptr: 81 + timestamp: 2022-01-25T17:11:23Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d6d657461646174612e6a736f6e"}' +- contract: KT1Gz8N3VwTriRD1VVPrrC5asYF2e1mPSDP9 + id: 108 + key: '{"bytes":"00026e354627a6c2eb69386cd8def55ec3a0a4aa70eb"}' + key_hash: expruWYcn3xKvCYtwHoBHvibssPzsK9NaWdfRfq2qa3gDEmwW33wfe + level: 44 + operation_id: 161 + protocol_id: 3 + ptr: 80 + timestamp: 2022-01-25T17:11:23Z + value: '{"int":"5"}' +- contract: KT1Gz8N3VwTriRD1VVPrrC5asYF2e1mPSDP9 + id: 109 + key: '{"bytes":"000265408e7ff3d4dcc3c0e746fa906fc2e5065f1aad"}' + key_hash: expru2BPn96x7ozLoDdPjNupAqwA6cpCdfBz6YaumDcxPDgsAy8amY + level: 44 + operation_id: 161 + protocol_id: 3 + ptr: 80 + timestamp: 2022-01-25T17:11:23Z + value: '{"int":"2"}' +- contract: KT1Tpdf4izXzLqafbQzcW1tfxfcH2ZU6ytVQ + id: 110 + key: '{"prim":"Pair","args":[{"bytes":"000239c6679d8012cb81f14d8bad681f7b13243d4ffa"},{"bytes":"0002e20225983377e005022c6686f7ff58fa44fc45c9"}]}' + key_hash: exprvM9C7iWDRH1WxKwpEKW4RuAAHxhX4SraxmuZsre6hpZwJCiMXu + level: 44 + operation_id: 162 + protocol_id: 3 + ptr: 86 + timestamp: 2022-01-25T17:11:23Z + value: '{"prim":"Unit"}' +- contract: KT1Tpdf4izXzLqafbQzcW1tfxfcH2ZU6ytVQ + id: 111 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 44 + operation_id: 162 + protocol_id: 3 + ptr: 85 + timestamp: 2022-01-25T17:11:23Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d6d657461646174612e6a736f6e"}' +- contract: KT1Tpdf4izXzLqafbQzcW1tfxfcH2ZU6ytVQ + id: 112 + key: '{"bytes":"000239c6679d8012cb81f14d8bad681f7b13243d4ffa"}' + key_hash: exprvSmjTtyqsdX5sZ2kUAKRRcQLNk79FT2oLPQ2nz5A2FHUvS2UxX + level: 44 + operation_id: 162 + protocol_id: 3 + ptr: 84 + timestamp: 2022-01-25T17:11:23Z + value: '{"int":"5"}' +- contract: KT1Tpdf4izXzLqafbQzcW1tfxfcH2ZU6ytVQ + id: 113 + key: '{"bytes":"0002e20225983377e005022c6686f7ff58fa44fc45c9"}' + key_hash: exprvRThuKxPh6zyi5MUdyYY5xkq1sxFU523KLQnPKCcPQr1hmNYWC + level: 44 + operation_id: 162 + protocol_id: 3 + ptr: 84 + timestamp: 2022-01-25T17:11:23Z + value: '{"int":"2"}' +- contract: KT1GCrzzHq2sHjNza1Q89JHHY8Xj2ASYqUJ7 + id: 114 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 45 + operation_id: 170 + protocol_id: 3 + ptr: 88 + timestamp: 2022-01-25T17:13:29Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f7461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1DApJtz9Raw5VB2rMcoCewNJUvTdcUmxcW + id: 115 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 45 + operation_id: 171 + protocol_id: 3 + ptr: 89 + timestamp: 2022-01-25T17:13:29Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d7074792d6d657461646174612e6a736f6e"}' +- contract: KT1URpVU61u5ubaWKdXBfJC2rfmSazD7Tdo8 + id: 116 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 45 + operation_id: 172 + protocol_id: 3 + ptr: 90 + timestamp: 2022-01-25T17:13:29Z + value: '{"bytes":"7368613235363a2f2f3078376539396563663361343439306533303434636364663331393839386437373338306132666332306161653336623665343033323764363738333939643137622f68747470733a25324625324673746f726167652e676f6f676c65617069732e636f6d253246747a69702d31362532467461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1LnJ3F6eYTBnuCmJGEuDCmsZWQGzrav4Kt + id: 117 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + level: 45 + operation_id: 173 + protocol_id: 3 + ptr: 91 + timestamp: 2022-01-25T17:13:29Z + value: '{"bytes":"7b226e616d65223a2274657374222c226465736372697074696f6e223a2241206d657461646174612074657374222c2276657273696f6e223a22302e31222c226c6963656e7365223a224d4954222c22617574686f7273223a5b225461717569746f203c68747470733a2f2f74657a6f737461717569746f2e696f2f3e225d2c22686f6d6570616765223a2268747470733a2f2f74657a6f737461717569746f2e696f2f227d"}' +- contract: KT1LnJ3F6eYTBnuCmJGEuDCmsZWQGzrav4Kt + id: 118 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 45 + operation_id: 173 + protocol_id: 3 + ptr: 91 + timestamp: 2022-01-25T17:13:29Z + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1EVwPVd8B1eDEbfj9AQCtFTzQ2AAQ16C4g + id: 119 + key: '{"bytes":"000081baf62ceef1633b95fef5d4908f15980e3c0a55"}' + key_hash: expruve3btzDkgS37mbEt6Q6D4CcRxUiwRPs3gyx2MmeaFsX3fLT6V + level: 45 + operation_id: 175 + protocol_id: 3 + ptr: 92 + timestamp: 2022-01-25T17:13:29Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1EVwPVd8B1eDEbfj9AQCtFTzQ2AAQ16C4g + id: 120 + key: '{"bytes":"0000b3927e0567be9d769cbfc67ede18a1f040115136"}' + key_hash: exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX + level: 45 + operation_id: 175 + protocol_id: 3 + ptr: 92 + timestamp: 2022-01-25T17:13:29Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + id: 121 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + level: 45 + operation_id: 176 + protocol_id: 3 + ptr: 98 + timestamp: 2022-01-25T17:13:29Z + value: '{"int":"10000000"}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + id: 122 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 45 + operation_id: 176 + protocol_id: 3 + ptr: 98 + timestamp: 2022-01-25T17:13:29Z + value: '{"int":"54000000"}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + id: 123 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + level: 45 + operation_id: 176 + protocol_id: 3 + ptr: 97 + timestamp: 2022-01-25T17:13:29Z + value: '{"prim":"Pair","args":[{"int":"2"},[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"30"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"416c696365546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"414c43"}]}]]}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + id: 124 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 45 + operation_id: 176 + protocol_id: 3 + ptr: 97 + timestamp: 2022-01-25T17:13:29Z + value: '{"prim":"Pair","args":[{"int":"1"},[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"36"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"77546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"77544b"}]}]]}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + id: 125 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + level: 45 + operation_id: 176 + protocol_id: 3 + ptr: 96 + timestamp: 2022-01-25T17:13:29Z + value: '{"prim":"Pair","args":[{"bytes":"00021f1076cb90f3b0fc7b7f44bf0c18f6c9a4cb8646"},{"prim":"True"}]}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + id: 126 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 45 + operation_id: 176 + protocol_id: 3 + ptr: 96 + timestamp: 2022-01-25T17:13:29Z + value: '{"prim":"Pair","args":[{"bytes":"00020427edce0782d677b5dfcd39e5a6973e022f9144"},{"prim":"True"}]}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + id: 127 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 45 + operation_id: 176 + protocol_id: 3 + ptr: 94 + timestamp: 2022-01-25T17:13:29Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d746f6b656e2d666163746f72792e6a736f6e"}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + id: 128 + key: '{"prim":"Pair","args":[{"bytes":"00020427edce0782d677b5dfcd39e5a6973e022f9144"},{"int":"1"}]}' + key_hash: expru3gmgjuoJdAKH3aEiTZEFwyZaGmCympXE6gRCdCXMjGa6TZMYN + level: 45 + operation_id: 176 + protocol_id: 3 + ptr: 93 + timestamp: 2022-01-25T17:13:29Z + value: '{"int":"18000000"}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + id: 129 + key: '{"prim":"Pair","args":[{"bytes":"00021f1076cb90f3b0fc7b7f44bf0c18f6c9a4cb8646"},{"int":"2"}]}' + key_hash: exprtx8hDU6Sey7ad2tUQaohDJz6jDi5mhPTymSZKJsjgMPqiuVG6c + level: 45 + operation_id: 176 + protocol_id: 3 + ptr: 93 + timestamp: 2022-01-25T17:13:29Z + value: '{"int":"9990000"}' +- contract: KT1HKqSnRy9JDvdin2kftG5f8pL1KMenL455 + id: 130 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + level: 45 + operation_id: 177 + protocol_id: 3 + ptr: 99 + timestamp: 2022-01-25T17:13:29Z + value: '{"bytes":"7b7d"}' +- contract: KT1HKqSnRy9JDvdin2kftG5f8pL1KMenL455 + id: 131 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 45 + operation_id: 177 + protocol_id: 3 + ptr: 99 + timestamp: 2022-01-25T17:13:29Z + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1WbQNVCyqq86XVsaD95L8XZf4D6SZEEmbv + id: 132 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 47 + operation_id: 185 + protocol_id: 3 + ptr: 100 + timestamp: 2022-01-25T17:17:47Z + value: '{"bytes":"74657a6f732d73746f726167653a2f2f756e646566696e65642f68657265"}' +- contract: KT1LAbdmU3YgRratLRomHaBfMGBbgW4TpzLz + id: 133 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 47 + operation_id: 186 + protocol_id: 3 + ptr: 101 + timestamp: 2022-01-25T17:17:47Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d6f6a692d696e2d6d657461646174612e6a736f6e"}' +- contract: KT1VuXpJtos2XEnGRBwioU83JceXD4JoVDpr + id: 134 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 47 + operation_id: 187 + protocol_id: 3 + ptr: 102 + timestamp: 2022-01-25T17:17:47Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f7461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + id: 135 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + level: 47 + operation_id: 189 + protocol_id: 3 + ptr: 106 + timestamp: 2022-01-25T17:17:47Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":"name"},{"bytes":"496e76616c696420746f6b656e206d65746164617461"}]}],{"int":"20000"}]}' +- contract: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + id: 136 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + level: 47 + operation_id: 189 + protocol_id: 3 + ptr: 106 + timestamp: 2022-01-25T17:17:47Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"30"}]},{"prim":"Elt","args":[{"string":"extra"},{"bytes":"416464206d6f72652064617461"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"416c696365546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"414c43"}]}],{"int":"20000"}]}' +- contract: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + id: 137 + key: '{"int":"0"}' + key_hash: exprtZBwZUeYYYfUs9B9Rg2ywHezVHnCCnmF9WsDQVrs582dSK63dC + level: 47 + operation_id: 189 + protocol_id: 3 + ptr: 106 + timestamp: 2022-01-25T17:17:47Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":""},{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f746f6b656e2d6d657461646174612e6a736f6e"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"4e616d652066726f6d20555249206973207072696f726974697a656421"}]}],{"int":"20000"}]}' +- contract: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + id: 138 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + level: 47 + operation_id: 189 + protocol_id: 3 + ptr: 104 + timestamp: 2022-01-25T17:17:47Z + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d76696577732e6a736f6e"}' +- contract: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + id: 139 + key: '{"prim":"Pair","args":[{"bytes":"00020149324a9e4c7fb22dd8e15cdcd89e74262ef532"},{"int":"0"}]}' + key_hash: exprvCFEqmxXvhjWhAXFNcbW9VbSPu7jErhaY1ZEbDrm5FP9KX81kM + level: 47 + operation_id: 189 + protocol_id: 3 + ptr: 103 + timestamp: 2022-01-25T17:17:47Z + value: '{"int":"20000"}' +- contract: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + id: 140 + key: '{"prim":"Pair","args":[{"bytes":"00028f6e1b3bbdaa25c778f0f3f66f9661dfddf73726"},{"int":"1"}]}' + key_hash: expruRKJKEmUMnMBVy5bC74YHTfD54rybttCsHMj1nMfc2qh4LnmDT + level: 47 + operation_id: 189 + protocol_id: 3 + ptr: 103 + timestamp: 2022-01-25T17:17:47Z + value: '{"int":"20000"}' +- contract: KT1EXfibFnDtpyZbUCAzWuy2QyeQ4bbtF7Ac + id: 141 + key: '{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"}' + key_hash: exprvEVwRjW3or3tGBSmpyXeqxzzp6XSJGRiKdxV5W1m4s5CceC83b + level: 47 + operation_id: 190 + protocol_id: 3 + ptr: 107 + timestamp: 2022-01-25T17:17:47Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"prim":"Pair","args":[{"int":"50"},{"prim":"True"}]}]}' +- contract: KT1EXfibFnDtpyZbUCAzWuy2QyeQ4bbtF7Ac + id: 142 + key: '{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"}' + key_hash: expruzjfAwk3HCHuixaChF3Jdja7VghEFjtrz1qow3UuY4rdCRD1GH + level: 47 + operation_id: 190 + protocol_id: 3 + ptr: 107 + timestamp: 2022-01-25T17:17:47Z + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"prim":"Pair","args":[{"int":"50"},{"prim":"True"}]}]}' diff --git a/internal/postgres/tests/fixtures/big_map_states.yml b/internal/postgres/tests/fixtures/big_map_states.yml new file mode 100644 index 000000000..2a2e1a387 --- /dev/null +++ b/internal/postgres/tests/fixtures/big_map_states.yml @@ -0,0 +1,1420 @@ +- contract: KT1W3fGSo8XfRSESPAg3Jngzt3D8xpPqW64i + count: 0 + id: 1 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 4 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d7074792d6d657461646174612e6a736f6e"}' +- contract: KT1Bc3T8ZcYPTTZHLTrAh2exfw6hyaTriMpQ + count: 0 + id: 2 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 5 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d7074792d6d657461646174612e6a736f6e"}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + count: 0 + id: 3 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 11 + removed: false + value: '{"int":"10000000"}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + count: 0 + id: 4 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 11 + removed: false + value: '{"int":"54000000"}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + count: 0 + id: 5 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 10 + removed: false + value: '{"prim":"Pair","args":[{"int":"2"},[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"30"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"416c696365546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"414c43"}]}]]}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + count: 0 + id: 6 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 10 + removed: false + value: '{"prim":"Pair","args":[{"int":"1"},[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"36"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"77546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"77544b"}]}]]}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + count: 0 + id: 7 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 9 + removed: false + value: '{"prim":"Pair","args":[{"bytes":"000270d7a915d558743de0e7edb96aa1c6cc3f17355b"},{"prim":"True"}]}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + count: 0 + id: 8 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 9 + removed: false + value: '{"prim":"Pair","args":[{"bytes":"0002928d0210a0fd4edc71beabbae6def736931862a9"},{"prim":"True"}]}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + count: 0 + id: 9 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 7 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d746f6b656e2d666163746f72792e6a736f6e"}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + count: 0 + id: 10 + key: '{"prim":"Pair","args":[{"bytes":"000270d7a915d558743de0e7edb96aa1c6cc3f17355b"},{"int":"2"}]}' + key_hash: exprvKUeU1hp2XrpHco1C5SN6UpATb2swCBZjn3ChsG67dL5q5M3yP + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 6 + removed: false + value: '{"int":"9990000"}' +- contract: KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7 + count: 0 + id: 11 + key: '{"prim":"Pair","args":[{"bytes":"0002928d0210a0fd4edc71beabbae6def736931862a9"},{"int":"1"}]}' + key_hash: expru2rxRxYK6nkgDG1Wysk9Qk8BxndCPRYbmddDYgry9GdyuNigtE + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 6 + removed: false + value: '{"int":"18000000"}' +- contract: KT18cv2aErkY6yf6SspaK9koxiDKJKfuacrD + count: 0 + id: 12 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 12 + removed: false + value: '{"bytes":"7b7d"}' +- contract: KT18cv2aErkY6yf6SspaK9koxiDKJKfuacrD + count: 0 + id: 13 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 12 + removed: false + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + count: 0 + id: 14 + key: '{"prim":"Pair","args":[{"bytes":"0002e63a8499e8e4e4efb97968b146ca642f0a942e5d"},{"bytes":"0002e0269b29d74638e31dbc79dd118347060252a3b1"}]}' + key_hash: expruyw8u644EyhfozymSjtnfmTdgEXTcYXjeb6adJqfWJ6okuff1L + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 15 + removed: false + value: '{"prim":"Unit"}' +- contract: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + count: 0 + id: 15 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 14 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d6d657461646174612e6a736f6e"}' +- contract: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + count: 0 + id: 16 + key: '{"bytes":"0002e63a8499e8e4e4efb97968b146ca642f0a942e5d"}' + key_hash: expruQPyA9Lix6xVuPDHvZt514ksW1ZiStk5T4errxkbXpv9ZRig2z + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 13 + removed: false + value: '{"int":"5"}' +- contract: KT1JFFa3ARM7cGxjLJ4CuynKq2pmYv1GupFM + count: 0 + id: 17 + key: '{"bytes":"0002e0269b29d74638e31dbc79dd118347060252a3b1"}' + key_hash: expru3EJD6S8yuMv2fGiviQpmC5JKLcJP8LXjGvRMkTAcudCGkj5df + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 13 + removed: false + value: '{"int":"2"}' +- contract: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + count: 0 + id: 18 + key: '{"prim":"Pair","args":[{"bytes":"0002d320e7a6c88ad303246f7bd1e75df9a2dc1a2bb9"},{"bytes":"00020c2dee271eb9b0d774a3fdc68305efb37527fb14"}]}' + key_hash: exprugVF5LMB4DiUqs8PZnNH21ehzpTH76SJQnB4AqKZQeoGprxR53 + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 19 + removed: false + value: '{"prim":"Unit"}' +- contract: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + count: 0 + id: 19 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 18 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d6d657461646174612e6a736f6e"}' +- contract: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + count: 0 + id: 20 + key: '{"bytes":"00020c2dee271eb9b0d774a3fdc68305efb37527fb14"}' + key_hash: exprujRoiGDdzgNck93Ua9SyM4hsaSw4pxXQ1VMK3j4GC6eto8vD7h + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 17 + removed: false + value: '{"int":"2"}' +- contract: KT1Ugw1u7ytn4YsWx8hFGcBFrddf3U6EsYTS + count: 0 + id: 21 + key: '{"bytes":"0002d320e7a6c88ad303246f7bd1e75df9a2dc1a2bb9"}' + key_hash: exprudH4HFTWyVqUpEkyt31LTQsRrphxXKHFGyk7KEanm8KE4gGV98 + last_update_level: 33 + last_update_time: 2022-01-25T16:45:09Z + ptr: 17 + removed: false + value: '{"int":"5"}' +- contract: KT1L6qnSbi7gCqbwKzGBqzbepxHNC5zR9Egj + count: 0 + id: 22 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 34 + last_update_time: 2022-01-25T16:47:37Z + ptr: 21 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f7461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1QyWsqRDsucjbjYvDa3Yr122oecdu3DEiC + count: 0 + id: 23 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 34 + last_update_time: 2022-01-25T16:47:37Z + ptr: 22 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f7461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1BNS3XGWDJM2Yghm3CYosKStE9reNscbfE + count: 0 + id: 24 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 34 + last_update_time: 2022-01-25T16:47:37Z + ptr: 23 + removed: false + value: '{"bytes":"7368613235363a2f2f3078376539396563663361343439306533303434636364663331393839386437373338306132666332306161653336623665343033323764363738333939643137622f68747470733a25324625324673746f726167652e676f6f676c65617069732e636f6d253246747a69702d31362532467461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + count: 0 + id: 25 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + last_update_level: 34 + last_update_time: 2022-01-25T16:47:37Z + ptr: 27 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":"name"},{"bytes":"496e76616c696420746f6b656e206d65746164617461"}]}],{"int":"20000"}]}' +- contract: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + count: 0 + id: 26 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 34 + last_update_time: 2022-01-25T16:47:37Z + ptr: 27 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"30"}]},{"prim":"Elt","args":[{"string":"extra"},{"bytes":"416464206d6f72652064617461"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"416c696365546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"414c43"}]}],{"int":"20000"}]}' +- contract: KT1Dd1HZSwbikboLRzurVg5z6rfTVziusdUt + count: 0 + id: 75 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 55 + removed: false + value: '{"bytes":"7b7d"}' +- contract: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + count: 0 + id: 27 + key: '{"int":"0"}' + key_hash: exprtZBwZUeYYYfUs9B9Rg2ywHezVHnCCnmF9WsDQVrs582dSK63dC + last_update_level: 34 + last_update_time: 2022-01-25T16:47:37Z + ptr: 27 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":""},{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f746f6b656e2d6d657461646174612e6a736f6e"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"4e616d652066726f6d20555249206973207072696f726974697a656421"}]}],{"int":"20000"}]}' +- contract: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + count: 0 + id: 28 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 34 + last_update_time: 2022-01-25T16:47:37Z + ptr: 25 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d76696577732e6a736f6e"}' +- contract: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + count: 0 + id: 29 + key: '{"prim":"Pair","args":[{"bytes":"0002b76f65564daa6ac08a05d3a6f85f0c03369e41f2"},{"int":"1"}]}' + key_hash: exprvEtXmAStEn985nAkpPZWZjyKT1NLrmEk7frzoR27hm5fSMDfkr + last_update_level: 34 + last_update_time: 2022-01-25T16:47:37Z + ptr: 24 + removed: false + value: '{"int":"20000"}' +- contract: KT1SsjnMpj4NJvUZZgEi3PkwB7dsqJviUH55 + count: 0 + id: 30 + key: '{"prim":"Pair","args":[{"bytes":"0002a5d55c090517bd98e04f18b46aa6a61b843fbd66"},{"int":"0"}]}' + key_hash: expruFJGEr7TdvRMvNYP22w6Rhf1WUztrx2nvxMU3wJsrZpxKKrNCZ + last_update_level: 34 + last_update_time: 2022-01-25T16:47:37Z + ptr: 24 + removed: false + value: '{"int":"20000"}' +- contract: KT1Gv5StW6rsCfuMW8kXN6XcZbbnxJP1SjKs + count: 0 + id: 31 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + last_update_level: 34 + last_update_time: 2022-01-25T16:47:37Z + ptr: 28 + removed: false + value: '{"bytes":"7b7d"}' +- contract: KT1Gv5StW6rsCfuMW8kXN6XcZbbnxJP1SjKs + count: 0 + id: 32 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 34 + last_update_time: 2022-01-25T16:47:37Z + ptr: 28 + removed: false + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1XKhK1QZWLrLntWhaDpaqEkuR57CYuWKk3 + count: 0 + id: 33 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 35 + last_update_time: 2022-01-25T16:49:57Z + ptr: 29 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d6f6a692d696e2d6d657461646174612e6a736f6e"}' +- contract: KT1H59QHJgqmiZ2Cfvw3MUUaPFxjWcowFVhY + count: 0 + id: 34 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 35 + last_update_time: 2022-01-25T16:49:57Z + ptr: 30 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d6f6a692d696e2d6d657461646174612e6a736f6e"}' +- contract: KT1BZJFEifWnscmwTPQonMufy7WZGKvzVhza + count: 0 + id: 35 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 35 + last_update_time: 2022-01-25T16:49:57Z + ptr: 31 + removed: false + value: '{"bytes":"7368613235363a2f2f3078376539396563663361343439316533303434636364663331393839386437373338306132666332306161653336623665343033323764363738333939643137622f68747470733a25324625324673746f726167652e676f6f676c65617069732e636f6d253246747a69702d31362532467461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1S1k4CKmLn6Bz95NT6HmeRzzJwaaRyCY7Q + count: 0 + id: 36 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 36 + last_update_time: 2022-01-25T16:52:19Z + ptr: 32 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f696e76616c69642e6a736f6e"}' +- contract: KT1MpEYtKWzgmpjFxryKvBC3dMuvD64Bt7pv + count: 0 + id: 37 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 36 + last_update_time: 2022-01-25T16:52:19Z + ptr: 33 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f696e76616c69642e6a736f6e"}' +- contract: KT1F6hdHeL6ceJtKHGnWj397SMqP4x4v3Mas + count: 0 + id: 38 + key: '{"bytes":"000081baf62ceef1633b95fef5d4908f15980e3c0a55"}' + key_hash: expruve3btzDkgS37mbEt6Q6D4CcRxUiwRPs3gyx2MmeaFsX3fLT6V + last_update_level: 36 + last_update_time: 2022-01-25T16:52:19Z + ptr: 34 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1F6hdHeL6ceJtKHGnWj397SMqP4x4v3Mas + count: 0 + id: 39 + key: '{"bytes":"0000b3927e0567be9d769cbfc67ede18a1f040115136"}' + key_hash: exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX + last_update_level: 36 + last_update_time: 2022-01-25T16:52:19Z + ptr: 34 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1RPs9iqAj4rRDyecoDz6RqhF2dVfRtWi78 + count: 0 + id: 40 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + last_update_level: 37 + last_update_time: 2022-01-25T16:54:35Z + ptr: 35 + removed: false + value: '{"bytes":"7b226e616d65223a2274657374222c226465736372697074696f6e223a2241206d657461646174612074657374222c2276657273696f6e223a22302e31222c226c6963656e7365223a224d4954222c22617574686f7273223a5b225461717569746f203c68747470733a2f2f74657a6f737461717569746f2e696f2f3e225d2c22686f6d6570616765223a2268747470733a2f2f74657a6f737461717569746f2e696f2f227d"}' +- contract: KT1RPs9iqAj4rRDyecoDz6RqhF2dVfRtWi78 + count: 0 + id: 41 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 37 + last_update_time: 2022-01-25T16:54:35Z + ptr: 35 + removed: false + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1LBiP4VgzuV9BV62wHiGhetE6saTbs4XSk + count: 0 + id: 42 + key: '{"bytes":"000081baf62ceef1633b95fef5d4908f15980e3c0a55"}' + key_hash: expruve3btzDkgS37mbEt6Q6D4CcRxUiwRPs3gyx2MmeaFsX3fLT6V + last_update_level: 37 + last_update_time: 2022-01-25T16:54:35Z + ptr: 36 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1LBiP4VgzuV9BV62wHiGhetE6saTbs4XSk + count: 0 + id: 43 + key: '{"bytes":"0000b3927e0567be9d769cbfc67ede18a1f040115136"}' + key_hash: exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX + last_update_level: 37 + last_update_time: 2022-01-25T16:54:35Z + ptr: 36 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1WfndvipjhvmJ7XoHTHJYDvTncPkgdEGWm + count: 0 + id: 44 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 38 + last_update_time: 2022-01-25T16:56:47Z + ptr: 37 + removed: false + value: '{"bytes":"74657a6f732d73746f726167653a2f2f4b5431525073396971416a347252447965636f447a3652716846326456665274576937382f68657265"}' +- contract: KT1MXcocFTwXV2emtgHAC7tCUt4Zc3EPPZAE + count: 0 + id: 45 + key: '{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"}' + key_hash: exprvEVwRjW3or3tGBSmpyXeqxzzp6XSJGRiKdxV5W1m4s5CceC83b + last_update_level: 38 + last_update_time: 2022-01-25T16:56:47Z + ptr: 38 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"prim":"Pair","args":[{"int":"50"},{"prim":"True"}]}]}' +- contract: KT1MXcocFTwXV2emtgHAC7tCUt4Zc3EPPZAE + count: 0 + id: 46 + key: '{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"}' + key_hash: expruzjfAwk3HCHuixaChF3Jdja7VghEFjtrz1qow3UuY4rdCRD1GH + last_update_level: 38 + last_update_time: 2022-01-25T16:56:47Z + ptr: 38 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"prim":"Pair","args":[{"int":"50"},{"prim":"True"}]}]}' +- contract: KT1EcQVhDC7izqW3uiGVrqbus6qBt78btyHv + count: 0 + id: 47 + key: '{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"}' + key_hash: exprvEVwRjW3or3tGBSmpyXeqxzzp6XSJGRiKdxV5W1m4s5CceC83b + last_update_level: 39 + last_update_time: 2022-01-25T16:59:07Z + ptr: 39 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"prim":"Pair","args":[{"int":"50"},{"prim":"True"}]}]}' +- contract: KT1Dd1HZSwbikboLRzurVg5z6rfTVziusdUt + count: 0 + id: 76 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 55 + removed: false + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1EcQVhDC7izqW3uiGVrqbus6qBt78btyHv + count: 0 + id: 48 + key: '{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"}' + key_hash: expruzjfAwk3HCHuixaChF3Jdja7VghEFjtrz1qow3UuY4rdCRD1GH + last_update_level: 39 + last_update_time: 2022-01-25T16:59:07Z + ptr: 39 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"prim":"Pair","args":[{"int":"50"},{"prim":"True"}]}]}' +- contract: KT1FQE7EtHEkmDTw5iRoUgeveVW6PiPUH9pC + count: 0 + id: 49 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + last_update_level: 40 + last_update_time: 2022-01-25T17:01:51Z + ptr: 40 + removed: false + value: '{"bytes":"7b226e616d65223a2274657374222c226465736372697074696f6e223a2241206d657461646174612074657374222c2276657273696f6e223a22302e31222c226c6963656e7365223a224d4954222c22617574686f7273223a5b225461717569746f203c68747470733a2f2f74657a6f737461717569746f2e696f2f3e225d2c22686f6d6570616765223a2268747470733a2f2f74657a6f737461717569746f2e696f2f227d"}' +- contract: KT1FQE7EtHEkmDTw5iRoUgeveVW6PiPUH9pC + count: 0 + id: 50 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 40 + last_update_time: 2022-01-25T17:01:51Z + ptr: 40 + removed: false + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1 + count: 0 + id: 51 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 40 + last_update_time: 2022-01-25T17:01:51Z + ptr: 42 + removed: false + value: '[{"int":"1"},{"string":"world"},{"string":"test2"},{"int":"0"},[]]' +- contract: KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1 + count: 0 + id: 52 + key: '{"int":"0"}' + key_hash: exprtZBwZUeYYYfUs9B9Rg2ywHezVHnCCnmF9WsDQVrs582dSK63dC + last_update_level: 40 + last_update_time: 2022-01-25T17:01:51Z + ptr: 42 + removed: false + value: '[{"int":"0"},{"string":"hello"},{"string":"test"},{"int":"0"},[]]' +- contract: KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1 + count: 0 + id: 53 + key: '{"bytes":"000081baf62ceef1633b95fef5d4908f15980e3c0a55"}' + key_hash: expruve3btzDkgS37mbEt6Q6D4CcRxUiwRPs3gyx2MmeaFsX3fLT6V + last_update_level: 40 + last_update_time: 2022-01-25T17:01:51Z + ptr: 41 + removed: false + value: '{"prim":"Pair","args":[[{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"}],{"int":"50"}]}' +- contract: KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1 + count: 0 + id: 54 + key: '{"bytes":"0000b3927e0567be9d769cbfc67ede18a1f040115136"}' + key_hash: exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX + last_update_level: 40 + last_update_time: 2022-01-25T17:01:51Z + ptr: 41 + removed: false + value: '{"prim":"Pair","args":[[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"}],{"int":"50"}]}' +- contract: KT1SryiY3YiHrtfth14JDWAP83W2WbSo1y6o + count: 0 + id: 55 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 43 + removed: false + value: '{"bytes":"74657a6f732d73746f726167653a2f2f4b543146514537457448456b6d4454773569526f556765766556573650695055483970432f68657265"}' +- contract: KT1RhyRG4etPssUovWHapMsfDbQqwPGAHHuc + count: 0 + id: 56 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 44 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d7074792d6d657461646174612e6a736f6e"}' +- contract: KT1D5LEDRjTeG4HcGyKKfnschdS3nTJEbqx7 + count: 0 + id: 57 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 45 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d7074792d6d657461646174612e6a736f6e"}' +- contract: KT1Lgy1eDiJpiZ3NZZXEz4i5MVSy4wG9g9c8 + count: 0 + id: 58 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 47 + removed: false + value: '[{"int":"1"},{"string":"world"},{"string":"test2"},{"int":"0"},[]]' +- contract: KT1Lgy1eDiJpiZ3NZZXEz4i5MVSy4wG9g9c8 + count: 0 + id: 59 + key: '{"int":"0"}' + key_hash: exprtZBwZUeYYYfUs9B9Rg2ywHezVHnCCnmF9WsDQVrs582dSK63dC + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 47 + removed: false + value: '[{"int":"0"},{"string":"hello"},{"string":"test"},{"int":"0"},[]]' +- contract: KT1Lgy1eDiJpiZ3NZZXEz4i5MVSy4wG9g9c8 + count: 0 + id: 60 + key: '{"bytes":"000081baf62ceef1633b95fef5d4908f15980e3c0a55"}' + key_hash: expruve3btzDkgS37mbEt6Q6D4CcRxUiwRPs3gyx2MmeaFsX3fLT6V + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 46 + removed: false + value: '{"prim":"Pair","args":[[{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"}],{"int":"50"}]}' +- contract: KT1Lgy1eDiJpiZ3NZZXEz4i5MVSy4wG9g9c8 + count: 0 + id: 61 + key: '{"bytes":"0000b3927e0567be9d769cbfc67ede18a1f040115136"}' + key_hash: exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 46 + removed: false + value: '{"prim":"Pair","args":[[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"}],{"int":"50"}]}' +- contract: KT1R9BdHMfGTwKnbCHii8akcB7DqzfdnD9AD + count: 0 + id: 62 + key: '{"bytes":"00022165a26786121eff8203bed56ffaf85d6bb25e42"}' + key_hash: exprv5VFJ5n3TWvuA7eR1Z5FqLvwoynr4sy9sjL9MsBww2f4LpfaC9 + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 48 + removed: false + value: '{"prim":"Pair","args":[{"int":"2"},[]]}' +- contract: KT1R9BdHMfGTwKnbCHii8akcB7DqzfdnD9AD + count: 0 + id: 63 + key: '{"bytes":"00012ffebbf1560632ca767bc960ccdb84669d284c2c"}' + key_hash: expruTQ93tbn1ZXLFCL1UwUjFXxBo1M3vyiCmnYWQN66Upv2oDfXrN + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 48 + removed: false + value: '{"prim":"Pair","args":[{"int":"3"},[]]}' +- contract: KT1R9BdHMfGTwKnbCHii8akcB7DqzfdnD9AD + count: 0 + id: 64 + key: '{"bytes":"000288192929d5d89c8dfe0aafc95a80398bcd6dfef8"}' + key_hash: exprtzcGNDTzKEnM8qMgD38ZJH6kQSoHcowPDj19y5CfvmwsXWVNF6 + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 48 + removed: false + value: '{"prim":"Pair","args":[{"int":"4"},[]]}' +- contract: KT1R9BdHMfGTwKnbCHii8akcB7DqzfdnD9AD + count: 0 + id: 65 + key: '{"bytes":"0001754887431181a33bef2bf9989e67f8700268ec77"}' + key_hash: exprtiGf7yyfTbdfv4Qmw5CVLs6JFwPrUBNLxK3bt3uZwrvJFGx3pT + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 48 + removed: false + value: '{"prim":"Pair","args":[{"int":"1"},[]]}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + count: 0 + id: 66 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 54 + removed: false + value: '{"int":"10000000"}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + count: 0 + id: 67 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 54 + removed: false + value: '{"int":"54000000"}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + count: 0 + id: 68 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 53 + removed: false + value: '{"prim":"Pair","args":[{"int":"2"},[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"30"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"416c696365546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"414c43"}]}]]}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + count: 0 + id: 69 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 53 + removed: false + value: '{"prim":"Pair","args":[{"int":"1"},[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"36"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"77546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"77544b"}]}]]}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + count: 0 + id: 70 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 52 + removed: false + value: '{"prim":"Pair","args":[{"bytes":"00021b614ccc67da1f2f9b569260f8c54e86b479a99f"},{"prim":"True"}]}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + count: 0 + id: 71 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 52 + removed: false + value: '{"prim":"Pair","args":[{"bytes":"0002f8b64c2fc9b122c4c66525f461a4453d1835f99d"},{"prim":"True"}]}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + count: 0 + id: 72 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 50 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d746f6b656e2d666163746f72792e6a736f6e"}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + count: 0 + id: 73 + key: '{"prim":"Pair","args":[{"bytes":"0002f8b64c2fc9b122c4c66525f461a4453d1835f99d"},{"int":"1"}]}' + key_hash: exprvJwEJXcvrQjMxa8fEFgrDLS6zy6BTfp8uwuAmeAMEmc6NUEK7T + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 49 + removed: false + value: '{"int":"18000000"}' +- contract: KT1DREzUemWyb1q7dUnHmxw3x8Ryq5VLZE8e + count: 0 + id: 74 + key: '{"prim":"Pair","args":[{"bytes":"00021b614ccc67da1f2f9b569260f8c54e86b479a99f"},{"int":"2"}]}' + key_hash: expru9H6FoqTCVubB6otu3sgcP7V26Ew7ffvDdaVKb9VAkmncTygfi + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 49 + removed: false + value: '{"int":"9990000"}' +- contract: KT1TSsjjzoGbWLMgUwdDUw33CLz34sQs5jYX + count: 0 + id: 77 + key: '{"prim":"Pair","args":[{"bytes":"0002ca6e1d3ef54a05bddfef5fbe17d09786865e89be"},{"bytes":"0002ead21e7f311ca2411c73388ff0e843f9602f4909"}]}' + key_hash: exprvJvHXN9x7wUYxwLNK2oqUqzB5JQLnXpQafsyaWoynG6aHvY8qc + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 58 + removed: false + value: '{"prim":"Unit"}' +- contract: KT1TSsjjzoGbWLMgUwdDUw33CLz34sQs5jYX + count: 0 + id: 78 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 57 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d6d657461646174612e6a736f6e"}' +- contract: KT1TSsjjzoGbWLMgUwdDUw33CLz34sQs5jYX + count: 0 + id: 79 + key: '{"bytes":"0002ead21e7f311ca2411c73388ff0e843f9602f4909"}' + key_hash: exprvCSQSQV4EAqbzVWVzbzdke38trBtBbGq4cPU94a115cqMedUke + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 56 + removed: false + value: '{"int":"2"}' +- contract: KT1TSsjjzoGbWLMgUwdDUw33CLz34sQs5jYX + count: 0 + id: 80 + key: '{"bytes":"0002ca6e1d3ef54a05bddfef5fbe17d09786865e89be"}' + key_hash: expru2mgufqqavCvYBFZY3NfQbHkNv28LZCKxMDy4ESeS3cKLzFVNR + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 56 + removed: false + value: '{"int":"5"}' +- contract: KT1RrexTzK8S2ecKsDZLB6BKMKUP1vVmg9Hh + count: 0 + id: 81 + key: '{"prim":"Pair","args":[{"bytes":"00021250b15c68a16f8efd59e879afbc89efb79921b7"},{"bytes":"00024850381eb4e9704d42218b1a00b5730a4225a18f"}]}' + key_hash: expruyKeUtiHeCBtsus6P397wL21s8KvChXrKeM1XVbEjMpwKn4s4Y + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 62 + removed: false + value: '{"prim":"Unit"}' +- contract: KT1RrexTzK8S2ecKsDZLB6BKMKUP1vVmg9Hh + count: 0 + id: 82 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 61 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d6d657461646174612e6a736f6e"}' +- contract: KT1RrexTzK8S2ecKsDZLB6BKMKUP1vVmg9Hh + count: 0 + id: 83 + key: '{"bytes":"00024850381eb4e9704d42218b1a00b5730a4225a18f"}' + key_hash: exprvPWmUvWbb76ZtF4LkkiHJ3Jtp3qQasscFuBWZmf9pEL5w9keU6 + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 60 + removed: false + value: '{"int":"2"}' +- contract: KT1RrexTzK8S2ecKsDZLB6BKMKUP1vVmg9Hh + count: 0 + id: 84 + key: '{"bytes":"00021250b15c68a16f8efd59e879afbc89efb79921b7"}' + key_hash: expruiuSzuwvXug1tHisFzFaUBaKzuevtWtMtXRm764MCAERqXQ3Er + last_update_level: 41 + last_update_time: 2022-01-25T17:04:35Z + ptr: 60 + removed: false + value: '{"int":"5"}' +- contract: KT18dyvjdq4gFuQuG1CnNZfd35Jk2UbiKcPB + count: 0 + id: 85 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 42 + last_update_time: 2022-01-25T17:07:03Z + ptr: 64 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f7461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1UJ5bYnGpkwZLTJpa2cUXUX3dz8St8qxNn + count: 0 + id: 86 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 42 + last_update_time: 2022-01-25T17:07:03Z + ptr: 65 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f7461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1Sd3BSdF5VKiU1oe6VqYifGe6TfqbkDDGZ + count: 0 + id: 87 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 42 + last_update_time: 2022-01-25T17:07:03Z + ptr: 66 + removed: false + value: '{"bytes":"7368613235363a2f2f3078376539396563663361343439306533303434636364663331393839386437373338306132666332306161653336623665343033323764363738333939643137622f68747470733a25324625324673746f726167652e676f6f676c65617069732e636f6d253246747a69702d31362532467461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + count: 0 + id: 88 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + last_update_level: 42 + last_update_time: 2022-01-25T17:07:03Z + ptr: 70 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":"name"},{"bytes":"496e76616c696420746f6b656e206d65746164617461"}]}],{"int":"20000"}]}' +- contract: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + count: 0 + id: 89 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 42 + last_update_time: 2022-01-25T17:07:03Z + ptr: 70 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"30"}]},{"prim":"Elt","args":[{"string":"extra"},{"bytes":"416464206d6f72652064617461"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"416c696365546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"414c43"}]}],{"int":"20000"}]}' +- contract: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + count: 0 + id: 90 + key: '{"int":"0"}' + key_hash: exprtZBwZUeYYYfUs9B9Rg2ywHezVHnCCnmF9WsDQVrs582dSK63dC + last_update_level: 42 + last_update_time: 2022-01-25T17:07:03Z + ptr: 70 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":""},{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f746f6b656e2d6d657461646174612e6a736f6e"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"4e616d652066726f6d20555249206973207072696f726974697a656421"}]}],{"int":"20000"}]}' +- contract: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + count: 0 + id: 91 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 42 + last_update_time: 2022-01-25T17:07:03Z + ptr: 68 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d76696577732e6a736f6e"}' +- contract: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + count: 0 + id: 92 + key: '{"prim":"Pair","args":[{"bytes":"0002229ac298406cfffb889cf71779fc94b72d96293d"},{"int":"1"}]}' + key_hash: exprujSJMkRG4GSarzGN5vy9uFsgyRpLc6d3DdDpygZQHFJjHntCDd + last_update_level: 42 + last_update_time: 2022-01-25T17:07:03Z + ptr: 67 + removed: false + value: '{"int":"20000"}' +- contract: KT1LFDKJRRnjxEpaMqb9CFUnAV4TB18ygCSh + count: 0 + id: 93 + key: '{"prim":"Pair","args":[{"bytes":"00022546581143cd99b47b60ee767874d30f2731cbaa"},{"int":"0"}]}' + key_hash: expruGTgtiQGef74HBKTdPG4ZsES9oJo82V3924iA2hv2fbh8GpbRg + last_update_level: 42 + last_update_time: 2022-01-25T17:07:03Z + ptr: 67 + removed: false + value: '{"int":"20000"}' +- contract: KT18jPdN1UAFvXppPh41PS5xZP3Xx7F6s91D + count: 0 + id: 94 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + last_update_level: 42 + last_update_time: 2022-01-25T17:07:03Z + ptr: 71 + removed: false + value: '{"bytes":"7b7d"}' +- contract: KT18jPdN1UAFvXppPh41PS5xZP3Xx7F6s91D + count: 0 + id: 95 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 42 + last_update_time: 2022-01-25T17:07:03Z + ptr: 71 + removed: false + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1SGb8wy8CPTWBTMYipFv5rDTBQnuyceL4Z + count: 0 + id: 96 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 43 + last_update_time: 2022-01-25T17:09:21Z + ptr: 72 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d6f6a692d696e2d6d657461646174612e6a736f6e"}' +- contract: KT1A1euYzsXoqoVq6CFss6ofWgfbfev97FxT + count: 0 + id: 97 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 43 + last_update_time: 2022-01-25T17:09:21Z + ptr: 73 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d6f6a692d696e2d6d657461646174612e6a736f6e"}' +- contract: KT1UnZaX82rgUBvaj3iA8D3W7T2Zxe6kxTiQ + count: 0 + id: 98 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 43 + last_update_time: 2022-01-25T17:09:21Z + ptr: 74 + removed: false + value: '{"bytes":"7368613235363a2f2f3078376539396563663361343439316533303434636364663331393839386437373338306132666332306161653336623665343033323764363738333939643137622f68747470733a25324625324673746f726167652e676f6f676c65617069732e636f6d253246747a69702d31362532467461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1NDZJknffhfNhh46unvGopGppVmTem1HBG + count: 0 + id: 99 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 75 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f696e76616c69642e6a736f6e"}' +- contract: KT1PZ4Qb4Q9NywpLpJBufR5nVUDDSbjH2D6j + count: 0 + id: 100 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 76 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f696e76616c69642e6a736f6e"}' +- contract: KT1TFRwXwt1xNd8bLDEnbvZLd446TzT163Bd + count: 0 + id: 101 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 77 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d7074792d6d657461646174612e6a736f6e"}' +- contract: KT1957qBZ6Qto5oSvqSZqkyTsBPcXFr4J6KM + count: 0 + id: 102 + key: '{"bytes":"000081baf62ceef1633b95fef5d4908f15980e3c0a55"}' + key_hash: expruve3btzDkgS37mbEt6Q6D4CcRxUiwRPs3gyx2MmeaFsX3fLT6V + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 78 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1957qBZ6Qto5oSvqSZqkyTsBPcXFr4J6KM + count: 0 + id: 103 + key: '{"bytes":"0000b3927e0567be9d769cbfc67ede18a1f040115136"}' + key_hash: exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 78 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1Q4KbVQZZiwgiQi5PWj7a8iVSeHvDLtrHd + count: 0 + id: 104 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 79 + removed: false + value: '{"bytes":"7b7d"}' +- contract: KT1Q4KbVQZZiwgiQi5PWj7a8iVSeHvDLtrHd + count: 0 + id: 105 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 79 + removed: false + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1Gz8N3VwTriRD1VVPrrC5asYF2e1mPSDP9 + count: 0 + id: 106 + key: '{"prim":"Pair","args":[{"bytes":"00026e354627a6c2eb69386cd8def55ec3a0a4aa70eb"},{"bytes":"000265408e7ff3d4dcc3c0e746fa906fc2e5065f1aad"}]}' + key_hash: expruHwatDGtmpjcvu9GMnQTdKNCTBMDHfJuYqDELoLxCkk7DKJmwp + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 82 + removed: false + value: '{"prim":"Unit"}' +- contract: KT1Gz8N3VwTriRD1VVPrrC5asYF2e1mPSDP9 + count: 0 + id: 107 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 81 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d6d657461646174612e6a736f6e"}' +- contract: KT1Gz8N3VwTriRD1VVPrrC5asYF2e1mPSDP9 + count: 0 + id: 108 + key: '{"bytes":"00026e354627a6c2eb69386cd8def55ec3a0a4aa70eb"}' + key_hash: expruWYcn3xKvCYtwHoBHvibssPzsK9NaWdfRfq2qa3gDEmwW33wfe + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 80 + removed: false + value: '{"int":"5"}' +- contract: KT1Gz8N3VwTriRD1VVPrrC5asYF2e1mPSDP9 + count: 0 + id: 109 + key: '{"bytes":"000265408e7ff3d4dcc3c0e746fa906fc2e5065f1aad"}' + key_hash: expru2BPn96x7ozLoDdPjNupAqwA6cpCdfBz6YaumDcxPDgsAy8amY + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 80 + removed: false + value: '{"int":"2"}' +- contract: KT1Tpdf4izXzLqafbQzcW1tfxfcH2ZU6ytVQ + count: 0 + id: 110 + key: '{"prim":"Pair","args":[{"bytes":"000239c6679d8012cb81f14d8bad681f7b13243d4ffa"},{"bytes":"0002e20225983377e005022c6686f7ff58fa44fc45c9"}]}' + key_hash: exprvM9C7iWDRH1WxKwpEKW4RuAAHxhX4SraxmuZsre6hpZwJCiMXu + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 86 + removed: false + value: '{"prim":"Unit"}' +- contract: KT1Tpdf4izXzLqafbQzcW1tfxfcH2ZU6ytVQ + count: 0 + id: 111 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 85 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d6d657461646174612e6a736f6e"}' +- contract: KT1Tpdf4izXzLqafbQzcW1tfxfcH2ZU6ytVQ + count: 0 + id: 112 + key: '{"bytes":"000239c6679d8012cb81f14d8bad681f7b13243d4ffa"}' + key_hash: exprvSmjTtyqsdX5sZ2kUAKRRcQLNk79FT2oLPQ2nz5A2FHUvS2UxX + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 84 + removed: false + value: '{"int":"5"}' +- contract: KT1Tpdf4izXzLqafbQzcW1tfxfcH2ZU6ytVQ + count: 0 + id: 113 + key: '{"bytes":"0002e20225983377e005022c6686f7ff58fa44fc45c9"}' + key_hash: exprvRThuKxPh6zyi5MUdyYY5xkq1sxFU523KLQnPKCcPQr1hmNYWC + last_update_level: 44 + last_update_time: 2022-01-25T17:11:23Z + ptr: 84 + removed: false + value: '{"int":"2"}' +- contract: KT1GCrzzHq2sHjNza1Q89JHHY8Xj2ASYqUJ7 + count: 0 + id: 114 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 88 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f7461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1DApJtz9Raw5VB2rMcoCewNJUvTdcUmxcW + count: 0 + id: 115 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 89 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d7074792d6d657461646174612e6a736f6e"}' +- contract: KT1URpVU61u5ubaWKdXBfJC2rfmSazD7Tdo8 + count: 0 + id: 116 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 90 + removed: false + value: '{"bytes":"7368613235363a2f2f3078376539396563663361343439306533303434636364663331393839386437373338306132666332306161653336623665343033323764363738333939643137622f68747470733a25324625324673746f726167652e676f6f676c65617069732e636f6d253246747a69702d31362532467461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1LnJ3F6eYTBnuCmJGEuDCmsZWQGzrav4Kt + count: 0 + id: 117 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 91 + removed: false + value: '{"bytes":"7b226e616d65223a2274657374222c226465736372697074696f6e223a2241206d657461646174612074657374222c2276657273696f6e223a22302e31222c226c6963656e7365223a224d4954222c22617574686f7273223a5b225461717569746f203c68747470733a2f2f74657a6f737461717569746f2e696f2f3e225d2c22686f6d6570616765223a2268747470733a2f2f74657a6f737461717569746f2e696f2f227d"}' +- contract: KT1LnJ3F6eYTBnuCmJGEuDCmsZWQGzrav4Kt + count: 0 + id: 118 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 91 + removed: false + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1EVwPVd8B1eDEbfj9AQCtFTzQ2AAQ16C4g + count: 0 + id: 119 + key: '{"bytes":"000081baf62ceef1633b95fef5d4908f15980e3c0a55"}' + key_hash: expruve3btzDkgS37mbEt6Q6D4CcRxUiwRPs3gyx2MmeaFsX3fLT6V + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 92 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1EVwPVd8B1eDEbfj9AQCtFTzQ2AAQ16C4g + count: 0 + id: 120 + key: '{"bytes":"0000b3927e0567be9d769cbfc67ede18a1f040115136"}' + key_hash: exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 92 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"},{"int":"25"}]}],{"int":"50"}]}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + count: 0 + id: 121 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 98 + removed: false + value: '{"int":"10000000"}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + count: 0 + id: 122 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 98 + removed: false + value: '{"int":"54000000"}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + count: 0 + id: 123 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 97 + removed: false + value: '{"prim":"Pair","args":[{"int":"2"},[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"30"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"416c696365546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"414c43"}]}]]}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + count: 0 + id: 124 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 97 + removed: false + value: '{"prim":"Pair","args":[{"int":"1"},[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"36"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"77546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"77544b"}]}]]}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + count: 0 + id: 125 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 96 + removed: false + value: '{"prim":"Pair","args":[{"bytes":"00021f1076cb90f3b0fc7b7f44bf0c18f6c9a4cb8646"},{"prim":"True"}]}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + count: 0 + id: 126 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 96 + removed: false + value: '{"prim":"Pair","args":[{"bytes":"00020427edce0782d677b5dfcd39e5a6973e022f9144"},{"prim":"True"}]}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + count: 0 + id: 127 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 94 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d746f6b656e2d666163746f72792e6a736f6e"}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + count: 0 + id: 128 + key: '{"prim":"Pair","args":[{"bytes":"00020427edce0782d677b5dfcd39e5a6973e022f9144"},{"int":"1"}]}' + key_hash: expru3gmgjuoJdAKH3aEiTZEFwyZaGmCympXE6gRCdCXMjGa6TZMYN + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 93 + removed: false + value: '{"int":"18000000"}' +- contract: KT1Kqz6gc9RbaL5Fu5q1MveBEN9npfqWjwY4 + count: 0 + id: 129 + key: '{"prim":"Pair","args":[{"bytes":"00021f1076cb90f3b0fc7b7f44bf0c18f6c9a4cb8646"},{"int":"2"}]}' + key_hash: exprtx8hDU6Sey7ad2tUQaohDJz6jDi5mhPTymSZKJsjgMPqiuVG6c + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 93 + removed: false + value: '{"int":"9990000"}' +- contract: KT1HKqSnRy9JDvdin2kftG5f8pL1KMenL455 + count: 0 + id: 130 + key: '{"string":"here"}' + key_hash: expruaHzyjwFcmFKHqR49qdxwJupAna6ygSKo2mFJQtqZQjid5t8GK + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 99 + removed: false + value: '{"bytes":"7b7d"}' +- contract: KT1HKqSnRy9JDvdin2kftG5f8pL1KMenL455 + count: 0 + id: 131 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 45 + last_update_time: 2022-01-25T17:13:29Z + ptr: 99 + removed: false + value: '{"bytes":"74657a6f732d73746f726167653a68657265"}' +- contract: KT1WbQNVCyqq86XVsaD95L8XZf4D6SZEEmbv + count: 0 + id: 132 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 47 + last_update_time: 2022-01-25T17:17:47Z + ptr: 100 + removed: false + value: '{"bytes":"74657a6f732d73746f726167653a2f2f756e646566696e65642f68657265"}' +- contract: KT1LAbdmU3YgRratLRomHaBfMGBbgW4TpzLz + count: 0 + id: 133 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 47 + last_update_time: 2022-01-25T17:17:47Z + ptr: 101 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f656d6f6a692d696e2d6d657461646174612e6a736f6e"}' +- contract: KT1VuXpJtos2XEnGRBwioU83JceXD4JoVDpr + count: 0 + id: 134 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 47 + last_update_time: 2022-01-25T17:17:47Z + ptr: 102 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f7461636f2d73686f702d6d657461646174612e6a736f6e"}' +- contract: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + count: 0 + id: 135 + key: '{"int":"2"}' + key_hash: expruDuAZnFKqmLoisJqUGqrNzXTvw7PJM2rYk97JErM5FHCerQqgn + last_update_level: 47 + last_update_time: 2022-01-25T17:17:47Z + ptr: 106 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":"name"},{"bytes":"496e76616c696420746f6b656e206d65746164617461"}]}],{"int":"20000"}]}' +- contract: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + count: 0 + id: 136 + key: '{"int":"1"}' + key_hash: expru2dKqDfZG8hu4wNGkiyunvq2hdSKuVYtcKta7BWP6Q18oNxKjS + last_update_level: 47 + last_update_time: 2022-01-25T17:17:47Z + ptr: 106 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":"decimals"},{"bytes":"30"}]},{"prim":"Elt","args":[{"string":"extra"},{"bytes":"416464206d6f72652064617461"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"416c696365546f6b656e"}]},{"prim":"Elt","args":[{"string":"symbol"},{"bytes":"414c43"}]}],{"int":"20000"}]}' +- contract: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + count: 0 + id: 137 + key: '{"int":"0"}' + key_hash: exprtZBwZUeYYYfUs9B9Rg2ywHezVHnCCnmF9WsDQVrs582dSK63dC + last_update_level: 47 + last_update_time: 2022-01-25T17:17:47Z + ptr: 106 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"string":""},{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f746f6b656e2d6d657461646174612e6a736f6e"}]},{"prim":"Elt","args":[{"string":"name"},{"bytes":"4e616d652066726f6d20555249206973207072696f726974697a656421"}]}],{"int":"20000"}]}' +- contract: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + count: 0 + id: 138 + key: '{"string":""}' + key_hash: expru5X1yxJG6ezR2uHMotwMLNmSzQyh5t1vUnhjx4cS6Pv9qE1Sdo + last_update_level: 47 + last_update_time: 2022-01-25T17:17:47Z + ptr: 104 + removed: false + value: '{"bytes":"68747470733a2f2f73746f726167652e676f6f676c65617069732e636f6d2f747a69702d31362f6661322d76696577732e6a736f6e"}' +- contract: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + count: 0 + id: 139 + key: '{"prim":"Pair","args":[{"bytes":"00020149324a9e4c7fb22dd8e15cdcd89e74262ef532"},{"int":"0"}]}' + key_hash: exprvCFEqmxXvhjWhAXFNcbW9VbSPu7jErhaY1ZEbDrm5FP9KX81kM + last_update_level: 47 + last_update_time: 2022-01-25T17:17:47Z + ptr: 103 + removed: false + value: '{"int":"20000"}' +- contract: KT1Ke1DAFk2SroYgvy44wcA74W4hWsu8LsHo + count: 0 + id: 140 + key: '{"prim":"Pair","args":[{"bytes":"00028f6e1b3bbdaa25c778f0f3f66f9661dfddf73726"},{"int":"1"}]}' + key_hash: expruRKJKEmUMnMBVy5bC74YHTfD54rybttCsHMj1nMfc2qh4LnmDT + last_update_level: 47 + last_update_time: 2022-01-25T17:17:47Z + ptr: 103 + removed: false + value: '{"int":"20000"}' +- contract: KT1EXfibFnDtpyZbUCAzWuy2QyeQ4bbtF7Ac + count: 0 + id: 141 + key: '{"bytes":"0000eadc0855adb415fa69a76fc10397dc2fb37039a0"}' + key_hash: exprvEVwRjW3or3tGBSmpyXeqxzzp6XSJGRiKdxV5W1m4s5CceC83b + last_update_level: 47 + last_update_time: 2022-01-25T17:17:47Z + ptr: 107 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"prim":"Pair","args":[{"int":"50"},{"prim":"True"}]}]}' +- contract: KT1EXfibFnDtpyZbUCAzWuy2QyeQ4bbtF7Ac + count: 0 + id: 142 + key: '{"bytes":"000023c3ed8ee591358444ebf21be3a5dcc26eda84a2"}' + key_hash: expruzjfAwk3HCHuixaChF3Jdja7VghEFjtrz1qow3UuY4rdCRD1GH + last_update_level: 47 + last_update_time: 2022-01-25T17:17:47Z + ptr: 107 + removed: false + value: '{"prim":"Pair","args":[[{"prim":"Elt","args":[{"bytes":"0000b10310dd49498e9e89c124a0df8cfb8e8d09ccbd"},{"int":"25"}]},{"prim":"Elt","args":[{"bytes":"0000e96b9f8b19af9c7ffa0c0480e1977b295850961f"},{"int":"25"}]}],{"prim":"Pair","args":[{"int":"50"},{"prim":"True"}]}]}' diff --git a/internal/postgres/tests/fixtures/blocks.yml b/internal/postgres/tests/fixtures/blocks.yml new file mode 100644 index 000000000..502a5e03c --- /dev/null +++ b/internal/postgres/tests/fixtures/blocks.yml @@ -0,0 +1,235 @@ +- hash: BLAuTiHQdSCXXhfDvv417JKsM8bYT5tNsrpmWyJiMrMdYJNuoLP + id: 1 + level: 1 + protocol_id: 1 + timestamp: 2022-01-25T15:03:39Z +- hash: BMQHBqRo1ZykVpEfKi7ruJa1iJKLV1sLAvwBR3zKWAxMXmVNjTR + id: 2 + level: 2 + protocol_id: 3 + timestamp: 2022-01-25T15:10:11Z +- hash: BMGJn5R1XqDVZVtDY43eG3yaoQn3TmkqGoEY6rs7RbTbcEDD7kz + id: 3 + level: 3 + protocol_id: 3 + timestamp: 2022-01-25T15:14:03Z +- hash: BLvZLV1NMG8jn7jj4uAA9w6AA8DPmLh1Lwa3gDkoGXdbNhZTmGB + id: 4 + level: 4 + protocol_id: 3 + timestamp: 2022-01-25T15:17:55Z +- hash: BKmoAD2euyC4k7WXJs7C2YsLHvJ6fgeTvt4pMCCgwtanoDucg79 + id: 5 + level: 5 + protocol_id: 3 + timestamp: 2022-01-25T15:22:15Z +- hash: BLDsrwg83uKpMGTRTASYjzUQMLaLHG7zDnSyvmZuqWRstJr4aJc + id: 6 + level: 6 + protocol_id: 3 + timestamp: 2022-01-25T15:25:49Z +- hash: BLcMcvShtXqHhBtT8RGSfi4Miaxp9m2Pg3HwxbfMhRFTdNau4mY + id: 7 + level: 7 + protocol_id: 3 + timestamp: 2022-01-25T15:29:29Z +- hash: BKyJC2dB4aGvYkAWJ7DMjWkyYGQQypyqtP4xnvNUzH2gLxF9x3k + id: 8 + level: 8 + protocol_id: 3 + timestamp: 2022-01-25T15:33:11Z +- hash: BKmV2op3EyAE71DDiYjzwBuvrEiUeL2pXCSc8ZD8w67fbY2eUgN + id: 9 + level: 9 + protocol_id: 3 + timestamp: 2022-01-25T15:36:21Z +- hash: BLqNTDzsU6hETYiAu4s1Ring6MsC5StmNps3fzcnxbRVW6LGk9Y + id: 10 + level: 10 + protocol_id: 3 + timestamp: 2022-01-25T15:39:27Z +- hash: BL3jesRARaRmd41ybbug5KQuH7S9QTDRBcA338K6gze3FrEkPsn + id: 11 + level: 11 + protocol_id: 3 + timestamp: 2022-01-25T15:42:29Z +- hash: BMNzbYZjy3mAD5qpuHAyynV2qMJsVaMNuLc6zTTwiAnsnEUK9Ax + id: 12 + level: 12 + protocol_id: 3 + timestamp: 2022-01-25T15:45:33Z +- hash: BMTKqhJpNCP88cEdho4tQk2uwWDMfsRPuAtCi1JgrdeMDFzFjFj + id: 13 + level: 13 + protocol_id: 3 + timestamp: 2022-01-25T15:48:05Z +- hash: BLWbDa8Yw7Jf1XD3p7QmnXMP6LRPrS2erjQk719nkthtaNzT4kU + id: 14 + level: 14 + protocol_id: 3 + timestamp: 2022-01-25T15:50:45Z +- hash: BMCUfRZQoctnuxWvWZ7A8diKi2SnXnPLna2vGtmvDkAcD7wMBwF + id: 15 + level: 15 + protocol_id: 3 + timestamp: 2022-01-25T15:53:43Z +- hash: BLMNZ3U5g4JQUChT8cAjA89rjMrwxsCZ1dD49hLa735MtLFnXRW + id: 16 + level: 16 + protocol_id: 3 + timestamp: 2022-01-25T15:56:51Z +- hash: BLpxmDN3C9N1vdjohB7ehfyDkBrrLJoUDeZGqV38VQGxmLsP6mg + id: 17 + level: 17 + protocol_id: 3 + timestamp: 2022-01-25T15:59:31Z +- hash: BMLRhULMV7iNH25qYW6Qu3DqV4N7vUdRoj7iNjz6bNW5Ni3ZhcB + id: 18 + level: 18 + protocol_id: 3 + timestamp: 2022-01-25T16:02:01Z +- hash: BLoNNfoQScqANttL3Goou7VZxPYagtzNw1ZbWR79ubBQTa5m8FF + id: 19 + level: 19 + protocol_id: 3 + timestamp: 2022-01-25T16:04:33Z +- hash: BL42ZFFWRDLiDGnbgzurs8xgP2ambAss2fh49yZBWXxns9MxTya + id: 20 + level: 20 + protocol_id: 3 + timestamp: 2022-01-25T16:08:31Z +- hash: BMU9DGmkfFBQJqDtaPNS6SjzDnf5c2wCeuTCH65vXXGU5TK2jKz + id: 21 + level: 21 + protocol_id: 3 + timestamp: 2022-01-25T16:11:31Z +- hash: BL9oXYMKsiDEijZinpJKLuPDg6XzU5Bx6ehxf3QDPQgeipbG1bR + id: 22 + level: 22 + protocol_id: 3 + timestamp: 2022-01-25T16:14:17Z +- hash: BMHCvFCYTQxhTHbGw1b3xk5sKAKDjZBSvnhVAL9YE2fwtQ2BU3u + id: 23 + level: 23 + protocol_id: 3 + timestamp: 2022-01-25T16:17:27Z +- hash: BMa7kWZtkf3gP85yfZjbwdaQXR9j1TuVtCvcxrZfGAwFNXzNdCm + id: 24 + level: 24 + protocol_id: 3 + timestamp: 2022-01-25T16:20:15Z +- hash: BLCWMA4JhHdxH7P74f6h5iVbSGiaqAiFKpKHxBxqCimqVXzMX4s + id: 25 + level: 25 + protocol_id: 3 + timestamp: 2022-01-25T16:23:21Z +- hash: BKmMhmPdzxKM4vNozP1KYgHWoYNGFLjiiPk5dDApL7szimuEFYe + id: 26 + level: 26 + protocol_id: 3 + timestamp: 2022-01-25T16:26:01Z +- hash: BLqEK4qWEdDiiYtm8XrYQFsmeZENFan36o2769X7We4f2KYA3sA + id: 27 + level: 27 + protocol_id: 3 + timestamp: 2022-01-25T16:28:55Z +- hash: BL3rrkXVFc9vuMkzX5QvQ1usNmPubu4w2UEUDuWM29XnVPK7oAp + id: 28 + level: 28 + protocol_id: 3 + timestamp: 2022-01-25T16:31:47Z +- hash: BMEuKFAi3tKhe18xxkY5uURJB9wCFGM6UagEVWfc8SiudzzpZqX + id: 29 + level: 29 + protocol_id: 3 + timestamp: 2022-01-25T16:34:57Z +- hash: BKnp27ciRRUX1yYFe79oQP1gjtFvJDs7v5tPssTgu12Mwr9H6bi + id: 30 + level: 30 + protocol_id: 3 + timestamp: 2022-01-25T16:37:35Z +- hash: BM5e31th7SBFFNGGifnwv5hjTiorabzesLGywkmRb2ncum9j1PK + id: 31 + level: 31 + protocol_id: 3 + timestamp: 2022-01-25T16:40:29Z +- hash: BLaGgW9pJREoiUwHiwx1NCWvsvipvQNVgdXaoSdCm67948wTnfv + id: 32 + level: 32 + protocol_id: 3 + timestamp: 2022-01-25T16:43:03Z +- hash: BLCBV9xm36PV6UETUiKjf7diokWeMgarkYJWiZeXHvwHUuQwE2S + id: 33 + level: 33 + protocol_id: 3 + timestamp: 2022-01-25T16:45:09Z +- hash: BMTvvPP9RVCLv6h9DFWYiQYJYDchedR9YjYLkp7rL242575CfCZ + id: 34 + level: 34 + protocol_id: 3 + timestamp: 2022-01-25T16:47:37Z +- hash: BLCWgT1sxqKxsmWnJgBEJfrzNYczeKgRPpsU7AKqfpqEqsQQoUu + id: 35 + level: 35 + protocol_id: 3 + timestamp: 2022-01-25T16:49:57Z +- hash: BM4TWUiAnAq3EwdSwDuoMULyxPeZrq5EgvRFzJN7fHZ1cPrC6xg + id: 36 + level: 36 + protocol_id: 3 + timestamp: 2022-01-25T16:52:19Z +- hash: BL4hzFPCPecGHt42Kob45Fm5JbTY2QNgYxvduWXdRrKACZEsB86 + id: 37 + level: 37 + protocol_id: 3 + timestamp: 2022-01-25T16:54:35Z +- hash: BME77ZHzx7A8Nww8YPhn9C2uSqFWVzGW5N5mnhDgw8d9wVW1RaU + id: 38 + level: 38 + protocol_id: 3 + timestamp: 2022-01-25T16:56:47Z +- hash: BLLm3v3A1HX6qDKpXPpVFYswrRSZwfb16s7MrbHJueReEnGkGFx + id: 39 + level: 39 + protocol_id: 3 + timestamp: 2022-01-25T16:59:07Z +- hash: BL68PgM93vRHeZe9dcKJuNixLQSLq13ZguthVu8fXDJT33bcQqf + id: 40 + level: 40 + protocol_id: 3 + timestamp: 2022-01-25T17:01:51Z +- hash: BKkTsDEs2rgGAymiVtGBGwyvEFBZ8dUXqBaPj5wnv3NRn3SZzPH + id: 41 + level: 41 + protocol_id: 3 + timestamp: 2022-01-25T17:04:35Z +- hash: BM8oxMKNUMQVzy72ztPE8EMnaAj59SmYzzWbbS9vMaWFZG1FPYP + id: 42 + level: 42 + protocol_id: 3 + timestamp: 2022-01-25T17:07:03Z +- hash: BLgeWZQq6goUy9sVnYggUyu27DffpKDoRap3t3V2HBw2Gusn7WM + id: 43 + level: 43 + protocol_id: 3 + timestamp: 2022-01-25T17:09:21Z +- hash: BLUJjd8UM4nnCCaJDcv5zMTuATk7WdnWFZduZAu8YxU8P37dqFQ + id: 44 + level: 44 + protocol_id: 3 + timestamp: 2022-01-25T17:11:23Z +- hash: BL45zYE7Mc7xp7WekcCVTQpNDGtRkeFi7gGfr5SfT2UUtUFYqAc + id: 45 + level: 45 + protocol_id: 3 + timestamp: 2022-01-25T17:13:29Z +- hash: BKuGbbQyvRByZE1p6XqYqu5d6Zt2aUp4YQjCLwmCGErhxejVMDw + id: 46 + level: 46 + protocol_id: 3 + timestamp: 2022-01-25T17:15:41Z +- hash: BLwSEbi7iNcW8Cu6wMzN93aHasWudPFL3An62k52SzfH4gHaXf4 + id: 47 + level: 47 + protocol_id: 3 + timestamp: 2022-01-25T17:17:47Z diff --git a/internal/postgres/tests/fixtures/contracts.yml b/internal/postgres/tests/fixtures/contracts.yml new file mode 100644 index 000000000..8d8feaeb9 --- /dev/null +++ b/internal/postgres/tests/fixtures/contracts.yml @@ -0,0 +1,1210 @@ +- account_id: 1 + alpha_id: 1 + babylon_id: 4 + delegate_id: 0 + id: 1 + jakarta_id: 0 + level: 1 + manager_id: 0 + tags: 192 + timestamp: 2022-01-25T15:03:39Z +- account_id: 2 + alpha_id: 2 + babylon_id: 5 + delegate_id: 0 + id: 2 + jakarta_id: 0 + level: 1 + manager_id: 0 + tags: 0 + timestamp: 2022-01-25T15:03:39Z +- account_id: 3 + alpha_id: 1 + babylon_id: 4 + delegate_id: 0 + id: 3 + jakarta_id: 0 + level: 1 + manager_id: 0 + tags: 192 + timestamp: 2022-01-25T15:03:39Z +- account_id: 45 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 4 + jakarta_id: 0 + level: 33 + manager_id: 38 + tags: 0 + timestamp: 2022-01-25T16:45:09Z +- account_id: 41 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 5 + jakarta_id: 0 + level: 33 + manager_id: 39 + tags: 8192 + timestamp: 2022-01-25T16:45:09Z +- account_id: 40 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 6 + jakarta_id: 0 + level: 33 + manager_id: 46 + tags: 8192 + timestamp: 2022-01-25T16:45:09Z +- account_id: 47 + alpha_id: 0 + babylon_id: 10 + delegate_id: 0 + id: 7 + jakarta_id: 0 + level: 33 + manager_id: 42 + tags: 16640 + timestamp: 2022-01-25T16:45:09Z +- account_id: 49 + alpha_id: 0 + babylon_id: 11 + delegate_id: 0 + id: 8 + jakarta_id: 0 + level: 33 + manager_id: 35 + tags: 0 + timestamp: 2022-01-25T16:45:09Z +- account_id: 48 + alpha_id: 0 + babylon_id: 12 + delegate_id: 0 + id: 9 + jakarta_id: 0 + level: 33 + manager_id: 36 + tags: 16664 + timestamp: 2022-01-25T16:45:09Z +- account_id: 43 + alpha_id: 0 + babylon_id: 12 + delegate_id: 0 + id: 10 + jakarta_id: 0 + level: 33 + manager_id: 44 + tags: 16664 + timestamp: 2022-01-25T16:45:09Z +- account_id: 58 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 11 + jakarta_id: 0 + level: 34 + manager_id: 53 + tags: 0 + timestamp: 2022-01-25T16:47:37Z +- account_id: 64 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 12 + jakarta_id: 0 + level: 34 + manager_id: 65 + tags: 0 + timestamp: 2022-01-25T16:47:37Z +- account_id: 54 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 13 + jakarta_id: 0 + level: 34 + manager_id: 63 + tags: 8192 + timestamp: 2022-01-25T16:47:37Z +- account_id: 59 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 14 + jakarta_id: 0 + level: 34 + manager_id: 50 + tags: 8192 + timestamp: 2022-01-25T16:47:37Z +- account_id: 55 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 15 + jakarta_id: 0 + level: 34 + manager_id: 56 + tags: 8192 + timestamp: 2022-01-25T16:47:37Z +- account_id: 57 + alpha_id: 0 + babylon_id: 14 + delegate_id: 0 + id: 16 + jakarta_id: 0 + level: 34 + manager_id: 60 + tags: 4 + timestamp: 2022-01-25T16:47:37Z +- account_id: 66 + alpha_id: 0 + babylon_id: 15 + delegate_id: 0 + id: 17 + jakarta_id: 0 + level: 34 + manager_id: 61 + tags: 16640 + timestamp: 2022-01-25T16:47:37Z +- account_id: 51 + alpha_id: 0 + babylon_id: 11 + delegate_id: 0 + id: 18 + jakarta_id: 0 + level: 34 + manager_id: 62 + tags: 0 + timestamp: 2022-01-25T16:47:37Z +- account_id: 71 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 19 + jakarta_id: 0 + level: 35 + manager_id: 67 + tags: 0 + timestamp: 2022-01-25T16:49:57Z +- account_id: 72 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 20 + jakarta_id: 0 + level: 35 + manager_id: 75 + tags: 0 + timestamp: 2022-01-25T16:49:57Z +- account_id: 77 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 21 + jakarta_id: 0 + level: 35 + manager_id: 76 + tags: 0 + timestamp: 2022-01-25T16:49:57Z +- account_id: 68 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 22 + jakarta_id: 0 + level: 35 + manager_id: 78 + tags: 0 + timestamp: 2022-01-25T16:49:57Z +- account_id: 79 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 23 + jakarta_id: 0 + level: 35 + manager_id: 80 + tags: 8192 + timestamp: 2022-01-25T16:49:57Z +- account_id: 81 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 24 + jakarta_id: 0 + level: 35 + manager_id: 73 + tags: 8192 + timestamp: 2022-01-25T16:49:57Z +- account_id: 69 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 25 + jakarta_id: 0 + level: 35 + manager_id: 74 + tags: 8192 + timestamp: 2022-01-25T16:49:57Z +- account_id: 88 + alpha_id: 0 + babylon_id: 17 + delegate_id: 0 + id: 26 + jakarta_id: 0 + level: 36 + manager_id: 92 + tags: 0 + timestamp: 2022-01-25T16:52:19Z +- account_id: 89 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 27 + jakarta_id: 0 + level: 36 + manager_id: 84 + tags: 0 + timestamp: 2022-01-25T16:52:19Z +- account_id: 82 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 28 + jakarta_id: 0 + level: 36 + manager_id: 90 + tags: 0 + timestamp: 2022-01-25T16:52:19Z +- account_id: 85 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 29 + jakarta_id: 0 + level: 36 + manager_id: 83 + tags: 8192 + timestamp: 2022-01-25T16:52:19Z +- account_id: 93 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 30 + jakarta_id: 0 + level: 36 + manager_id: 86 + tags: 8192 + timestamp: 2022-01-25T16:52:19Z +- account_id: 87 + alpha_id: 0 + babylon_id: 18 + delegate_id: 0 + id: 31 + jakarta_id: 0 + level: 36 + manager_id: 94 + tags: 0 + timestamp: 2022-01-25T16:52:19Z +- account_id: 99 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 32 + jakarta_id: 0 + level: 37 + manager_id: 96 + tags: 0 + timestamp: 2022-01-25T16:54:35Z +- account_id: 101 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 33 + jakarta_id: 0 + level: 37 + manager_id: 100 + tags: 0 + timestamp: 2022-01-25T16:54:35Z +- account_id: 98 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 34 + jakarta_id: 0 + level: 37 + manager_id: 104 + tags: 0 + timestamp: 2022-01-25T16:54:35Z +- account_id: 97 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 35 + jakarta_id: 0 + level: 37 + manager_id: 105 + tags: 0 + timestamp: 2022-01-25T16:54:35Z +- account_id: 95 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 36 + jakarta_id: 0 + level: 37 + manager_id: 108 + tags: 8192 + timestamp: 2022-01-25T16:54:35Z +- account_id: 109 + alpha_id: 0 + babylon_id: 18 + delegate_id: 0 + id: 37 + jakarta_id: 0 + level: 37 + manager_id: 94 + tags: 0 + timestamp: 2022-01-25T16:54:35Z +- account_id: 116 + alpha_id: 0 + babylon_id: 19 + delegate_id: 0 + id: 38 + jakarta_id: 0 + level: 38 + manager_id: 117 + tags: 0 + timestamp: 2022-01-25T16:56:47Z +- account_id: 122 + alpha_id: 0 + babylon_id: 14 + delegate_id: 0 + id: 39 + jakarta_id: 0 + level: 38 + manager_id: 123 + tags: 4 + timestamp: 2022-01-25T16:56:47Z +- account_id: 110 + alpha_id: 0 + babylon_id: 14 + delegate_id: 0 + id: 40 + jakarta_id: 0 + level: 38 + manager_id: 124 + tags: 4 + timestamp: 2022-01-25T16:56:47Z +- account_id: 113 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 41 + jakarta_id: 0 + level: 38 + manager_id: 114 + tags: 0 + timestamp: 2022-01-25T16:56:47Z +- account_id: 111 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 42 + jakarta_id: 0 + level: 38 + manager_id: 112 + tags: 0 + timestamp: 2022-01-25T16:56:47Z +- account_id: 118 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 43 + jakarta_id: 0 + level: 38 + manager_id: 119 + tags: 8192 + timestamp: 2022-01-25T16:56:47Z +- account_id: 120 + alpha_id: 0 + babylon_id: 20 + delegate_id: 0 + id: 44 + jakarta_id: 0 + level: 38 + manager_id: 115 + tags: 0 + timestamp: 2022-01-25T16:56:47Z +- account_id: 137 + alpha_id: 0 + babylon_id: 14 + delegate_id: 0 + id: 45 + jakarta_id: 0 + level: 39 + manager_id: 130 + tags: 4 + timestamp: 2022-01-25T16:59:07Z +- account_id: 132 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 46 + jakarta_id: 0 + level: 39 + manager_id: 126 + tags: 0 + timestamp: 2022-01-25T16:59:07Z +- account_id: 133 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 47 + jakarta_id: 0 + level: 39 + manager_id: 139 + tags: 0 + timestamp: 2022-01-25T16:59:07Z +- account_id: 129 + alpha_id: 0 + babylon_id: 21 + delegate_id: 0 + id: 48 + jakarta_id: 0 + level: 39 + manager_id: 135 + tags: 0 + timestamp: 2022-01-25T16:59:07Z +- account_id: 141 + alpha_id: 0 + babylon_id: 20 + delegate_id: 0 + id: 49 + jakarta_id: 0 + level: 39 + manager_id: 115 + tags: 0 + timestamp: 2022-01-25T16:59:07Z +- account_id: 156 + alpha_id: 0 + babylon_id: 22 + delegate_id: 0 + id: 50 + jakarta_id: 0 + level: 40 + manager_id: 158 + tags: 0 + timestamp: 2022-01-25T17:01:51Z +- account_id: 145 + alpha_id: 0 + babylon_id: 14 + delegate_id: 0 + id: 51 + jakarta_id: 0 + level: 40 + manager_id: 159 + tags: 4 + timestamp: 2022-01-25T17:01:51Z +- account_id: 146 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 52 + jakarta_id: 0 + level: 40 + manager_id: 157 + tags: 0 + timestamp: 2022-01-25T17:01:51Z +- account_id: 148 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 53 + jakarta_id: 0 + level: 40 + manager_id: 151 + tags: 0 + timestamp: 2022-01-25T17:01:51Z +- account_id: 160 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 54 + jakarta_id: 0 + level: 40 + manager_id: 149 + tags: 8192 + timestamp: 2022-01-25T17:01:51Z +- account_id: 154 + alpha_id: 0 + babylon_id: 23 + delegate_id: 0 + id: 55 + jakarta_id: 0 + level: 40 + manager_id: 144 + tags: 0 + timestamp: 2022-01-25T17:01:51Z +- account_id: 150 + alpha_id: 0 + babylon_id: 24 + delegate_id: 0 + id: 56 + jakarta_id: 0 + level: 40 + manager_id: 147 + tags: 256 + timestamp: 2022-01-25T17:01:51Z +- account_id: 182 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 57 + jakarta_id: 0 + level: 41 + manager_id: 167 + tags: 0 + timestamp: 2022-01-25T17:04:35Z +- account_id: 188 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 58 + jakarta_id: 0 + level: 41 + manager_id: 176 + tags: 0 + timestamp: 2022-01-25T17:04:35Z +- account_id: 172 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 59 + jakarta_id: 0 + level: 41 + manager_id: 190 + tags: 8192 + timestamp: 2022-01-25T17:04:35Z +- account_id: 168 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 60 + jakarta_id: 0 + level: 41 + manager_id: 191 + tags: 8192 + timestamp: 2022-01-25T17:04:35Z +- account_id: 184 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 61 + jakarta_id: 0 + level: 41 + manager_id: 185 + tags: 8192 + timestamp: 2022-01-25T17:04:35Z +- account_id: 162 + alpha_id: 0 + babylon_id: 25 + delegate_id: 0 + id: 62 + jakarta_id: 0 + level: 41 + manager_id: 163 + tags: 16 + timestamp: 2022-01-25T17:04:35Z +- account_id: 179 + alpha_id: 0 + babylon_id: 25 + delegate_id: 0 + id: 63 + jakarta_id: 0 + level: 41 + manager_id: 180 + tags: 16 + timestamp: 2022-01-25T17:04:35Z +- account_id: 164 + alpha_id: 0 + babylon_id: 24 + delegate_id: 0 + id: 64 + jakarta_id: 0 + level: 41 + manager_id: 147 + tags: 256 + timestamp: 2022-01-25T17:04:35Z +- account_id: 186 + alpha_id: 0 + babylon_id: 27 + delegate_id: 0 + id: 65 + jakarta_id: 0 + level: 41 + manager_id: 169 + tags: 192 + timestamp: 2022-01-25T17:04:35Z +- account_id: 187 + alpha_id: 0 + babylon_id: 10 + delegate_id: 0 + id: 66 + jakarta_id: 0 + level: 41 + manager_id: 165 + tags: 16640 + timestamp: 2022-01-25T17:04:35Z +- account_id: 166 + alpha_id: 0 + babylon_id: 11 + delegate_id: 0 + id: 67 + jakarta_id: 0 + level: 41 + manager_id: 181 + tags: 0 + timestamp: 2022-01-25T17:04:35Z +- account_id: 171 + alpha_id: 0 + babylon_id: 12 + delegate_id: 0 + id: 68 + jakarta_id: 0 + level: 41 + manager_id: 174 + tags: 16664 + timestamp: 2022-01-25T17:04:35Z +- account_id: 173 + alpha_id: 0 + babylon_id: 12 + delegate_id: 0 + id: 69 + jakarta_id: 0 + level: 41 + manager_id: 170 + tags: 16664 + timestamp: 2022-01-25T17:04:35Z +- account_id: 195 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 70 + jakarta_id: 0 + level: 42 + manager_id: 210 + tags: 0 + timestamp: 2022-01-25T17:07:03Z +- account_id: 211 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 71 + jakarta_id: 0 + level: 42 + manager_id: 212 + tags: 0 + timestamp: 2022-01-25T17:07:03Z +- account_id: 201 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 72 + jakarta_id: 0 + level: 42 + manager_id: 193 + tags: 0 + timestamp: 2022-01-25T17:07:03Z +- account_id: 196 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 73 + jakarta_id: 0 + level: 42 + manager_id: 213 + tags: 8192 + timestamp: 2022-01-25T17:07:03Z +- account_id: 198 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 74 + jakarta_id: 0 + level: 42 + manager_id: 214 + tags: 8192 + timestamp: 2022-01-25T17:07:03Z +- account_id: 199 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 75 + jakarta_id: 0 + level: 42 + manager_id: 207 + tags: 8192 + timestamp: 2022-01-25T17:07:03Z +- account_id: 208 + alpha_id: 0 + babylon_id: 14 + delegate_id: 0 + id: 76 + jakarta_id: 0 + level: 42 + manager_id: 200 + tags: 4 + timestamp: 2022-01-25T17:07:03Z +- account_id: 197 + alpha_id: 0 + babylon_id: 15 + delegate_id: 0 + id: 77 + jakarta_id: 0 + level: 42 + manager_id: 209 + tags: 16640 + timestamp: 2022-01-25T17:07:03Z +- account_id: 205 + alpha_id: 0 + babylon_id: 11 + delegate_id: 0 + id: 78 + jakarta_id: 0 + level: 42 + manager_id: 206 + tags: 0 + timestamp: 2022-01-25T17:07:03Z +- account_id: 225 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 79 + jakarta_id: 0 + level: 43 + manager_id: 226 + tags: 0 + timestamp: 2022-01-25T17:09:21Z +- account_id: 218 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 80 + jakarta_id: 0 + level: 43 + manager_id: 221 + tags: 0 + timestamp: 2022-01-25T17:09:21Z +- account_id: 222 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 81 + jakarta_id: 0 + level: 43 + manager_id: 223 + tags: 0 + timestamp: 2022-01-25T17:09:21Z +- account_id: 227 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 82 + jakarta_id: 0 + level: 43 + manager_id: 219 + tags: 0 + timestamp: 2022-01-25T17:09:21Z +- account_id: 220 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 83 + jakarta_id: 0 + level: 43 + manager_id: 217 + tags: 8192 + timestamp: 2022-01-25T17:09:21Z +- account_id: 228 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 84 + jakarta_id: 0 + level: 43 + manager_id: 215 + tags: 8192 + timestamp: 2022-01-25T17:09:21Z +- account_id: 216 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 85 + jakarta_id: 0 + level: 43 + manager_id: 229 + tags: 8192 + timestamp: 2022-01-25T17:09:21Z +- account_id: 232 + alpha_id: 0 + babylon_id: 17 + delegate_id: 0 + id: 86 + jakarta_id: 0 + level: 44 + manager_id: 243 + tags: 0 + timestamp: 2022-01-25T17:11:23Z +- account_id: 251 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 87 + jakarta_id: 0 + level: 44 + manager_id: 244 + tags: 0 + timestamp: 2022-01-25T17:11:23Z +- account_id: 245 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 88 + jakarta_id: 0 + level: 44 + manager_id: 252 + tags: 0 + timestamp: 2022-01-25T17:11:23Z +- account_id: 253 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 89 + jakarta_id: 0 + level: 44 + manager_id: 246 + tags: 0 + timestamp: 2022-01-25T17:11:23Z +- account_id: 254 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 90 + jakarta_id: 0 + level: 44 + manager_id: 247 + tags: 0 + timestamp: 2022-01-25T17:11:23Z +- account_id: 239 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 91 + jakarta_id: 0 + level: 44 + manager_id: 233 + tags: 8192 + timestamp: 2022-01-25T17:11:23Z +- account_id: 248 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 92 + jakarta_id: 0 + level: 44 + manager_id: 234 + tags: 8192 + timestamp: 2022-01-25T17:11:23Z +- account_id: 249 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 93 + jakarta_id: 0 + level: 44 + manager_id: 240 + tags: 8192 + timestamp: 2022-01-25T17:11:23Z +- account_id: 250 + alpha_id: 0 + babylon_id: 18 + delegate_id: 0 + id: 94 + jakarta_id: 0 + level: 44 + manager_id: 236 + tags: 0 + timestamp: 2022-01-25T17:11:23Z +- account_id: 241 + alpha_id: 0 + babylon_id: 11 + delegate_id: 0 + id: 95 + jakarta_id: 0 + level: 44 + manager_id: 237 + tags: 0 + timestamp: 2022-01-25T17:11:23Z +- account_id: 238 + alpha_id: 0 + babylon_id: 12 + delegate_id: 0 + id: 96 + jakarta_id: 0 + level: 44 + manager_id: 230 + tags: 16664 + timestamp: 2022-01-25T17:11:23Z +- account_id: 242 + alpha_id: 0 + babylon_id: 12 + delegate_id: 0 + id: 97 + jakarta_id: 0 + level: 44 + manager_id: 235 + tags: 16664 + timestamp: 2022-01-25T17:11:23Z +- account_id: 283 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 98 + jakarta_id: 0 + level: 45 + manager_id: 270 + tags: 0 + timestamp: 2022-01-25T17:13:29Z +- account_id: 272 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 99 + jakarta_id: 0 + level: 45 + manager_id: 280 + tags: 0 + timestamp: 2022-01-25T17:13:29Z +- account_id: 279 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 100 + jakarta_id: 0 + level: 45 + manager_id: 267 + tags: 0 + timestamp: 2022-01-25T17:13:29Z +- account_id: 261 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 101 + jakarta_id: 0 + level: 45 + manager_id: 255 + tags: 0 + timestamp: 2022-01-25T17:13:29Z +- account_id: 271 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 102 + jakarta_id: 0 + level: 45 + manager_id: 268 + tags: 0 + timestamp: 2022-01-25T17:13:29Z +- account_id: 278 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 103 + jakarta_id: 0 + level: 45 + manager_id: 277 + tags: 8192 + timestamp: 2022-01-25T17:13:29Z +- account_id: 256 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 104 + jakarta_id: 0 + level: 45 + manager_id: 262 + tags: 8192 + timestamp: 2022-01-25T17:13:29Z +- account_id: 257 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 105 + jakarta_id: 0 + level: 45 + manager_id: 260 + tags: 8192 + timestamp: 2022-01-25T17:13:29Z +- account_id: 281 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 106 + jakarta_id: 0 + level: 45 + manager_id: 263 + tags: 8192 + timestamp: 2022-01-25T17:13:29Z +- account_id: 273 + alpha_id: 0 + babylon_id: 14 + delegate_id: 0 + id: 107 + jakarta_id: 0 + level: 45 + manager_id: 274 + tags: 4 + timestamp: 2022-01-25T17:13:29Z +- account_id: 275 + alpha_id: 0 + babylon_id: 18 + delegate_id: 0 + id: 108 + jakarta_id: 0 + level: 45 + manager_id: 236 + tags: 0 + timestamp: 2022-01-25T17:13:29Z +- account_id: 269 + alpha_id: 0 + babylon_id: 10 + delegate_id: 0 + id: 109 + jakarta_id: 0 + level: 45 + manager_id: 264 + tags: 16640 + timestamp: 2022-01-25T17:13:29Z +- account_id: 265 + alpha_id: 0 + babylon_id: 11 + delegate_id: 0 + id: 110 + jakarta_id: 0 + level: 45 + manager_id: 276 + tags: 0 + timestamp: 2022-01-25T17:13:29Z +- account_id: 307 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 111 + jakarta_id: 0 + level: 47 + manager_id: 287 + tags: 0 + timestamp: 2022-01-25T17:17:47Z +- account_id: 303 + alpha_id: 0 + babylon_id: 7 + delegate_id: 0 + id: 112 + jakarta_id: 0 + level: 47 + manager_id: 295 + tags: 0 + timestamp: 2022-01-25T17:17:47Z +- account_id: 289 + alpha_id: 0 + babylon_id: 19 + delegate_id: 0 + id: 113 + jakarta_id: 0 + level: 47 + manager_id: 290 + tags: 0 + timestamp: 2022-01-25T17:17:47Z +- account_id: 291 + alpha_id: 0 + babylon_id: 14 + delegate_id: 0 + id: 114 + jakarta_id: 0 + level: 47 + manager_id: 288 + tags: 4 + timestamp: 2022-01-25T17:17:47Z +- account_id: 285 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 115 + jakarta_id: 0 + level: 47 + manager_id: 292 + tags: 0 + timestamp: 2022-01-25T17:17:47Z +- account_id: 286 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 116 + jakarta_id: 0 + level: 47 + manager_id: 301 + tags: 8192 + timestamp: 2022-01-25T17:17:47Z +- account_id: 304 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 117 + jakarta_id: 0 + level: 47 + manager_id: 293 + tags: 8192 + timestamp: 2022-01-25T17:17:47Z +- account_id: 302 + alpha_id: 0 + babylon_id: 8 + delegate_id: 0 + id: 118 + jakarta_id: 0 + level: 47 + manager_id: 294 + tags: 8192 + timestamp: 2022-01-25T17:17:47Z +- account_id: 297 + alpha_id: 0 + babylon_id: 16 + delegate_id: 0 + id: 119 + jakarta_id: 0 + level: 47 + manager_id: 268 + tags: 0 + timestamp: 2022-01-25T17:17:47Z +- account_id: 298 + alpha_id: 0 + babylon_id: 15 + delegate_id: 0 + id: 120 + jakarta_id: 0 + level: 47 + manager_id: 305 + tags: 16640 + timestamp: 2022-01-25T17:17:47Z +- account_id: 300 + alpha_id: 0 + babylon_id: 20 + delegate_id: 0 + id: 121 + jakarta_id: 0 + level: 47 + manager_id: 296 + tags: 0 + timestamp: 2022-01-25T17:17:47Z diff --git a/internal/postgres/tests/fixtures/global_constants.yml b/internal/postgres/tests/fixtures/global_constants.yml new file mode 100644 index 000000000..59fc7a7a0 --- /dev/null +++ b/internal/postgres/tests/fixtures/global_constants.yml @@ -0,0 +1,15 @@ +- id: 1 + timestamp: '2022-01-23 17:10:55+00' + level: 30 + address: expruv45XuhGc4fdRzTwwXpmp2ZyqwmUYeMmnKbxkCn5Q8uCtwkhM6 + value: 7b7d +- id: 2 + timestamp: '2022-01-23 17:11:03+00' + level: 31 + address: expru5X5fvCer8tbRkSAtwyVCs9FUCq46JQG7QCAkhZSumjbZBUGzb + value: 7b7d +- id: 3 + timestamp: '2022-01-23 17:12:23+00' + level: 32 + address: expruwxajrCoMUcJrPzVdLxzX3UyKVTNwRhLSQbLiK5JGdaMU7w1Bp + value: 7b7d diff --git a/internal/postgres/tests/fixtures/migrations.yml b/internal/postgres/tests/fixtures/migrations.yml new file mode 100644 index 000000000..203ddb636 --- /dev/null +++ b/internal/postgres/tests/fixtures/migrations.yml @@ -0,0 +1,48 @@ +- contract_id: 1 + hash: null + id: 1 + kind: 1 + level: 1 + prev_protocol_id: 0 + protocol_id: 1 + timestamp: 2022-01-25T15:03:39Z +- contract_id: 2 + hash: null + id: 2 + kind: 1 + level: 1 + prev_protocol_id: 0 + protocol_id: 1 + timestamp: 2022-01-25T15:03:39Z +- contract_id: 3 + hash: null + id: 3 + kind: 1 + level: 1 + prev_protocol_id: 0 + protocol_id: 1 + timestamp: 2022-01-25T15:03:39Z +- contract_id: 1 + hash: null + id: 4 + kind: 3 + level: 2 + prev_protocol_id: 1 + protocol_id: 3 + timestamp: 2022-01-25T15:10:11Z +- contract_id: 2 + hash: null + id: 5 + kind: 3 + level: 2 + prev_protocol_id: 1 + protocol_id: 3 + timestamp: 2022-01-25T15:10:11Z +- contract_id: 3 + hash: null + id: 6 + kind: 3 + level: 2 + prev_protocol_id: 1 + protocol_id: 3 + timestamp: 2022-01-25T15:10:11Z diff --git a/internal/postgres/tests/fixtures/operations.yml b/internal/postgres/tests/fixtures/operations.yml new file mode 100644 index 000000000..587bb0f7b --- /dev/null +++ b/internal/postgres/tests/fixtures/operations.yml @@ -0,0 +1,6720 @@ +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 2468 + content_index: 0 + counter: 2 + deffated_storage: '[{"int":"1"},{"int":"2500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 1 + initiator_id: 0 + internal: false + kind: 1 + level: 2 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:10:11Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 3 + deffated_storage: '[{"int":"1"},{"int":"5000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 2 + initiator_id: 0 + internal: false + kind: 1 + level: 3 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:14:03Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 4 + deffated_storage: '[{"int":"1"},{"int":"7500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 3 + initiator_id: 0 + internal: false + kind: 1 + level: 4 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:17:55Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 5 + deffated_storage: '[{"int":"1"},{"int":"10000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 4 + initiator_id: 0 + internal: false + kind: 1 + level: 5 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:22:15Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 6 + deffated_storage: '[{"int":"1"},{"int":"12500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 5 + initiator_id: 0 + internal: false + kind: 1 + level: 6 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:25:49Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 7 + deffated_storage: '[{"int":"1"},{"int":"15000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 6 + initiator_id: 0 + internal: false + kind: 1 + level: 7 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:29:29Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 8 + deffated_storage: '[{"int":"1"},{"int":"17500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 7 + initiator_id: 0 + internal: false + kind: 1 + level: 8 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:33:11Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 9 + deffated_storage: '[{"int":"1"},{"int":"20000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 8 + initiator_id: 0 + internal: false + kind: 1 + level: 9 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:36:21Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 10 + deffated_storage: '[{"int":"1"},{"int":"22500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 9 + initiator_id: 0 + internal: false + kind: 1 + level: 10 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:39:27Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 11 + deffated_storage: '[{"int":"1"},{"int":"25000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 10 + initiator_id: 0 + internal: false + kind: 1 + level: 11 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:42:29Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 12 + deffated_storage: '[{"int":"1"},{"int":"27500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 11 + initiator_id: 0 + internal: false + kind: 1 + level: 12 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:45:33Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 13 + deffated_storage: '[{"int":"1"},{"int":"30000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 12 + initiator_id: 0 + internal: false + kind: 1 + level: 13 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:48:05Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 14 + deffated_storage: '[{"int":"1"},{"int":"32500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 13 + initiator_id: 0 + internal: false + kind: 1 + level: 14 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:50:45Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 15 + deffated_storage: '[{"int":"1"},{"int":"35000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 14 + initiator_id: 0 + internal: false + kind: 1 + level: 15 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:53:43Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 16 + deffated_storage: '[{"int":"1"},{"int":"37500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 15 + initiator_id: 0 + internal: false + kind: 1 + level: 16 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:56:51Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 17 + deffated_storage: '[{"int":"1"},{"int":"40000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 16 + initiator_id: 0 + internal: false + kind: 1 + level: 17 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T15:59:31Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 18 + deffated_storage: '[{"int":"1"},{"int":"42500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 17 + initiator_id: 0 + internal: false + kind: 1 + level: 18 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:02:01Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 19 + deffated_storage: '[{"int":"1"},{"int":"45000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 18 + initiator_id: 0 + internal: false + kind: 1 + level: 19 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:04:33Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 20 + deffated_storage: '[{"int":"1"},{"int":"47500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 19 + initiator_id: 0 + internal: false + kind: 1 + level: 20 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:08:31Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 21 + deffated_storage: '[{"int":"1"},{"int":"50000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 20 + initiator_id: 0 + internal: false + kind: 1 + level: 21 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:11:31Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 22 + deffated_storage: '[{"int":"1"},{"int":"52500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 21 + initiator_id: 0 + internal: false + kind: 1 + level: 22 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:14:17Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 23 + deffated_storage: '[{"int":"1"},{"int":"55000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 22 + initiator_id: 0 + internal: false + kind: 1 + level: 23 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:17:27Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 24 + deffated_storage: '[{"int":"1"},{"int":"57500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 23 + initiator_id: 0 + internal: false + kind: 1 + level: 24 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:20:15Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 25 + deffated_storage: '[{"int":"1"},{"int":"60000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 24 + initiator_id: 0 + internal: false + kind: 1 + level: 25 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:23:21Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 26 + deffated_storage: '[{"int":"1"},{"int":"62500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 25 + initiator_id: 0 + internal: false + kind: 1 + level: 26 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:26:01Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 27 + deffated_storage: '[{"int":"1"},{"int":"65000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 26 + initiator_id: 0 + internal: false + kind: 1 + level: 27 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:28:55Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 28 + deffated_storage: '[{"int":"1"},{"int":"67500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 27 + initiator_id: 0 + internal: false + kind: 1 + level: 28 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:31:47Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 29 + deffated_storage: '[{"int":"1"},{"int":"70000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 28 + initiator_id: 0 + internal: false + kind: 1 + level: 29 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:34:57Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 30 + deffated_storage: '[{"int":"1"},{"int":"72500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 29 + initiator_id: 0 + internal: false + kind: 1 + level: 30 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:37:35Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 31 + deffated_storage: '[{"int":"1"},{"int":"75000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 30 + initiator_id: 0 + internal: false + kind: 1 + level: 31 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:40:29Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 32 + deffated_storage: '[{"int":"1"},{"int":"77500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 31 + initiator_id: 0 + internal: false + kind: 1 + level: 32 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:43:03Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 33 + deffated_storage: '[{"int":"1"},{"int":"80000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 32 + initiator_id: 0 + internal: false + kind: 1 + level: 33 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:45:09Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 45 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x62ffe376145e6f12906ef9aee02213fcbfb617e89d0fd02c7b24e7bbd8220fd5 + id: 33 + initiator_id: 38 + internal: false + kind: 2 + level: 33 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 38 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:45:09Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 210250 + consumed_gas: 1705387 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"4"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]},{"prim":"Elt","args":[{"int":"2"},{"prim":"Pair","args":[{"int":"120"},{"int":"20"}]}]},{"prim":"Elt","args":[{"int":"3"},{"prim":"Pair","args":[{"int":"50"},{"int":"60"}]}]}]]}' + delegate_id: 0 + destination_id: 41 + entrypoint: null + errors: null + fee: 1005 + gas_limit: 1806 + hash: 0xd1fdb6347a1f5654de681e286550e750671f25addb053606e01ac590628250b9 + id: 34 + initiator_id: 39 + internal: false + kind: 2 + level: 33 + nonce: null + paid_storage_size_diff: 584 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 39 + status: 1 + storage_limit: 841 + storage_size: 584 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:45:09Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 210250 + consumed_gas: 1705387 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"5"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]},{"prim":"Elt","args":[{"int":"2"},{"prim":"Pair","args":[{"int":"120"},{"int":"20"}]}]},{"prim":"Elt","args":[{"int":"3"},{"prim":"Pair","args":[{"int":"50"},{"int":"60"}]}]}]]}' + delegate_id: 0 + destination_id: 40 + entrypoint: null + errors: null + fee: 1005 + gas_limit: 1806 + hash: 0x2ab42c7a778d78be5ff00c8ba76d9ffda0b74a4cd6c40f6e56e79ad889a40a0e + id: 35 + initiator_id: 46 + internal: false + kind: 2 + level: 33 + nonce: null + paid_storage_size_diff: 584 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 46 + status: 1 + storage_limit: 841 + storage_size: 584 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:45:09Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 9 + burned: 2268000 + consumed_gas: 6285069 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[[{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"0001f09131ddf7a88db40c11ebf10c93f2b305a438e0"},{"bytes":"0133604c1ee2391a5db33300d8c7ec332455525a4d00"}]},{"prim":"Pair","args":[{"int":"2"},{"int":"6"}]}]},{"prim":"Pair","args":[{"int":"7"},{"int":"8"}]},{"int":"9"},{"int":"10"}],{"int":"11"}]}' + delegate_id: 0 + destination_id: 47 + entrypoint: null + errors: null + fee: 9199 + gas_limit: 6386 + hash: 0xef8ad8f3de22f0c9ead0a001e93895efdb242c57a5190f5dd9fc4af1ebe1ae85 + id: 36 + initiator_id: 42 + internal: false + kind: 2 + level: 33 + nonce: null + paid_storage_size_diff: 8815 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 42 + status: 1 + storage_limit: 9072 + storage_size: 8815 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:45:09Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 2 + burned: 1672500 + consumed_gas: 3442508 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"7"},{"int":"12"}]}' + delegate_id: 0 + destination_id: 49 + entrypoint: null + errors: null + fee: 6974 + gas_limit: 3543 + hash: 0x526399f89c7c5525fb51de267234caf808defb2394e94a9a52ace6088a2394b3 + id: 37 + initiator_id: 35 + internal: false + kind: 2 + level: 33 + nonce: null + paid_storage_size_diff: 6433 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 35 + status: 1 + storage_limit: 6690 + storage_size: 6433 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:45:09Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 4 + burned: 3030000 + consumed_gas: 8932729 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[[{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"1000"},{"int":"13"}]},{"prim":"Pair","args":[{"int":"14"},[]]}]},{"prim":"Pair","args":[{"int":"15"},{"prim":"False"}]},{"int":"0"},{"int":"16"}],{"prim":"Pair","args":[{"prim":"Pair","args":[{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"00014577b523d117611769033e40573912b63e5bb6dc"},{"bytes":"0002e63a8499e8e4e4efb97968b146ca642f0a942e5d"}]},{"prim":"Pair","args":[{"bytes":"0002e0269b29d74638e31dbc79dd118347060252a3b1"},{"prim":"None"}]}]},{"bytes":"016c01640a1acd661bb46408e7a854899de4ea451100"}]},{"prim":"None"}]}]}' + delegate_id: 0 + destination_id: 48 + entrypoint: null + errors: null + fee: 12951 + gas_limit: 9033 + hash: 0x06d7c41639ac7e069f47c98fadae37e2762f1e8a025dbd1645cfba1a9ecc0f88 + id: 38 + initiator_id: 36 + internal: false + kind: 2 + level: 33 + nonce: null + paid_storage_size_diff: 11863 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 36 + status: 1 + storage_limit: 12120 + storage_size: 11863 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:45:09Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 203250 + consumed_gas: 1700385 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"32"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 85 + entrypoint: null + errors: null + fee: 977 + gas_limit: 1801 + hash: 0x684af13d41eef0ea543889ce091b66cf0f1db26ca54d73bf5ab8acb635d20eda + id: 61 + initiator_id: 83 + internal: false + kind: 2 + level: 36 + nonce: null + paid_storage_size_diff: 556 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 83 + status: 1 + storage_limit: 813 + storage_size: 556 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:52:19Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 122250 + consumed_gas: 1433807 + content_index: 1 + counter: 539 + deffated_storage: '{"bytes":"0184e9903a5e129ee46a4a3e523273ce537ae25443"}' + delegate_id: 0 + destination_id: 145 + entrypoint: null + errors: null + fee: 731 + gas_limit: 1534 + hash: 0xdac57765c2e01d3474a47bcdaef114358dcce0ccf59f45dbc1239b69f76e55e9 + id: 99 + initiator_id: 159 + internal: false + kind: 2 + level: 40 + nonce: null + paid_storage_size_diff: 232 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 159 + status: 1 + storage_limit: 489 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 4 + burned: 3030000 + consumed_gas: 8932729 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[[{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"1000"},{"int":"17"}]},{"prim":"Pair","args":[{"int":"18"},[]]}]},{"prim":"Pair","args":[{"int":"19"},{"prim":"False"}]},{"int":"0"},{"int":"20"}],{"prim":"Pair","args":[{"prim":"Pair","args":[{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"0001e654270a14d846be988220074f71b8da3d239682"},{"bytes":"0002d320e7a6c88ad303246f7bd1e75df9a2dc1a2bb9"}]},{"prim":"Pair","args":[{"bytes":"00020c2dee271eb9b0d774a3fdc68305efb37527fb14"},{"prim":"None"}]}]},{"bytes":"016c01640a1acd661bb46408e7a854899de4ea451100"}]},{"prim":"None"}]}]}' + delegate_id: 0 + destination_id: 43 + entrypoint: null + errors: null + fee: 12951 + gas_limit: 9033 + hash: 0xbd87faef58cd57051b819414db8bb17b0c865962fc095329864a0cd1aede725d + id: 39 + initiator_id: 44 + internal: false + kind: 2 + level: 33 + nonce: null + paid_storage_size_diff: 11863 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 44 + status: 1 + storage_limit: 12120 + storage_size: 11863 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:45:09Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 34 + deffated_storage: '[{"int":"1"},{"int":"82500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 40 + initiator_id: 0 + internal: false + kind: 1 + level: 34 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:47:37Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 58 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x849b45cd4d93336389f3eca6fe71e3bb174c1d5803af5bba40c7395c0f63682a + id: 41 + initiator_id: 53 + internal: false + kind: 2 + level: 34 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 53 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:47:37Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 64 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x63eb20910fc871b445678908ab0bbddbd839a245b678ea4e21070db326838b04 + id: 42 + initiator_id: 65 + internal: false + kind: 2 + level: 34 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 65 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:47:37Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 206000 + consumed_gas: 1704429 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"21"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 54 + entrypoint: null + errors: null + fee: 988 + gas_limit: 1805 + hash: 0xe5013f43896659a921d5b167ae9676453d5e6d6c46fae1f9a43e70ca7470529f + id: 43 + initiator_id: 63 + internal: false + kind: 2 + level: 34 + nonce: null + paid_storage_size_diff: 567 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 63 + status: 1 + storage_limit: 824 + storage_size: 567 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:47:37Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 206000 + consumed_gas: 1704429 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"22"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 59 + entrypoint: null + errors: null + fee: 988 + gas_limit: 1805 + hash: 0xa32f7a70ee5ff781534bc77c7ba4be350afeba9e8a4ec9aa36cdf620fcd03416 + id: 44 + initiator_id: 50 + internal: false + kind: 2 + level: 34 + nonce: null + paid_storage_size_diff: 567 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 50 + status: 1 + storage_limit: 824 + storage_size: 567 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:47:37Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 227000 + consumed_gas: 1724765 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"23"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 55 + entrypoint: null + errors: null + fee: 1074 + gas_limit: 1825 + hash: 0x3edd7f773e7e0c601bf3bb3985f3af74495b37df68c8660e94cc1ececd76441f + id: 45 + initiator_id: 56 + internal: false + kind: 2 + level: 34 + nonce: null + paid_storage_size_diff: 651 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 56 + status: 1 + storage_limit: 908 + storage_size: 651 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:47:37Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 122250 + consumed_gas: 1433807 + content_index: 0 + counter: 540 + deffated_storage: '{"bytes":"02a6ff88d1024e86a2554e740a4a03ab6adc2a34dc"}' + delegate_id: 0 + destination_id: 57 + entrypoint: null + errors: null + fee: 668 + gas_limit: 1534 + hash: 0xf81c22edd0948d811c8d8aa140c2965d0a736056f85574be91dc0eb8dc16668f + id: 46 + initiator_id: 60 + internal: false + kind: 2 + level: 34 + nonce: null + paid_storage_size_diff: 232 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 60 + status: 1 + storage_limit: 489 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:47:37Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 6 + burned: 1300500 + consumed_gas: 4219348 + content_index: 1 + counter: 539 + deffated_storage: '[{"prim":"Pair","args":[{"bytes":"0001832294c44b00797fd9fdec20ee00c8d9f1e756e5"},{"prim":"Pair","args":[{"int":"2"},{"int":"24"}]}]},{"prim":"Pair","args":[{"int":"25"},{"int":"26"}]},{"prim":"False"},{"int":"27"}]' + delegate_id: 0 + destination_id: 66 + entrypoint: null + errors: null + fee: 5323 + gas_limit: 4320 + hash: 0xef20c798664e7ac3ede73087b18e7091cd4c4e03c7f1ac3faa2d6432fa28db68 + id: 47 + initiator_id: 61 + internal: false + kind: 2 + level: 34 + nonce: null + paid_storage_size_diff: 4945 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 61 + status: 1 + storage_limit: 5202 + storage_size: 4945 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:47:37Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 2 + burned: 2691500 + consumed_gas: 4478812 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"7"},{"int":"28"}]}' + delegate_id: 0 + destination_id: 51 + entrypoint: null + errors: null + fee: 11153 + gas_limit: 4579 + hash: 0xe31c433f27552caf38c73675da20c0f989cf4765b5e9bfee4aac13306beabfe1 + id: 48 + initiator_id: 62 + internal: false + kind: 2 + level: 34 + nonce: null + paid_storage_size_diff: 10509 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 62 + status: 1 + storage_limit: 10766 + storage_size: 10509 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:47:37Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 35 + deffated_storage: '[{"int":"1"},{"int":"85000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 49 + initiator_id: 0 + internal: false + kind: 1 + level: 35 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:49:57Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 2 + counter: 540 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 71 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x2ef689e5a566ab14b9df1cd09baafa09130ffdbc694d68bfe7dd0bf56d8a3d25 + id: 50 + initiator_id: 67 + internal: false + kind: 2 + level: 35 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 67 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:49:57Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 72 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0xdbbd9cf441aa5c73087d6f1d378398658d8c4ee33425c456d8ac0ccb747696ae + id: 51 + initiator_id: 75 + internal: false + kind: 2 + level: 35 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 75 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:49:57Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 2 + counter: 540 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 77 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0xc20b2a756f5e070ccddbff375d5077ff5342b88866e7c42921f29e7583a24b85 + id: 52 + initiator_id: 76 + internal: false + kind: 2 + level: 35 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 76 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:49:57Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 68 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0xb3b2afcd398bcba73c0984fe1bec112dc47473e637a7ad7f32466d5965a71057 + id: 53 + initiator_id: 78 + internal: false + kind: 2 + level: 35 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 78 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:49:57Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 205750 + consumed_gas: 1704425 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"29"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 79 + entrypoint: null + errors: null + fee: 987 + gas_limit: 1805 + hash: 0xf79262db03b3319e4e9f9ed4244c19285287462faef4efdf03fd3daf22d54bfd + id: 54 + initiator_id: 80 + internal: false + kind: 2 + level: 35 + nonce: null + paid_storage_size_diff: 566 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 80 + status: 1 + storage_limit: 823 + storage_size: 566 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:49:57Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 205750 + consumed_gas: 1704425 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"30"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 81 + entrypoint: null + errors: null + fee: 987 + gas_limit: 1805 + hash: 0x0ab2d43df7d401fe9fff6cbfcc109be502e8139beecfbde4236d298bbdc581f2 + id: 55 + initiator_id: 73 + internal: false + kind: 2 + level: 35 + nonce: null + paid_storage_size_diff: 566 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 73 + status: 1 + storage_limit: 823 + storage_size: 566 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:49:57Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 227000 + consumed_gas: 1724765 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"31"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 69 + entrypoint: null + errors: null + fee: 1074 + gas_limit: 1825 + hash: 0x9fd46865cf08396ddf5876aaee38742564bf9fadd294c7f9147a2a1de2064231 + id: 56 + initiator_id: 74 + internal: false + kind: 2 + level: 35 + nonce: null + paid_storage_size_diff: 651 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 74 + status: 1 + storage_limit: 908 + storage_size: 651 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:49:57Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 36 + deffated_storage: '[{"int":"1"},{"int":"87500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 57 + initiator_id: 0 + internal: false + kind: 1 + level: 36 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:52:19Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 86000 + consumed_gas: 1408014 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Some","args":[{"bytes":"0001000000000000000000000000000000000000000000000000000000000000"}]}' + delegate_id: 0 + destination_id: 88 + entrypoint: null + errors: null + fee: 536 + gas_limit: 1509 + hash: 0xf8c91a523176510d15903840b2d5990a63603fa3bb65b5ebef472d2dbde4a63c + id: 58 + initiator_id: 92 + internal: false + kind: 2 + level: 36 + nonce: null + paid_storage_size_diff: 87 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 92 + status: 1 + storage_limit: 344 + storage_size: 87 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:52:19Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 2 + counter: 540 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 89 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x163066d6fe58d5c4f7d2bc2dd13717abe1ee9ec5377547240eadaa852903caa2 + id: 59 + initiator_id: 84 + internal: false + kind: 2 + level: 36 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 84 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:52:19Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 82 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0xd382a52fcf75075a9e9a2fb9a945d42c2c0e23d09ff049f7a7ee842557907a25 + id: 60 + initiator_id: 90 + internal: false + kind: 2 + level: 36 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 90 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:52:19Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 203250 + consumed_gas: 1700385 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"33"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 93 + entrypoint: null + errors: null + fee: 977 + gas_limit: 1801 + hash: 0x807a10037c38762486af1c6111eb92d373322d0c1dcba2f6e98d05bd47952e8d + id: 62 + initiator_id: 86 + internal: false + kind: 2 + level: 36 + nonce: null + paid_storage_size_diff: 556 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 86 + status: 1 + storage_limit: 813 + storage_size: 556 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:52:19Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 2 + burned: 645250 + consumed_gas: 2859067 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"34"},{"bytes":"0001a23c906c3796e8c9d5b7be01ce6c80aac790b0ac"}]},{"int":"100"}]}' + delegate_id: 0 + destination_id: 87 + entrypoint: null + errors: null + fee: 2946 + gas_limit: 2960 + hash: 0x22a28412bccace57e3b6a26d943fe68104a211ae66b4af512f88d5467cb4702c + id: 63 + initiator_id: 94 + internal: false + kind: 2 + level: 36 + nonce: null + paid_storage_size_diff: 2324 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 94 + status: 1 + storage_limit: 2581 + storage_size: 2324 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:52:19Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 37 + deffated_storage: '[{"int":"1"},{"int":"90000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 64 + initiator_id: 0 + internal: false + kind: 1 + level: 37 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:54:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 2 + counter: 609 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 99 + entrypoint: null + errors: null + fee: 603 + gas_limit: 1539 + hash: 0x51da8e9675a6d2c75fe9b4a97227790e19671de9c0d35503f47bce5a801a93b8 + id: 65 + initiator_id: 96 + internal: false + kind: 2 + level: 37 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 96 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:54:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 2 + counter: 611 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 101 + entrypoint: null + errors: null + fee: 603 + gas_limit: 1539 + hash: 0xa02c0adca467aeb404b76181339e36bdc722b400b5e4afe0db70daebd8233a19 + id: 66 + initiator_id: 100 + internal: false + kind: 2 + level: 37 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 100 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:54:35Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 2054659 + content_index: 0 + counter: 540 + deffated_storage: '{"prim":"Some","args":[{"bytes":"0200000000000000000000000000000000000000000000000000000000000000"}]}' + delegate_id: 0 + destination_id: 88 + entrypoint: '@entrypoint_0' + errors: null + fee: 518 + gas_limit: 2155 + hash: 0xa47ce950e17c7f06af8e9e992ae10ad2b7aca0cf8a72c0ce451684f673f20324 + id: 67 + initiator_id: 92 + internal: false + kind: 1 + level: 37 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"default","value":{"prim":"Pair","args":[{"bytes":"01"},{"int":"1"}]}}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 92 + status: 1 + storage_limit: 0 + storage_size: 87 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:54:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 98 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0xa6c86683d7886f2e8fed0fe634b98eb09f9b236dab7c1e666cbfb2945860609c + id: 68 + initiator_id: 104 + internal: false + kind: 2 + level: 37 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 104 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:54:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 97 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0xa9d2451bf6b061e5a15fd8800fcc0817154e0c7064d5bb8bc21c563234bfd30b + id: 69 + initiator_id: 105 + internal: false + kind: 2 + level: 37 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 105 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:54:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 2 + burned: 251000 + consumed_gas: 1965705 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"35"},[]]}' + delegate_id: 0 + destination_id: 95 + entrypoint: null + errors: null + fee: 1140 + gas_limit: 2066 + hash: 0x91d28300f8a7e266b0653efd94d72d963d3b775364949245454d6f1efce76094 + id: 70 + initiator_id: 108 + internal: false + kind: 2 + level: 37 + nonce: null + paid_storage_size_diff: 747 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 108 + status: 1 + storage_limit: 1004 + storage_size: 747 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:54:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 2 + burned: 645250 + consumed_gas: 2859067 + content_index: 0 + counter: 540 + deffated_storage: '{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"36"},{"bytes":"0001a23c906c3796e8c9d5b7be01ce6c80aac790b0ac"}]},{"int":"100"}]}' + delegate_id: 0 + destination_id: 109 + entrypoint: null + errors: null + fee: 2883 + gas_limit: 2960 + hash: 0xe60df3f6031662375716412295a8ff2955ab5cf661423e30097d8b40de07e049 + id: 71 + initiator_id: 94 + internal: false + kind: 2 + level: 37 + nonce: null + paid_storage_size_diff: 2324 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 94 + status: 1 + storage_limit: 2581 + storage_size: 2324 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:54:35Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 38 + deffated_storage: '[{"int":"1"},{"int":"92500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 72 + initiator_id: 0 + internal: false + kind: 1 + level: 38 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:56:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 102000 + consumed_gas: 1603860 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Some","args":[{"bytes":"0572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"}]}' + delegate_id: 0 + destination_id: 116 + entrypoint: null + errors: null + fee: 650 + gas_limit: 1704 + hash: 0xcb77f8b51343ea69b568bb3a8754a5d4ac643f189744faa3cab70353d848e206 + id: 73 + initiator_id: 117 + internal: false + kind: 2 + level: 38 + nonce: null + paid_storage_size_diff: 151 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 117 + status: 1 + storage_limit: 408 + storage_size: 151 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:56:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 122250 + consumed_gas: 1433807 + content_index: 1 + counter: 539 + deffated_storage: '{"bytes":"01305a16477d6f06df8022b67589d78104a0b5b9d2"}' + delegate_id: 0 + destination_id: 122 + entrypoint: null + errors: null + fee: 731 + gas_limit: 1534 + hash: 0x62b3a40c4b65eff367b43bbd23e4862321a6e115770a5899fe4a59a20b9023e8 + id: 74 + initiator_id: 123 + internal: false + kind: 2 + level: 38 + nonce: null + paid_storage_size_diff: 232 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 123 + status: 1 + storage_limit: 489 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:56:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 122250 + consumed_gas: 1433807 + content_index: 1 + counter: 539 + deffated_storage: '{"bytes":"01574430dbc9b1e2b0a21cc1366b42d9bcc974060b"}' + delegate_id: 0 + destination_id: 110 + entrypoint: null + errors: null + fee: 731 + gas_limit: 1534 + hash: 0xb43aefb837976aee6074b345d7fbe415135f2bff34edbead675539547e0ecf30 + id: 75 + initiator_id: 124 + internal: false + kind: 2 + level: 38 + nonce: null + paid_storage_size_diff: 232 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 124 + status: 1 + storage_limit: 489 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:56:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 113 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0xa7d7b3ca3e80cde3b671a9fe6e494b41fa1918f0501177c4faf9e5ddbdd35faa + id: 76 + initiator_id: 114 + internal: false + kind: 2 + level: 38 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 114 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:56:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 111 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0x44be036dafe607133727a1f97be1ae5723e116d8a5f021a356dc1df6568827e9 + id: 77 + initiator_id: 112 + internal: false + kind: 2 + level: 38 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 112 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:56:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 201750 + consumed_gas: 1701031 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"37"},[]]}' + delegate_id: 0 + destination_id: 118 + entrypoint: null + errors: null + fee: 971 + gas_limit: 1802 + hash: 0xcdefe3fa9e73485c3255e30ae7ef87ddc637f909fc7f058b0a87142dcfdc8fc1 + id: 78 + initiator_id: 119 + internal: false + kind: 2 + level: 38 + nonce: null + paid_storage_size_diff: 550 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 119 + status: 1 + storage_limit: 807 + storage_size: 550 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:56:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 2 + burned: 1796000 + consumed_gas: 3664415 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"0001ef2ab478dc5da4f80a81485b2484ba5dd42126f1"},{"int":"38"}]},{"prim":"Pair","args":[{"prim":"False"},{"int":"50"}]}]}' + delegate_id: 0 + destination_id: 120 + entrypoint: null + errors: null + fee: 7630 + gas_limit: 3765 + hash: 0x6d7730f29e8f8a6549e9d549a5c54c4976af4f4a1c841f8de51db5537554a978 + id: 79 + initiator_id: 115 + internal: false + kind: 2 + level: 38 + nonce: null + paid_storage_size_diff: 6927 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 115 + status: 1 + storage_limit: 7184 + storage_size: 6927 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:56:47Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 39 + deffated_storage: '[{"int":"1"},{"int":"95000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 80 + initiator_id: 0 + internal: false + kind: 1 + level: 39 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 122250 + consumed_gas: 1433807 + content_index: 1 + counter: 539 + deffated_storage: '{"bytes":"01923832354dde7bb074f959a6e729a0319293c88a"}' + delegate_id: 0 + destination_id: 137 + entrypoint: null + errors: null + fee: 731 + gas_limit: 1534 + hash: 0x6d35baf5682a7770aa8f9edadf42056b31a8c2e8badf92fd6ac3abd4e7599a65 + id: 81 + initiator_id: 130 + internal: false + kind: 2 + level: 39 + nonce: null + paid_storage_size_diff: 232 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 130 + status: 1 + storage_limit: 489 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 2677848 + content_index: 0 + counter: 540 + deffated_storage: '{"prim":"Some","args":[{"bytes":"0c9b60d5afcbd5663a8a44b7c5a02f19e9a77ab0a35bd65809bb5c67ec582c897feb04decc694b13e08587f3ff9b5b60143be6d078c2b79a7d4f1d1b21486a030ec93f56aa54e1de880db5a66dd833a652a95bee27c824084006cb5644cbd43f"}]}' + delegate_id: 0 + destination_id: 116 + entrypoint: '@entrypoint_0' + errors: null + fee: 675 + gas_limit: 2778 + hash: 0xace8d95da38e2b8e844f60c81089c0b9e30bc9a0ce6a30c38b1fe33dad393ed9 + id: 82 + initiator_id: 117 + internal: false + kind: 1 + level: 39 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"default","value":{"prim":"Pair","args":[{"bytes":"0572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"},{"int":"2"}]}}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 117 + status: 1 + storage_limit: 0 + storage_size: 151 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 132 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0x3418fec05300d4efab029b18770de63dc4dded3344a6cd182b54d814de63ee4a + id: 83 + initiator_id: 126 + internal: false + kind: 2 + level: 39 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 126 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 133 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0xea57b3eab18dc4853f294fcedae28bed31a1e4a2b676a88166349ecc2b3a993b + id: 84 + initiator_id: 139 + internal: false + kind: 2 + level: 39 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 139 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 1000000 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 2082479 + content_index: 0 + counter: 540 + deffated_storage: '{"bytes":"01305a16477d6f06df8022b67589d78104a0b5b9d2"}' + delegate_id: 0 + destination_id: 122 + entrypoint: default + errors: null + fee: 524 + gas_limit: 2183 + hash: 0xa90c585d70df40f1aa14d17e443817aa3dd178f6a233b548f002c0349edeef4b + id: 85 + initiator_id: 123 + internal: false + kind: 1 + level: 39 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 123 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1211778 + content_index: 1 + counter: 541 + deffated_storage: '{"bytes":"01305a16477d6f06df8022b67589d78104a0b5b9d2"}' + delegate_id: 0 + destination_id: 122 + entrypoint: do + errors: null + fee: 579 + gas_limit: 2732 + hash: 0xa90c585d70df40f1aa14d17e443817aa3dd178f6a233b548f002c0349edeef4b + id: 86 + initiator_id: 123 + internal: false + kind: 1 + level: 39 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"do","value":[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PUSH","args":[{"prim":"key_hash"},{"string":"tz1eY5Aqa1kXDFoiebL28emyXFoneAoVg1zh"}]},{"prim":"IMPLICIT_ACCOUNT"},{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"50"}]},{"prim":"UNIT"},{"prim":"TRANSFER_TOKENS"},{"prim":"CONS"}]}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 123 + status: 1 + storage_limit: 257 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 50 + big_map_diffs_count: 0 + burned: 64250 + consumed_gas: 1420000 + content_index: 1 + counter: 541 + deffated_storage: null + delegate_id: 0 + destination_id: 125 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: 0xa90c585d70df40f1aa14d17e443817aa3dd178f6a233b548f002c0349edeef4b + id: 87 + initiator_id: 123 + internal: true + kind: 1 + level: 39 + nonce: 0 + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 122 + status: 1 + storage_limit: 0 + storage_size: 0 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1209977 + content_index: 2 + counter: 542 + deffated_storage: '{"bytes":"01305a16477d6f06df8022b67589d78104a0b5b9d2"}' + delegate_id: 0 + destination_id: 122 + entrypoint: do + errors: null + fee: 536 + gas_limit: 2310 + hash: 0xa90c585d70df40f1aa14d17e443817aa3dd178f6a233b548f002c0349edeef4b + id: 88 + initiator_id: 123 + internal: false + kind: 1 + level: 39 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"do","value":[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PUSH","args":[{"prim":"key_hash"},{"string":"tz1cjyja1TU6fiyiFav3mFAdnDsCReJ12hPD"}]},{"prim":"SOME"},{"prim":"SET_DELEGATE"},{"prim":"CONS"}]}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 123 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1206327 + content_index: 3 + counter: 543 + deffated_storage: '{"bytes":"01305a16477d6f06df8022b67589d78104a0b5b9d2"}' + delegate_id: 0 + destination_id: 122 + entrypoint: do + errors: null + fee: 536 + gas_limit: 2307 + hash: 0xa90c585d70df40f1aa14d17e443817aa3dd178f6a233b548f002c0349edeef4b + id: 89 + initiator_id: 123 + internal: false + kind: 1 + level: 39 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"do","value":[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"NONE","args":[{"prim":"key_hash"}]},{"prim":"SET_DELEGATE"},{"prim":"CONS"}]}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 123 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 1000000 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 2082479 + content_index: 0 + counter: 540 + deffated_storage: '{"bytes":"01574430dbc9b1e2b0a21cc1366b42d9bcc974060b"}' + delegate_id: 0 + destination_id: 110 + entrypoint: default + errors: null + fee: 524 + gas_limit: 2183 + hash: 0x1cd33909c88cfa2c5276b584c42f277541b3cf355e81125e8d916b4f0611a6d9 + id: 90 + initiator_id: 124 + internal: false + kind: 1 + level: 39 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 124 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1211778 + content_index: 1 + counter: 541 + deffated_storage: '{"bytes":"01574430dbc9b1e2b0a21cc1366b42d9bcc974060b"}' + delegate_id: 0 + destination_id: 110 + entrypoint: do + errors: null + fee: 579 + gas_limit: 2732 + hash: 0x1cd33909c88cfa2c5276b584c42f277541b3cf355e81125e8d916b4f0611a6d9 + id: 91 + initiator_id: 124 + internal: false + kind: 1 + level: 39 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"do","value":[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PUSH","args":[{"prim":"key_hash"},{"string":"tz1eY5Aqa1kXDFoiebL28emyXFoneAoVg1zh"}]},{"prim":"IMPLICIT_ACCOUNT"},{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"50"}]},{"prim":"UNIT"},{"prim":"TRANSFER_TOKENS"},{"prim":"CONS"}]}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 124 + status: 1 + storage_limit: 257 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 50 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1420000 + content_index: 1 + counter: 541 + deffated_storage: null + delegate_id: 0 + destination_id: 125 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: 0x1cd33909c88cfa2c5276b584c42f277541b3cf355e81125e8d916b4f0611a6d9 + id: 92 + initiator_id: 124 + internal: true + kind: 1 + level: 39 + nonce: 3 + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 110 + status: 1 + storage_limit: 0 + storage_size: 0 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1209977 + content_index: 2 + counter: 542 + deffated_storage: '{"bytes":"01574430dbc9b1e2b0a21cc1366b42d9bcc974060b"}' + delegate_id: 0 + destination_id: 110 + entrypoint: do + errors: null + fee: 536 + gas_limit: 2310 + hash: 0x1cd33909c88cfa2c5276b584c42f277541b3cf355e81125e8d916b4f0611a6d9 + id: 93 + initiator_id: 124 + internal: false + kind: 1 + level: 39 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"do","value":[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PUSH","args":[{"prim":"key_hash"},{"string":"tz1cjyja1TU6fiyiFav3mFAdnDsCReJ12hPD"}]},{"prim":"SOME"},{"prim":"SET_DELEGATE"},{"prim":"CONS"}]}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 124 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1206327 + content_index: 3 + counter: 543 + deffated_storage: '{"bytes":"01574430dbc9b1e2b0a21cc1366b42d9bcc974060b"}' + delegate_id: 0 + destination_id: 110 + entrypoint: do + errors: null + fee: 536 + gas_limit: 2307 + hash: 0x1cd33909c88cfa2c5276b584c42f277541b3cf355e81125e8d916b4f0611a6d9 + id: 94 + initiator_id: 124 + internal: false + kind: 1 + level: 39 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"do","value":[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"NONE","args":[{"prim":"key_hash"}]},{"prim":"SET_DELEGATE"},{"prim":"CONS"}]}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 124 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 234750 + consumed_gas: 1437692 + content_index: 1 + counter: 539 + deffated_storage: '{"bytes":"bc92e2db9de1b4a8bbf8d186d3eac5e0d2aeefaccd96b3c59dabc3d4f1d1b89494c181e4cff3bfb2c0fda189edad93ddb3c5a9dfbdb5f1ae98b49ae9f395aa8f91d6e5e4b78aacbac4f3a595dbc7e6dafbe3cf8bf38ce183a7bbc7be9ae3bfe7f487a28d93c7a3cdf597a5e188828ff8d192ddf28eb4a4c9beffbf9383e9e18ccb90e3b6b499ffd1b4fbabd68ca3fab2d2eeb2f9c6fbb9fdb5dab69fbbb6e893f0eac2b2dde5dca382c7fea6fde7dae186ca99b4e9a6eb90eec9a6e080c6b3baccf8d9fbc1d0d782a3e7b28dbfeccdaec6c4f592d7dcffc8e69af2aa9eb7aeb1f7cce0d899d38eb2a5abf0c0f395ced28ca395d9cb8e9ab6f387dbdce6b4db8af0ada493e0d5ee8bf8f99ea8ae9f9386e3c69ef9ffdfa9898f8594ff97cfa0bcc3f1c64af7c88ba5f694defdd7e7bdf9afb9f5f3babde98d85b18cfd9ffd82e8de9d8ac6d4f5dacfe28ae087f5ea8da5e984abcdb888e6d2debcaf98e6d4d2d296c6d083ffaecdbffca6c7e0beded4c5eac795e6a5829bbe94f3ebaef3e6a0d1e395889a9e90d490f8afeea9bb968f8bdedaf8d288fcd8bfb68db29293e4e1b8c0a7e6ad9fe79191e9e9e8e58f9dc098fd8792adc8dea2c7facfbdddd082c2d784ecdddebc8aa6fe8abd94f0f4a3c2cdfbd99ac0f1c2929686f5cfe4bbd3e6cf87cebadcf0efc0eea29bebc5c5d496aeb0fdd9a0d3ce98a1dbd39da5d487b29ba2caf2cdffaff89cb3fe9afaffe7cb85f68b90e9e1a8df8f89ea97b589a7b9b991bec2e1bfa4edbed49fb3abe2ade2bc9dc7a5bfc3fed5f5c0dfb199cafd8bd1f59adae8dbe8b39701cb0982a71363254e51ebe33ea52ec2cd61e9234e11891cfa0000001c67e1d80f729e0621c48cc74afc15e7551eb8c198b3151605e431863f"}' + delegate_id: 0 + destination_id: 129 + entrypoint: null + errors: null + fee: 1166 + gas_limit: 1538 + hash: 0x12473fe5964c82f4418a43d8d4ce0229934870e3008f946045e15adb82b82373 + id: 95 + initiator_id: 135 + internal: false + kind: 2 + level: 39 + nonce: null + paid_storage_size_diff: 682 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 135 + status: 1 + storage_limit: 939 + storage_size: 682 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 2 + burned: 1796000 + consumed_gas: 3664415 + content_index: 0 + counter: 540 + deffated_storage: '{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"0001ef2ab478dc5da4f80a81485b2484ba5dd42126f1"},{"int":"39"}]},{"prim":"Pair","args":[{"prim":"False"},{"int":"50"}]}]}' + delegate_id: 0 + destination_id: 141 + entrypoint: null + errors: null + fee: 7567 + gas_limit: 3765 + hash: 0xabe87938646bc7483ea4797bc3834dd06b02a608c35a4faa2fa465f0c391ce1e + id: 96 + initiator_id: 115 + internal: false + kind: 2 + level: 39 + nonce: null + paid_storage_size_diff: 6927 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 115 + status: 1 + storage_limit: 7184 + storage_size: 6927 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T16:59:07Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 40 + deffated_storage: '[{"int":"1"},{"int":"97500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 97 + initiator_id: 0 + internal: false + kind: 1 + level: 40 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 74750 + consumed_gas: 1405658 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"None"}' + delegate_id: 0 + destination_id: 156 + entrypoint: null + errors: null + fee: 521 + gas_limit: 1506 + hash: 0x6a6d581ea2d767be9a3bc17789c81d518e9ec4f4b04e5aa5899aada03b72e9e7 + id: 98 + initiator_id: 158 + internal: false + kind: 2 + level: 40 + nonce: null + paid_storage_size_diff: 42 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 158 + status: 1 + storage_limit: 299 + storage_size: 42 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 146 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0xda66c0045fc21d9a319a55867f8f01ca4fac26e24f785400befa975380e01722 + id: 100 + initiator_id: 157 + internal: false + kind: 2 + level: 40 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 157 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 148 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0x7123d70e9db9929040bc328ed187ddb58c7c18b8411f7a04bfc910cc65c3f85d + id: 101 + initiator_id: 151 + internal: false + kind: 2 + level: 40 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 151 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 1000000 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 2082479 + content_index: 0 + counter: 540 + deffated_storage: '{"bytes":"01923832354dde7bb074f959a6e729a0319293c88a"}' + delegate_id: 0 + destination_id: 137 + entrypoint: default + errors: null + fee: 524 + gas_limit: 2183 + hash: 0xd5567a8596a08a9cc49e22d7f5d8741161a1146f8369e897242bb8d59a8f6a7a + id: 102 + initiator_id: 130 + internal: false + kind: 1 + level: 40 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 130 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1211778 + content_index: 1 + counter: 541 + deffated_storage: '{"bytes":"01923832354dde7bb074f959a6e729a0319293c88a"}' + delegate_id: 0 + destination_id: 137 + entrypoint: do + errors: null + fee: 579 + gas_limit: 2732 + hash: 0xd5567a8596a08a9cc49e22d7f5d8741161a1146f8369e897242bb8d59a8f6a7a + id: 103 + initiator_id: 130 + internal: false + kind: 1 + level: 40 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"do","value":[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PUSH","args":[{"prim":"key_hash"},{"string":"tz1eY5Aqa1kXDFoiebL28emyXFoneAoVg1zh"}]},{"prim":"IMPLICIT_ACCOUNT"},{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"50"}]},{"prim":"UNIT"},{"prim":"TRANSFER_TOKENS"},{"prim":"CONS"}]}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 130 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 50 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1420000 + content_index: 1 + counter: 541 + deffated_storage: null + delegate_id: 0 + destination_id: 125 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: 0xd5567a8596a08a9cc49e22d7f5d8741161a1146f8369e897242bb8d59a8f6a7a + id: 104 + initiator_id: 130 + internal: true + kind: 1 + level: 40 + nonce: 0 + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 137 + status: 1 + storage_limit: 0 + storage_size: 0 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1209977 + content_index: 2 + counter: 542 + deffated_storage: '{"bytes":"01923832354dde7bb074f959a6e729a0319293c88a"}' + delegate_id: 0 + destination_id: 137 + entrypoint: do + errors: null + fee: 536 + gas_limit: 2310 + hash: 0xd5567a8596a08a9cc49e22d7f5d8741161a1146f8369e897242bb8d59a8f6a7a + id: 105 + initiator_id: 130 + internal: false + kind: 1 + level: 40 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"do","value":[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PUSH","args":[{"prim":"key_hash"},{"string":"tz1cjyja1TU6fiyiFav3mFAdnDsCReJ12hPD"}]},{"prim":"SOME"},{"prim":"SET_DELEGATE"},{"prim":"CONS"}]}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 130 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1206327 + content_index: 3 + counter: 543 + deffated_storage: '{"bytes":"01923832354dde7bb074f959a6e729a0319293c88a"}' + delegate_id: 0 + destination_id: 137 + entrypoint: do + errors: null + fee: 536 + gas_limit: 2307 + hash: 0xd5567a8596a08a9cc49e22d7f5d8741161a1146f8369e897242bb8d59a8f6a7a + id: 106 + initiator_id: 130 + internal: false + kind: 1 + level: 40 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"do","value":[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"NONE","args":[{"prim":"key_hash"}]},{"prim":"SET_DELEGATE"},{"prim":"CONS"}]}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 130 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 2 + burned: 251000 + consumed_gas: 1965705 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"40"},[]]}' + delegate_id: 0 + destination_id: 160 + entrypoint: null + errors: null + fee: 1140 + gas_limit: 2066 + hash: 0x130385f9a8df23042fdb9f88a43f0b43c682a55b5405d3e733ee7e932c15d7f9 + id: 107 + initiator_id: 149 + internal: false + kind: 2 + level: 40 + nonce: null + paid_storage_size_diff: 747 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 149 + status: 1 + storage_limit: 1004 + storage_size: 747 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 220500 + consumed_gas: 1433538 + content_index: 1 + counter: 539 + deffated_storage: '{"bytes":"e4c381978ba7ebedf29781eadfe6b7e0bfcca9a581f0a5f8959efdbadacce9d1d0d8e7bdf8adff92c586f5ebd6ecb5eef6d69bf7bdd38feba7c895a0e4cee0cabaffdeacca91f69ac9a7e684b8fbf9c584c7f889998b9881bbebead2f3a48794999cb8c6a299939f95f7b0e6bcf8f4f492c398ea8fe7b3f7c591a2d9f3bbc19d9facaf91afc5fde1c0f6a0ed9be2bdf79198c787f0f5d2e28cf8d1d180c5879aa7959c98b79cb8f9b3c3a4c0c6b7ae8ed7ddddaa86d9ece78ecccac1878cfd8db7ae94e1979980ecad98d4f4fba2a8d2e7e098f5fdccbbea868ed7e085f7d0f5bbb48c84ebe78bcbc78c86d9c6b4d7ede99888d0e38d84a1aa91a5cec8d4e3e6ccabcebbe2a0e0a18aa6c090a3a9f0a4fdf3a89ecbffdccaedf6e2e8f3bcada5f8ce9a7cfde0958f89b0e3b7f6badf84f5eb94e389b2a3f1cfcadbf3cdb4bbec95e9f3cef7cca3b6f187b0e6e997cc84c7ddd0948d80b186b0b1b089c2b3bcee80f8918d8dafc1c2a6c2a193f492c6e0cfd18998fefee7fdb1c5acae8fc29be097fa9e948ec292edc997ef9bcca8eab694bff688d28c89c8adae90b19f9ef3a0f3e1abfffff0c5b7f6bddaeffbb9fbecaa98a6ed9d92e8bab9d29cadf7dfe3ada1bc89c9a59af1dffea284d7edc9f2d1c8b0fd9fcc999ce7fdfdeccc9cafe1d7d2fef1eeda8babc1f2f282a5ee919da88a8ff093a8c5f8c3fcddf5c7ccdef8ceb496a2848d8284bae2e8bdbcdfd9f1b1adffd788e880cc82d3a8c5a086cfc3fde1fad3c6a0d1dac2a4e6ccf7a0bcc9abf499888ed49cefc1f0aed9d8bef0cbaabe91e9f9adab933c"}' + delegate_id: 0 + destination_id: 154 + entrypoint: null + errors: null + fee: 1109 + gas_limit: 1534 + hash: 0x613b362bc453fd1f71f7a159959065c5c37fcb7488e6613f4524b762379c7960 + id: 108 + initiator_id: 144 + internal: false + kind: 2 + level: 40 + nonce: null + paid_storage_size_diff: 625 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 144 + status: 1 + storage_limit: 882 + storage_size: 625 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 4 + burned: 692500 + consumed_gas: 3175280 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"41"},{"int":"42"}]},{"int":"100"}]}' + delegate_id: 0 + destination_id: 150 + entrypoint: null + errors: null + fee: 2979 + gas_limit: 3276 + hash: 0x6be72e3d1510d73986475cee80abea4d5f949d84e0c5213c23696159498c2672 + id: 109 + initiator_id: 147 + internal: false + kind: 2 + level: 40 + nonce: null + paid_storage_size_diff: 2513 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 147 + status: 1 + storage_limit: 2770 + storage_size: 2513 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:01:51Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 41 + deffated_storage: '[{"int":"1"},{"int":"100000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 110 + initiator_id: 0 + internal: false + kind: 1 + level: 41 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 182 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x3614d406810edceedb5dd776e896498364ef932c8dc3b66958697032b4dafe5a + id: 111 + initiator_id: 167 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 167 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 188 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0x3bcd834fb9e5cd8d0c5c0f8712bfb24939cf0a1607bbb42f0d004858afb5ee31 + id: 112 + initiator_id: 176 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 176 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 1000000 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 2082479 + content_index: 0 + counter: 540 + deffated_storage: '{"bytes":"0184e9903a5e129ee46a4a3e523273ce537ae25443"}' + delegate_id: 0 + destination_id: 145 + entrypoint: default + errors: null + fee: 524 + gas_limit: 2183 + hash: 0x219d11012ee41f921d029892d1942ca6488be9aafc792df0033ed572111a13f9 + id: 113 + initiator_id: 159 + internal: false + kind: 1 + level: 41 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 159 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1211778 + content_index: 1 + counter: 541 + deffated_storage: '{"bytes":"0184e9903a5e129ee46a4a3e523273ce537ae25443"}' + delegate_id: 0 + destination_id: 145 + entrypoint: do + errors: null + fee: 579 + gas_limit: 2732 + hash: 0x219d11012ee41f921d029892d1942ca6488be9aafc792df0033ed572111a13f9 + id: 114 + initiator_id: 159 + internal: false + kind: 1 + level: 41 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"do","value":[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PUSH","args":[{"prim":"key_hash"},{"string":"tz1eY5Aqa1kXDFoiebL28emyXFoneAoVg1zh"}]},{"prim":"IMPLICIT_ACCOUNT"},{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"50"}]},{"prim":"UNIT"},{"prim":"TRANSFER_TOKENS"},{"prim":"CONS"}]}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 159 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 50 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1420000 + content_index: 1 + counter: 541 + deffated_storage: null + delegate_id: 0 + destination_id: 125 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: 0x219d11012ee41f921d029892d1942ca6488be9aafc792df0033ed572111a13f9 + id: 115 + initiator_id: 159 + internal: true + kind: 1 + level: 41 + nonce: 0 + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 145 + status: 1 + storage_limit: 0 + storage_size: 0 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1209977 + content_index: 2 + counter: 542 + deffated_storage: '{"bytes":"0184e9903a5e129ee46a4a3e523273ce537ae25443"}' + delegate_id: 0 + destination_id: 145 + entrypoint: do + errors: null + fee: 536 + gas_limit: 2310 + hash: 0x219d11012ee41f921d029892d1942ca6488be9aafc792df0033ed572111a13f9 + id: 116 + initiator_id: 159 + internal: false + kind: 1 + level: 41 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"do","value":[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PUSH","args":[{"prim":"key_hash"},{"string":"tz1cjyja1TU6fiyiFav3mFAdnDsCReJ12hPD"}]},{"prim":"SOME"},{"prim":"SET_DELEGATE"},{"prim":"CONS"}]}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 159 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 195 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0xdff06c8933c1ce92b4813256a943abca7ff36f53b317180de600ed0591559176 + id: 131 + initiator_id: 210 + internal: false + kind: 2 + level: 42 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 210 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:07:03Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1206327 + content_index: 3 + counter: 543 + deffated_storage: '{"bytes":"0184e9903a5e129ee46a4a3e523273ce537ae25443"}' + delegate_id: 0 + destination_id: 145 + entrypoint: do + errors: null + fee: 536 + gas_limit: 2307 + hash: 0x219d11012ee41f921d029892d1942ca6488be9aafc792df0033ed572111a13f9 + id: 117 + initiator_id: 159 + internal: false + kind: 1 + level: 41 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"do","value":[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"NONE","args":[{"prim":"key_hash"}]},{"prim":"SET_DELEGATE"},{"prim":"CONS"}]}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 159 + status: 1 + storage_limit: 0 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 49250 + consumed_gas: 2712828 + content_index: 0 + counter: 540 + deffated_storage: '{"prim":"Some","args":[{"bytes":"0a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c335771638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a0530f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf30468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899"}]}' + delegate_id: 0 + destination_id: 156 + entrypoint: '@entrypoint_0' + errors: null + fee: 771 + gas_limit: 2813 + hash: 0xb4404e7a5a2f9fa89a59294d2f7fe1cb37992c9a69f43efc52242df4ef39d793 + id: 118 + initiator_id: 158 + internal: false + kind: 1 + level: 41 + nonce: null + paid_storage_size_diff: 197 + parameters: '{"entrypoint":"default","value":{"bytes":"0a4edef9c1ed7f729f520e47730a124fd70662a904ba1074728114d1031e1572c6c886f6b57ec72a6178288c47c335771638533957d540a9d2370f17cc7ed5863bc0b995b8825e0ee1ea1e1e4d00dbae81f14b0bf3611b78c952aacab827a0530f6d4552fa65dd2638b361543f887136a43253d9c66c411697003f7a13c308f5422e1aa0a59c8967acdefd8b6e36ccf30468fb440d82b0630aeb8dca2b5256789a66da69bf91009cbfe6bd221e47aa8ae88dece9764bf3bd999d95d71e4c9899"}}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 158 + status: 1 + storage_limit: 197 + storage_size: 239 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 201750 + consumed_gas: 1701031 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"43"},[]]}' + delegate_id: 0 + destination_id: 172 + entrypoint: null + errors: null + fee: 971 + gas_limit: 1802 + hash: 0xfe8a395175f06008092345848b858cdfb17a0cf5fddde5afcf5e466675d0292d + id: 119 + initiator_id: 190 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 550 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 190 + status: 1 + storage_limit: 807 + storage_size: 550 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 210250 + consumed_gas: 1705387 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"44"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]},{"prim":"Elt","args":[{"int":"2"},{"prim":"Pair","args":[{"int":"120"},{"int":"20"}]}]},{"prim":"Elt","args":[{"int":"3"},{"prim":"Pair","args":[{"int":"50"},{"int":"60"}]}]}]]}' + delegate_id: 0 + destination_id: 168 + entrypoint: null + errors: null + fee: 1005 + gas_limit: 1806 + hash: 0x05ad99caf15daa4498f7eefde3a2007790050362d710ebd022a719ff4af386e3 + id: 120 + initiator_id: 191 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 584 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 191 + status: 1 + storage_limit: 841 + storage_size: 584 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 210250 + consumed_gas: 1705387 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"45"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]},{"prim":"Elt","args":[{"int":"2"},{"prim":"Pair","args":[{"int":"120"},{"int":"20"}]}]},{"prim":"Elt","args":[{"int":"3"},{"prim":"Pair","args":[{"int":"50"},{"int":"60"}]}]}]]}' + delegate_id: 0 + destination_id: 184 + entrypoint: null + errors: null + fee: 1005 + gas_limit: 1806 + hash: 0x35d9bb92b1d7ac41173fa01dc9feeec2a3e9454b04ccd1f240e5ccda8e8ffdfe + id: 121 + initiator_id: 185 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 584 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 185 + status: 1 + storage_limit: 841 + storage_size: 584 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 323000 + consumed_gas: 1615447 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"prim":"Pair","args":[{"int":"2"},[{"bytes":"02022e051144b2394061a2e9a16f93067d2c530039ac239f8130793fc3c46cf6f506"},{"bytes":"02031003cb56448a253cb550d6d5bee33e1f56b9eb62d7a7bcf0814759ee0870fbf6"},{"bytes":"02023c3cf00856016d01cebf27aca8a3417f815751f3572eb9bd15a0ad146bd4103a"}]]}]}' + delegate_id: 0 + destination_id: 162 + entrypoint: null + errors: null + fee: 1600 + gas_limit: 1716 + hash: 0xca710d2c8c2f125b278234b150270eeeb5d86ebceb7f1a085def1abbf1e57c33 + id: 122 + initiator_id: 163 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 1035 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 163 + status: 1 + storage_limit: 1292 + storage_size: 1035 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 323000 + consumed_gas: 1615447 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"prim":"Pair","args":[{"int":"2"},[{"bytes":"02025d6341293d8740662d595bcbcfaed49f151361a1c5ab1b9532ce614bccca2a8b"},{"bytes":"02027e98765d6b5f97f224db3aef946172dbca85949d331d37948286cd4eb8098728"},{"bytes":"02031f43250499d22855556ff8ce7916617cbf224edaad5d0619768f3aef9d6973f8"}]]}]}' + delegate_id: 0 + destination_id: 179 + entrypoint: null + errors: null + fee: 1600 + gas_limit: 1716 + hash: 0xd2849ce49e6474e4d23048457db64213f4da5e2f943caf58c47c5fce16403af5 + id: 123 + initiator_id: 180 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 1035 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 180 + status: 1 + storage_limit: 1292 + storage_size: 1035 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 4 + burned: 692500 + consumed_gas: 3175280 + content_index: 0 + counter: 540 + deffated_storage: '{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"46"},{"int":"47"}]},{"int":"100"}]}' + delegate_id: 0 + destination_id: 164 + entrypoint: null + errors: null + fee: 2916 + gas_limit: 3276 + hash: 0x443f40e6694c3e86eebb082f7cada06396b5a30bc6280a81101a165798d9127a + id: 124 + initiator_id: 147 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 2513 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 147 + status: 1 + storage_limit: 2770 + storage_size: 2513 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 4 + burned: 1452500 + consumed_gas: 3705580 + content_index: 1 + counter: 539 + deffated_storage: '[{"int":"48"},{"bytes":"0001754887431181a33bef2bf9989e67f8700268ec77"},{"prim":"True"},{"int":"3"}]' + delegate_id: 0 + destination_id: 186 + entrypoint: null + errors: null + fee: 6159 + gas_limit: 3806 + hash: 0x3d95b8b2b05051c27fea58b08ee89ea0b364bbf5ba04e147fe946b35f02f6e57 + id: 125 + initiator_id: 169 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 5553 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 169 + status: 1 + storage_limit: 5810 + storage_size: 5553 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 9 + burned: 2268000 + consumed_gas: 6285069 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[[{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"00019563a4ee6d5aad2f10b62c0e07955fd6cb4f2509"},{"bytes":"0133604c1ee2391a5db33300d8c7ec332455525a4d00"}]},{"prim":"Pair","args":[{"int":"2"},{"int":"49"}]}]},{"prim":"Pair","args":[{"int":"50"},{"int":"51"}]},{"int":"52"},{"int":"53"}],{"int":"54"}]}' + delegate_id: 0 + destination_id: 187 + entrypoint: null + errors: null + fee: 9199 + gas_limit: 6386 + hash: 0x1ba58b4d4286f69a9a3709433316cb26bb16b7e1f2e40348e176191dee21f2e8 + id: 126 + initiator_id: 165 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 8815 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 165 + status: 1 + storage_limit: 9072 + storage_size: 8815 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 2 + burned: 1672500 + consumed_gas: 3442508 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"7"},{"int":"55"}]}' + delegate_id: 0 + destination_id: 166 + entrypoint: null + errors: null + fee: 6974 + gas_limit: 3543 + hash: 0x18480f37864b18b0cef223932626ce44680cbdcbffc677bc778d596d9f5899a1 + id: 127 + initiator_id: 181 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 6433 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 181 + status: 1 + storage_limit: 6690 + storage_size: 6433 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 4 + burned: 3030000 + consumed_gas: 8932729 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[[{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"1000"},{"int":"56"}]},{"prim":"Pair","args":[{"int":"57"},[]]}]},{"prim":"Pair","args":[{"int":"58"},{"prim":"False"}]},{"int":"0"},{"int":"59"}],{"prim":"Pair","args":[{"prim":"Pair","args":[{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"000152f080af98f9afbff0ee6bc4cfe8d07e5b37a387"},{"bytes":"0002ca6e1d3ef54a05bddfef5fbe17d09786865e89be"}]},{"prim":"Pair","args":[{"bytes":"0002ead21e7f311ca2411c73388ff0e843f9602f4909"},{"prim":"None"}]}]},{"bytes":"016c01640a1acd661bb46408e7a854899de4ea451100"}]},{"prim":"None"}]}]}' + delegate_id: 0 + destination_id: 171 + entrypoint: null + errors: null + fee: 12951 + gas_limit: 9033 + hash: 0x590842df008ed24ea751e2ecea2e2c16229d901fc93fa5ca5456b11163183a98 + id: 128 + initiator_id: 174 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 11863 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 174 + status: 1 + storage_limit: 12120 + storage_size: 11863 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 4 + burned: 3030000 + consumed_gas: 8932729 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[[{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"1000"},{"int":"60"}]},{"prim":"Pair","args":[{"int":"61"},[]]}]},{"prim":"Pair","args":[{"int":"62"},{"prim":"False"}]},{"int":"0"},{"int":"63"}],{"prim":"Pair","args":[{"prim":"Pair","args":[{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"00015f5050e2454f074a82bf51403da19fc3fe6c22d7"},{"bytes":"00021250b15c68a16f8efd59e879afbc89efb79921b7"}]},{"prim":"Pair","args":[{"bytes":"00024850381eb4e9704d42218b1a00b5730a4225a18f"},{"prim":"None"}]}]},{"bytes":"016c01640a1acd661bb46408e7a854899de4ea451100"}]},{"prim":"None"}]}]}' + delegate_id: 0 + destination_id: 173 + entrypoint: null + errors: null + fee: 12951 + gas_limit: 9033 + hash: 0xbb0241e55ea168cb5273cf8d7d8afe13a618fa4eb911b5ed1e7079b3bdfaa3fa + id: 129 + initiator_id: 170 + internal: false + kind: 2 + level: 41 + nonce: null + paid_storage_size_diff: 11863 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 170 + status: 1 + storage_limit: 12120 + storage_size: 11863 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:04:35Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 42 + deffated_storage: '[{"int":"1"},{"int":"102500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 130 + initiator_id: 0 + internal: false + kind: 1 + level: 42 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:07:03Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 211 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0xe6799e8364a0786ab12a5139c0b135571d3476f9ba2e87ec3b3f40d55e966166 + id: 132 + initiator_id: 212 + internal: false + kind: 2 + level: 42 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 212 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:07:03Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 201 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0xd94cf254ababb64a8438eb87abf67ec9b1815e3593c127b3716ec6221bfb18df + id: 133 + initiator_id: 193 + internal: false + kind: 2 + level: 42 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 193 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:07:03Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 3398138 + content_index: 0 + counter: 540 + deffated_storage: '{"prim":"Pair","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"2"},[{"bytes":"02025d6341293d8740662d595bcbcfaed49f151361a1c5ab1b9532ce614bccca2a8b"},{"bytes":"02027e98765d6b5f97f224db3aef946172dbca85949d331d37948286cd4eb8098728"},{"bytes":"02031f43250499d22855556ff8ce7916617cbf224edaad5d0619768f3aef9d6973f8"}]]}]}' + delegate_id: 0 + destination_id: 179 + entrypoint: main + errors: null + fee: 1085 + gas_limit: 4919 + hash: 0x8f100d13e7c9a28969fb561b3ebbc0195f4c04363e89f638ce19ceb88024e03f + id: 134 + initiator_id: 180 + internal: false + kind: 1 + level: 42 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"main","value":{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"0"},{"prim":"Left","args":[[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PUSH","args":[{"prim":"key_hash"},{"string":"tz1eY5Aqa1kXDFoiebL28emyXFoneAoVg1zh"}]},{"prim":"IMPLICIT_ACCOUNT"},{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"500"}]},{"prim":"UNIT"},{"prim":"TRANSFER_TOKENS"},{"prim":"CONS"}]]}]},[{"prim":"Some","args":[{"string":"p2sigrJEk5X9B6A8PAd3VYdCyshfpRTXtdf2vMhMyt1Aosv188uW2EYUS65kL247NzJWv7474LifwGG6muggxcpGCr7QaLRAR7"}]},{"prim":"Some","args":[{"string":"p2sigsGspRjWCxBghobYv1A6PX7WLoiq3SBcd3rTSzfWrhUfGuzquBAj5C5ADwZgvpPmP6UfnBEyGhDp1a8JiVPUq6hGcBwL7f"}]},{"prim":"None"}]]}}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 180 + status: 1 + storage_limit: 0 + storage_size: 1035 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:07:03Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 500 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 1420000 + content_index: 0 + counter: 540 + deffated_storage: null + delegate_id: 0 + destination_id: 125 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: 0x8f100d13e7c9a28969fb561b3ebbc0195f4c04363e89f638ce19ceb88024e03f + id: 135 + initiator_id: 180 + internal: true + kind: 1 + level: 42 + nonce: 0 + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 179 + status: 1 + storage_limit: 0 + storage_size: 0 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:07:03Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 206250 + consumed_gas: 1704433 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"64"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 196 + entrypoint: null + errors: null + fee: 988 + gas_limit: 1805 + hash: 0xefc17ad695b629c57aa46ece5bd68f348a0e08a4fc31ebf0275107aca4b77f08 + id: 136 + initiator_id: 213 + internal: false + kind: 2 + level: 42 + nonce: null + paid_storage_size_diff: 568 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 213 + status: 1 + storage_limit: 825 + storage_size: 568 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:07:03Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 206250 + consumed_gas: 1704433 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"65"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 198 + entrypoint: null + errors: null + fee: 988 + gas_limit: 1805 + hash: 0xac2b3dbf97c2b38b55aac870a7115798748912ffe808aa89b8eddff9ae5491a6 + id: 137 + initiator_id: 214 + internal: false + kind: 2 + level: 42 + nonce: null + paid_storage_size_diff: 568 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 214 + status: 1 + storage_limit: 825 + storage_size: 568 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:07:03Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 227250 + consumed_gas: 1724769 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"66"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 199 + entrypoint: null + errors: null + fee: 1074 + gas_limit: 1825 + hash: 0x8405ad698d74c396992bb0aa78b56b7922f859d92e167686685554f2c0808dc2 + id: 138 + initiator_id: 207 + internal: false + kind: 2 + level: 42 + nonce: null + paid_storage_size_diff: 652 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 207 + status: 1 + storage_limit: 909 + storage_size: 652 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:07:03Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 122250 + consumed_gas: 1433807 + content_index: 0 + counter: 540 + deffated_storage: '{"bytes":"027ff2116646294a659554a984bc33a8fddee43595"}' + delegate_id: 0 + destination_id: 208 + entrypoint: null + errors: null + fee: 668 + gas_limit: 1534 + hash: 0xaa9bc9c34c0cc4d2a1f970bfc4fdc1795b3b24688220fb50b9bcb06e81665960 + id: 139 + initiator_id: 200 + internal: false + kind: 2 + level: 42 + nonce: null + paid_storage_size_diff: 232 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 200 + status: 1 + storage_limit: 489 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:07:03Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 6 + burned: 1301500 + consumed_gas: 4219364 + content_index: 1 + counter: 539 + deffated_storage: '[{"prim":"Pair","args":[{"bytes":"00019a96a19be02fc025557d17c2775e9c8dd426f722"},{"prim":"Pair","args":[{"int":"2"},{"int":"67"}]}]},{"prim":"Pair","args":[{"int":"68"},{"int":"69"}]},{"prim":"False"},{"int":"70"}]' + delegate_id: 0 + destination_id: 197 + entrypoint: null + errors: null + fee: 5323 + gas_limit: 4320 + hash: 0xab7109c1650ce424b0d6ffed3e2900a1b1b2c52ca4f6ec8029277760df0d39e0 + id: 140 + initiator_id: 209 + internal: false + kind: 2 + level: 42 + nonce: null + paid_storage_size_diff: 4949 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 209 + status: 1 + storage_limit: 5206 + storage_size: 4949 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:07:03Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 2 + burned: 2691750 + consumed_gas: 4478816 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"7"},{"int":"71"}]}' + delegate_id: 0 + destination_id: 205 + entrypoint: null + errors: null + fee: 11153 + gas_limit: 4579 + hash: 0x2be674d9eb91ca788af18d05c83a7137e63934a51df0223ec194dd346be9dacf + id: 141 + initiator_id: 206 + internal: false + kind: 2 + level: 42 + nonce: null + paid_storage_size_diff: 10510 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 206 + status: 1 + storage_limit: 10767 + storage_size: 10510 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:07:03Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 43 + deffated_storage: '[{"int":"1"},{"int":"105000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 142 + initiator_id: 0 + internal: false + kind: 1 + level: 43 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:09:21Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 2 + counter: 540 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 225 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0xe408a1ef6bb8bb31591921bca03898cd794d2db0c73aa05a2a607ba9bad61fd1 + id: 143 + initiator_id: 226 + internal: false + kind: 2 + level: 43 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 226 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:09:21Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 218 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x51173d6b3ff894608c997203aad834d6f4e04c852f2bee59a78924164e2d5738 + id: 144 + initiator_id: 221 + internal: false + kind: 2 + level: 43 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 221 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:09:21Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 222 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0xca1ccc691a5ac67d3bdf7e209efb2a743d93aab4d1db623fdd6a0cfb7eb10b66 + id: 145 + initiator_id: 223 + internal: false + kind: 2 + level: 43 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 223 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:09:21Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 227 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0xec0a02b9cb12816a3eccc845ab4baa782b116b9c9499f4b4a4cb148a949d33a7 + id: 146 + initiator_id: 219 + internal: false + kind: 2 + level: 43 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 219 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:09:21Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 206000 + consumed_gas: 1704429 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"72"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 220 + entrypoint: null + errors: null + fee: 987 + gas_limit: 1805 + hash: 0x42252bc68fbf7cb71af1e2da8abb4f79db5b1698e42507962f4358be71d0db34 + id: 147 + initiator_id: 217 + internal: false + kind: 2 + level: 43 + nonce: null + paid_storage_size_diff: 567 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 217 + status: 1 + storage_limit: 824 + storage_size: 567 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:09:21Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 206000 + consumed_gas: 1704429 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"73"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 228 + entrypoint: null + errors: null + fee: 987 + gas_limit: 1805 + hash: 0x2d4b7d8fe061563108c576d844f4de3e1bc4ed6144961cc9ef00638a77c78e4c + id: 148 + initiator_id: 215 + internal: false + kind: 2 + level: 43 + nonce: null + paid_storage_size_diff: 567 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 215 + status: 1 + storage_limit: 824 + storage_size: 567 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:09:21Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 227250 + consumed_gas: 1724769 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"74"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 216 + entrypoint: null + errors: null + fee: 1074 + gas_limit: 1825 + hash: 0x225e13b922ff186b3d3887fc871e2811c01f1b056d916eff2b5b4102bc938b03 + id: 149 + initiator_id: 229 + internal: false + kind: 2 + level: 43 + nonce: null + paid_storage_size_diff: 652 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 229 + status: 1 + storage_limit: 909 + storage_size: 652 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:09:21Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 44 + deffated_storage: '[{"int":"1"},{"int":"107500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 150 + initiator_id: 0 + internal: false + kind: 1 + level: 44 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 86000 + consumed_gas: 1408014 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Some","args":[{"bytes":"0001000000000000000000000000000000000000000000000000000000000000"}]}' + delegate_id: 0 + destination_id: 232 + entrypoint: null + errors: null + fee: 536 + gas_limit: 1509 + hash: 0x54d36e3b8f7a249768139fef88f453bb37805047d8431d246e53970ee03d3350 + id: 151 + initiator_id: 243 + internal: false + kind: 2 + level: 44 + nonce: null + paid_storage_size_diff: 87 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 243 + status: 1 + storage_limit: 344 + storage_size: 87 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 2 + counter: 540 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 251 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x28f1931f2a4eb8522d78c7ed14500ae0594c218ba38eb8955d0f6e3b04b4a132 + id: 152 + initiator_id: 244 + internal: false + kind: 2 + level: 44 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 244 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 245 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x2ca318854781631cb45bd7e2b33c35e8600cd2f98c776f5810e37af15ad9c4e1 + id: 153 + initiator_id: 252 + internal: false + kind: 2 + level: 44 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 252 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 2 + counter: 540 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 253 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x76e432e59c28ee58100780e9bfb39d123b99fcfdee44dd4b3ea9a2afd3f92b14 + id: 154 + initiator_id: 246 + internal: false + kind: 2 + level: 44 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 246 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 254 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0x2125bad275ee2f66b32db7e6a2b8b457aba196ba105faf47e399a38bdefd811e + id: 155 + initiator_id: 247 + internal: false + kind: 2 + level: 44 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 247 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 203500 + consumed_gas: 1700389 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"75"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 239 + entrypoint: null + errors: null + fee: 977 + gas_limit: 1801 + hash: 0xa9813b19733cc1f0ab24304e94edc4d2ad2f5e87b1c9d029541f34153bc7a8a0 + id: 156 + initiator_id: 233 + internal: false + kind: 2 + level: 44 + nonce: null + paid_storage_size_diff: 557 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 233 + status: 1 + storage_limit: 814 + storage_size: 557 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 203500 + consumed_gas: 1700389 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"76"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 248 + entrypoint: null + errors: null + fee: 977 + gas_limit: 1801 + hash: 0x21bba219aa339ee3a430bf8a0b6013e3c6c98fb39d9aa456c5277be84051c4b3 + id: 157 + initiator_id: 234 + internal: false + kind: 2 + level: 44 + nonce: null + paid_storage_size_diff: 557 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 234 + status: 1 + storage_limit: 814 + storage_size: 557 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 210500 + consumed_gas: 1705391 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"77"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]},{"prim":"Elt","args":[{"int":"2"},{"prim":"Pair","args":[{"int":"120"},{"int":"20"}]}]},{"prim":"Elt","args":[{"int":"3"},{"prim":"Pair","args":[{"int":"50"},{"int":"60"}]}]}]]}' + delegate_id: 0 + destination_id: 249 + entrypoint: null + errors: null + fee: 1005 + gas_limit: 1806 + hash: 0x576ba1367b8dc2c7b50be24cddd58bb4f5e77d99cea7cf69368b078e5898183e + id: 158 + initiator_id: 240 + internal: false + kind: 2 + level: 44 + nonce: null + paid_storage_size_diff: 585 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 240 + status: 1 + storage_limit: 842 + storage_size: 585 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 2 + burned: 645500 + consumed_gas: 2859071 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"78"},{"bytes":"0001aa7d7c6aa3db6d0b0b471f6102dce8cdb9cbe834"}]},{"int":"100"}]}' + delegate_id: 0 + destination_id: 250 + entrypoint: null + errors: null + fee: 2946 + gas_limit: 2960 + hash: 0x49b766ad50aa1b7cbeee09cab8f1bf9bb779348f50276706d5116bfd2e5d3659 + id: 159 + initiator_id: 236 + internal: false + kind: 2 + level: 44 + nonce: null + paid_storage_size_diff: 2325 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 236 + status: 1 + storage_limit: 2582 + storage_size: 2325 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 2 + burned: 1672750 + consumed_gas: 3442512 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"7"},{"int":"79"}]}' + delegate_id: 0 + destination_id: 241 + entrypoint: null + errors: null + fee: 6974 + gas_limit: 3543 + hash: 0xce784687a6f40819acaca72d969174cd22c8a3dd14eb3857f64f77fd163f7e34 + id: 160 + initiator_id: 237 + internal: false + kind: 2 + level: 44 + nonce: null + paid_storage_size_diff: 6434 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 237 + status: 1 + storage_limit: 6691 + storage_size: 6434 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 4 + burned: 3031000 + consumed_gas: 8932745 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[[{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"1000"},{"int":"80"}]},{"prim":"Pair","args":[{"int":"81"},[]]}]},{"prim":"Pair","args":[{"int":"82"},{"prim":"False"}]},{"int":"0"},{"int":"83"}],{"prim":"Pair","args":[{"prim":"Pair","args":[{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"0001307461d7c7b4398303ff40d536b9fa848c0f710c"},{"bytes":"00026e354627a6c2eb69386cd8def55ec3a0a4aa70eb"}]},{"prim":"Pair","args":[{"bytes":"000265408e7ff3d4dcc3c0e746fa906fc2e5065f1aad"},{"prim":"None"}]}]},{"bytes":"016c01640a1acd661bb46408e7a854899de4ea451100"}]},{"prim":"None"}]}]}' + delegate_id: 0 + destination_id: 238 + entrypoint: null + errors: null + fee: 12951 + gas_limit: 9033 + hash: 0x6707cb9c83de1c6396b9d79f42a72d3cec9401d16cd5a4cea10554cbd13b8176 + id: 161 + initiator_id: 230 + internal: false + kind: 2 + level: 44 + nonce: null + paid_storage_size_diff: 11867 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 230 + status: 1 + storage_limit: 12124 + storage_size: 11867 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 4 + burned: 3031000 + consumed_gas: 8932745 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[[{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"1000"},{"int":"84"}]},{"prim":"Pair","args":[{"int":"85"},[]]}]},{"prim":"Pair","args":[{"int":"86"},{"prim":"False"}]},{"int":"0"},{"int":"87"}],{"prim":"Pair","args":[{"prim":"Pair","args":[{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"00019b5aec2c8bb470d580cb4989d87c4332227835d6"},{"bytes":"000239c6679d8012cb81f14d8bad681f7b13243d4ffa"}]},{"prim":"Pair","args":[{"bytes":"0002e20225983377e005022c6686f7ff58fa44fc45c9"},{"prim":"None"}]}]},{"bytes":"016c01640a1acd661bb46408e7a854899de4ea451100"}]},{"prim":"None"}]}]}' + delegate_id: 0 + destination_id: 242 + entrypoint: null + errors: null + fee: 12951 + gas_limit: 9033 + hash: 0x82d0450df851eb757156b1bf9174cd869b42da9a4fd97e597fc4a5e7fce8be2e + id: 162 + initiator_id: 235 + internal: false + kind: 2 + level: 44 + nonce: null + paid_storage_size_diff: 11867 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 235 + status: 1 + storage_limit: 12124 + storage_size: 11867 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:11:23Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 45 + deffated_storage: '[{"int":"1"},{"int":"110000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 163 + initiator_id: 0 + internal: false + kind: 1 + level: 45 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 283 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0xaf227b85db63be3f2afa7fd971ab1ebd9a3f593eff3e14f58dde08389c7991a7 + id: 164 + initiator_id: 270 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 270 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 272 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x200ed6003c364c1bd116333da50cb3085261c3199feddb1a699538645fff44b9 + id: 165 + initiator_id: 280 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 280 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 2 + counter: 1119 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 279 + entrypoint: null + errors: null + fee: 603 + gas_limit: 1539 + hash: 0x17ec7782831a6cef7e999c8dafd5102b181c07b173ef93483c71fde1eeaee665 + id: 166 + initiator_id: 267 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 267 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 2054773 + content_index: 0 + counter: 540 + deffated_storage: '{"prim":"Some","args":[{"bytes":"0200000000000000000000000000000000000000000000000000000000000000"}]}' + delegate_id: 0 + destination_id: 232 + entrypoint: '@entrypoint_0' + errors: null + fee: 518 + gas_limit: 2155 + hash: 0x64a33f139c383d2a4951ea5db3a4d74227e33f4256c35f7aa1afa19a938dc392 + id: 167 + initiator_id: 243 + internal: false + kind: 1 + level: 45 + nonce: null + paid_storage_size_diff: 0 + parameters: '{"entrypoint":"default","value":{"prim":"Pair","args":[{"bytes":"01"},{"int":"1"}]}}' + payload: null + payload_type: null + protocol_id: 3 + source_id: 243 + status: 1 + storage_limit: 0 + storage_size: 87 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 261 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0x072feb60859b0f080383400a024886ece0553d9b719461452ca3fb33758569f2 + id: 168 + initiator_id: 255 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 255 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 271 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0x0d3cc3c71a0f3629307122a3f6804f827c7448ac864e2b6c6028ea279ce1cd41 + id: 169 + initiator_id: 268 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 268 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 206250 + consumed_gas: 1704433 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"88"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 278 + entrypoint: null + errors: null + fee: 988 + gas_limit: 1805 + hash: 0x32f55c0ab4a9f0117cc876295bec18861c38ec269cdda6a053197a02af6e1eb5 + id: 170 + initiator_id: 277 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 568 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 277 + status: 1 + storage_limit: 825 + storage_size: 568 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 210500 + consumed_gas: 1705391 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"89"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]},{"prim":"Elt","args":[{"int":"2"},{"prim":"Pair","args":[{"int":"120"},{"int":"20"}]}]},{"prim":"Elt","args":[{"int":"3"},{"prim":"Pair","args":[{"int":"50"},{"int":"60"}]}]}]]}' + delegate_id: 0 + destination_id: 256 + entrypoint: null + errors: null + fee: 1005 + gas_limit: 1806 + hash: 0x0982bfc6a6c51b56c80ce88bbe37e6ad2edfdd584a12b58b48aa8f2ef1d05e9d + id: 171 + initiator_id: 262 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 585 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 262 + status: 1 + storage_limit: 842 + storage_size: 585 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 227250 + consumed_gas: 1724769 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"90"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 257 + entrypoint: null + errors: null + fee: 1074 + gas_limit: 1825 + hash: 0xa2fc076eb1cb3bbd73c155eaaeabc7382da2ff316080203eb2de05c978ef5153 + id: 172 + initiator_id: 260 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 652 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 260 + status: 1 + storage_limit: 909 + storage_size: 652 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 2 + burned: 251250 + consumed_gas: 1965709 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"91"},[]]}' + delegate_id: 0 + destination_id: 281 + entrypoint: null + errors: null + fee: 1140 + gas_limit: 2066 + hash: 0xed1cbbb2fba8501dc9c365e3ebfeca16d6907485b2243dd866516ba0eb03e119 + id: 173 + initiator_id: 263 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 748 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 263 + status: 1 + storage_limit: 1005 + storage_size: 748 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 122250 + consumed_gas: 1433807 + content_index: 0 + counter: 540 + deffated_storage: '{"bytes":"026695127e0147c3e3734b7061f0573fec0ee8fdad"}' + delegate_id: 0 + destination_id: 273 + entrypoint: null + errors: null + fee: 668 + gas_limit: 1534 + hash: 0x4b40907dc6aa568dbc1125f490898a983af66b4a28afb27dcdd461719fd1de07 + id: 174 + initiator_id: 274 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 232 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 274 + status: 1 + storage_limit: 489 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 2 + burned: 645500 + consumed_gas: 2859071 + content_index: 0 + counter: 540 + deffated_storage: '{"prim":"Pair","args":[{"prim":"Pair","args":[{"int":"92"},{"bytes":"0001aa7d7c6aa3db6d0b0b471f6102dce8cdb9cbe834"}]},{"int":"100"}]}' + delegate_id: 0 + destination_id: 275 + entrypoint: null + errors: null + fee: 2883 + gas_limit: 2960 + hash: 0x2b86c861cdd433af6129b2231d652df0c583047006d371d46eac99c242441956 + id: 175 + initiator_id: 236 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 2325 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 236 + status: 1 + storage_limit: 2582 + storage_size: 2325 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 9 + burned: 2269500 + consumed_gas: 6285093 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[[{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"0001ca36067accfc6f87908782919c0f14c462803f93"},{"bytes":"0133604c1ee2391a5db33300d8c7ec332455525a4d00"}]},{"prim":"Pair","args":[{"int":"2"},{"int":"93"}]}]},{"prim":"Pair","args":[{"int":"94"},{"int":"95"}]},{"int":"96"},{"int":"97"}],{"int":"98"}]}' + delegate_id: 0 + destination_id: 269 + entrypoint: null + errors: null + fee: 9199 + gas_limit: 6386 + hash: 0x75d1c940e2c166492791eeb268bc105c47c7060bd7b2f2bad4915188f3d06e5a + id: 176 + initiator_id: 264 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 8821 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 264 + status: 1 + storage_limit: 9078 + storage_size: 8821 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 2 + burned: 2691750 + consumed_gas: 4478816 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"7"},{"int":"99"}]}' + delegate_id: 0 + destination_id: 265 + entrypoint: null + errors: null + fee: 11153 + gas_limit: 4579 + hash: 0x0416e1ba25a1b8832e1a264bad8d1eb525b21c3aeb3c3604424ee46e071f126d + id: 177 + initiator_id: 276 + internal: false + kind: 2 + level: 45 + nonce: null + paid_storage_size_diff: 10510 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 276 + status: 1 + storage_limit: 10767 + storage_size: 10510 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:13:29Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 46 + deffated_storage: '[{"int":"1"},{"int":"112500100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 178 + initiator_id: 0 + internal: false + kind: 1 + level: 46 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:15:41Z +- allocated_destination_contract: false + allocated_destination_contract_burned: 0 + amount: 0 + big_map_diffs_count: 0 + burned: 0 + consumed_gas: 223 + content_index: 0 + counter: 47 + deffated_storage: '[{"int":"1"},{"int":"115000100"},{"int":"100"},{"bytes":"01e927f00ef734dfc85919635e9afc9166c83ef9fc00"},{"bytes":"0115eb0104481a6d7921160bc982c5e0a561cd8a3a00"}]' + delegate_id: 0 + destination_id: 2 + entrypoint: null + errors: null + fee: 0 + gas_limit: 0 + hash: null + id: 179 + initiator_id: 0 + internal: false + kind: 1 + level: 47 + nonce: null + paid_storage_size_diff: 0 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 0 + status: 1 + storage_limit: 0 + storage_size: 4630 + tag: null + tags: 32768 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:17:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 2 + counter: 540 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 307 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x7bf680382b207619cc76f57eb482096b5ee1407597b0b7a7de147478df199121 + id: 180 + initiator_id: 287 + internal: false + kind: 2 + level: 47 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 287 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:17:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 142750 + consumed_gas: 1438103 + content_index: 4 + counter: 542 + deffated_storage: '{"int":"0"}' + delegate_id: 0 + destination_id: 303 + entrypoint: null + errors: null + fee: 508 + gas_limit: 1539 + hash: 0x1437f0dbdc20280612a967268f37c57505c183a90b6cc66e7110a88613c0ff89 + id: 181 + initiator_id: 295 + internal: false + kind: 2 + level: 47 + nonce: null + paid_storage_size_diff: 314 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 295 + status: 1 + storage_limit: 571 + storage_size: 314 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:17:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 102000 + consumed_gas: 1603860 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Some","args":[{"bytes":"0572cbea904d67468808c8eb50a9450c9721db309128012543902d0ac358a62ae28f75bb8f1c7c42c39a8c5529bf0f4e166a9d8cabc673a322fda673779d8e3822ba3ecb8670e461f73bb9021d5fd76a4c56d9d4cd16bd1bba86881979749d28"}]}' + delegate_id: 0 + destination_id: 289 + entrypoint: null + errors: null + fee: 650 + gas_limit: 1704 + hash: 0xc7d51f0238701e464084817333b68e92d806dd8b4f5dbd28f875f7fb6076ce95 + id: 182 + initiator_id: 290 + internal: false + kind: 2 + level: 47 + nonce: null + paid_storage_size_diff: 151 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 290 + status: 1 + storage_limit: 408 + storage_size: 151 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:17:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 0 + burned: 122250 + consumed_gas: 1433807 + content_index: 1 + counter: 539 + deffated_storage: '{"bytes":"01530c982f4a18593a0d72eaf4297c554632e49023"}' + delegate_id: 0 + destination_id: 291 + entrypoint: null + errors: null + fee: 731 + gas_limit: 1534 + hash: 0x4e2f8619e36156d85c6e644a48ebf7c10b3c2e0fce04370d672c440145e953eb + id: 183 + initiator_id: 288 + internal: false + kind: 2 + level: 47 + nonce: null + paid_storage_size_diff: 232 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 288 + status: 1 + storage_limit: 489 + storage_size: 232 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:17:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 285 + entrypoint: null + errors: null + fee: 822 + gas_limit: 1616 + hash: 0xae11d963d7b9f8207bdb6fa83a0c913a174c8bfe45328de3d9b92e0aea1148ca + id: 184 + initiator_id: 292 + internal: false + kind: 2 + level: 47 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 292 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:17:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 195250 + consumed_gas: 1694927 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"100"},[]]}' + delegate_id: 0 + destination_id: 286 + entrypoint: null + errors: null + fee: 943 + gas_limit: 1795 + hash: 0xc43902b39bfe06b436a13012759dde3c36f809fbf14aac5442424fe9cf3a5c3f + id: 185 + initiator_id: 301 + internal: false + kind: 2 + level: 47 + nonce: null + paid_storage_size_diff: 524 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 301 + status: 1 + storage_limit: 781 + storage_size: 524 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:17:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 206000 + consumed_gas: 1704429 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"101"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 304 + entrypoint: null + errors: null + fee: 987 + gas_limit: 1805 + hash: 0x41fc546e5b2edb0d79d2b0fd51722057317e6db903408be8c997ceb9c9e2d22e + id: 186 + initiator_id: 293 + internal: false + kind: 2 + level: 47 + nonce: null + paid_storage_size_diff: 567 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 293 + status: 1 + storage_limit: 824 + storage_size: 567 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:17:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 1 + burned: 206250 + consumed_gas: 1704433 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"int":"102"},[{"prim":"Elt","args":[{"int":"1"},{"prim":"Pair","args":[{"int":"10000"},{"int":"50"}]}]}]]}' + delegate_id: 0 + destination_id: 302 + entrypoint: null + errors: null + fee: 988 + gas_limit: 1805 + hash: 0xd8df9c5f60cfaad71027c1b2e163f653d3d4faa756d62e611beeedfbbf47732e + id: 187 + initiator_id: 294 + internal: false + kind: 2 + level: 47 + nonce: null + paid_storage_size_diff: 568 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 294 + status: 1 + storage_limit: 825 + storage_size: 568 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:17:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 0 + burned: 143750 + consumed_gas: 1515377 + content_index: 0 + counter: 540 + deffated_storage: '{"prim":"Pair","args":[{"int":"0"},{"bytes":"000035e993d8c7aaa42b5e3ccd86a33390ececc73abd"}]}' + delegate_id: 0 + destination_id: 297 + entrypoint: null + errors: null + fee: 759 + gas_limit: 1616 + hash: 0xecaaf7a28e8a06cb876cb5161b18edd791ece03203493fec9047e03f61c5aa8e + id: 188 + initiator_id: 268 + internal: false + kind: 2 + level: 47 + nonce: null + paid_storage_size_diff: 318 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 268 + status: 1 + storage_limit: 575 + storage_size: 318 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:17:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 0 + big_map_diffs_count: 6 + burned: 1301500 + consumed_gas: 4219364 + content_index: 1 + counter: 539 + deffated_storage: '[{"prim":"Pair","args":[{"bytes":"0001a37cd5082d398fa6f22951b933a9fe4007351536"},{"prim":"Pair","args":[{"int":"2"},{"int":"103"}]}]},{"prim":"Pair","args":[{"int":"104"},{"int":"105"}]},{"prim":"False"},{"int":"106"}]' + delegate_id: 0 + destination_id: 298 + entrypoint: null + errors: null + fee: 5323 + gas_limit: 4320 + hash: 0x3db06d9a0b3314ff98b3153ba55af08d62e94253d04127c431205e238e70f2ca + id: 189 + initiator_id: 305 + internal: false + kind: 2 + level: 47 + nonce: null + paid_storage_size_diff: 4949 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 305 + status: 1 + storage_limit: 5206 + storage_size: 4949 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:17:47Z +- allocated_destination_contract: true + allocated_destination_contract_burned: 64250 + amount: 1000000 + big_map_diffs_count: 2 + burned: 1796250 + consumed_gas: 3664419 + content_index: 1 + counter: 539 + deffated_storage: '{"prim":"Pair","args":[{"prim":"Pair","args":[{"bytes":"00017e3970e2057dec9f91cb66f5b222d8f38af568b0"},{"int":"107"}]},{"prim":"Pair","args":[{"prim":"False"},{"int":"50"}]}]}' + delegate_id: 0 + destination_id: 300 + entrypoint: null + errors: null + fee: 7630 + gas_limit: 3765 + hash: 0xee5c1afa2965f6df2a72e476e5ce32fee4e7e40bd152b96e07b9f07df11b6ecc + id: 190 + initiator_id: 296 + internal: false + kind: 2 + level: 47 + nonce: null + paid_storage_size_diff: 6928 + parameters: null + payload: null + payload_type: null + protocol_id: 3 + source_id: 296 + status: 1 + storage_limit: 7185 + storage_size: 6928 + tag: null + tags: 0 + ticket_updates_count: 0 + timestamp: 2022-01-25T17:17:47Z +- id: 191 + content_index: 0 + level: 41 + counter: 136721 + fee: 0 + gas_limit: 1818 + storage_limit: 60000 + amount: 0 + consumed_gas: 100000 + storage_size: 0 + paid_storage_size_diff: 0 + burned: 0 + allocated_destination_contract_burned: 0 + protocol_id: 3 + ticket_updates_count: 0 + big_map_diffs_count: 0 + tags: 0 + nonce: 1 + initiator_id: 42 + source_id: 37 + destination_id: NULL + delegate_id: NULL + timestamp: '2022-01-27 16:39:09+00' + status: 1 + kind: 7 + entrypoint: NULL + tag: add_account_event + hash: 0xb93485a275086765e71f00488fda52cae7e0378808651f2034c36e22a143f31b + parameters: NULL + deffated_storage: NULL + payload: 0x11223344556677889900 + payload_type: 0x11223344556677889900 + errors: NULL + allocated_destination_contract: False + internal: True +- id: 192 + content_index: 0 + level: 41 + counter: 136723 + fee: 0 + gas_limit: 1818 + storage_limit: 60000 + amount: 0 + consumed_gas: 100000 + storage_size: 0 + paid_storage_size_diff: 0 + burned: 0 + allocated_destination_contract_burned: 0 + protocol_id: 3 + ticket_updates_count: 0 + big_map_diffs_count: 0 + tags: 0 + nonce: 1 + initiator_id: 42 + source_id: 37 + destination_id: NULL + delegate_id: NULL + timestamp: '2022-01-27 16:39:17+00' + status: 1 + kind: 7 + entrypoint: NULL + tag: add_account_event + hash: 0x3006fe3748e23bee8499ddd4ef69c3f910b1de0aa04080cc5be242b5123c1207 + parameters: NULL + deffated_storage: NULL + payload: 0x11223344556677889900 + payload_type: 0x11223344556677889900 + errors: NULL + allocated_destination_contract: False + internal: True diff --git a/internal/postgres/tests/fixtures/protocols.yml b/internal/postgres/tests/fixtures/protocols.yml new file mode 100644 index 000000000..043668e8b --- /dev/null +++ b/internal/postgres/tests/fixtures/protocols.yml @@ -0,0 +1,22 @@ +- id: 1 + hash: Ps9mPmXaRzmzk35gbAYNCAw6UXdE2qoABTHbN2oEEc1qM7CwT9P + start_level: 1 + end_level: 1 + sym_link: alpha + alias: Ps9mPmXa + chain_id: NetXnHfVqm9iesp + cost_per_byte: 250 + hard_gas_limit_per_operation: 1040000 + hard_storage_limit_per_operation: 60000 + time_between_blocks: 15 +- id: 3 + hash: PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx + start_level: 2 + end_level: 0 + sym_link: babylon + alias: PtHangz2 + chain_id: NetXnHfVqm9iesp + cost_per_byte: 250 + hard_gas_limit_per_operation: 1040000 + hard_storage_limit_per_operation: 60000 + time_between_blocks: 15 diff --git a/internal/postgres/tests/fixtures/script_constants.yml b/internal/postgres/tests/fixtures/script_constants.yml new file mode 100644 index 000000000..424b99574 --- /dev/null +++ b/internal/postgres/tests/fixtures/script_constants.yml @@ -0,0 +1,6 @@ +- script_id: 5 + global_constant_id: 1 +- script_id: 4 + global_constant_id: 2 +- script_id: 4 + global_constant_id: 3 \ No newline at end of file diff --git a/internal/postgres/tests/fixtures/scripts.yml b/internal/postgres/tests/fixtures/scripts.yml new file mode 100644 index 000000000..b447b438a --- /dev/null +++ b/internal/postgres/tests/fixtures/scripts.yml @@ -0,0 +1,267 @@ +- annotations: '{%minTokensBought,%minXtzWithdrawn,%minTokensWithdrawn,%tokensSold,%tokenAddress,%xtzPool,%to,%maxTokensDeposited,%tokenToToken,%lqtAddress,%tokenToXtz,%transfer,%mintOrBurn,%addLiquidity,%minLqtMinted,%default,%removeLiquidity,%lqtBurned,%minXtzBought,%lqtTotal,%outputDexterContract,%quantity,%target,%xtzToToken,%deadline,%tokenPool,%owner}' + code: '[]' + entrypoints: '{addLiquidity,default,removeLiquidity,tokenToToken,tokenToXtz,xtzToToken}' + fail_strings: '{"DIV by 0"}' + hardcoded: '{}' + hash: 92f78ba925b291d4099acd92ff79545652db1a20a59b2d6ac33023638b61df07 + id: 2 + level: 1 + parameter: '[{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"nat","annots":["%minLqtMinted"]},{"prim":"nat","annots":["%maxTokensDeposited"]},{"prim":"timestamp","annots":["%deadline"]}],"annots":["%addLiquidity"]},{"prim":"unit","annots":["%default"]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%to"]},{"prim":"nat","annots":["%lqtBurned"]},{"prim":"mutez","annots":["%minXtzWithdrawn"]},{"prim":"nat","annots":["%minTokensWithdrawn"]},{"prim":"timestamp","annots":["%deadline"]}],"annots":["%removeLiquidity"]},{"prim":"pair","args":[{"prim":"address","annots":["%outputDexterContract"]},{"prim":"nat","annots":["%minTokensBought"]},{"prim":"address","annots":["%to"]},{"prim":"nat","annots":["%tokensSold"]},{"prim":"timestamp","annots":["%deadline"]}],"annots":["%tokenToToken"]}]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%to"]},{"prim":"nat","annots":["%tokensSold"]},{"prim":"mutez","annots":["%minXtzBought"]},{"prim":"timestamp","annots":["%deadline"]}],"annots":["%tokenToXtz"]},{"prim":"pair","args":[{"prim":"address","annots":["%to"]},{"prim":"nat","annots":["%minTokensBought"]},{"prim":"timestamp","annots":["%deadline"]}],"annots":["%xtzToToken"]}]}]}]' + storage: '[{"prim":"pair","args":[{"prim":"nat","annots":["%tokenPool"]},{"prim":"mutez","annots":["%xtzPool"]},{"prim":"nat","annots":["%lqtTotal"]},{"prim":"address","annots":["%tokenAddress"]},{"prim":"address","annots":["%lqtAddress"]}]}]' + tags: 0 + views: null +- annotations: '{%target,%to,%total_supply,%callback,%getBalance,%mintOrBurn,%quantity,%approve,%spender,%transfer,%from,%getAllowance,%request,%owner,%allowances,%value,%getTotalSupply,%tokens,%admin}' + code: '[]' + entrypoints: '{approve,getAllowance,getBalance,getTotalSupply,mintOrBurn,transfer}' + fail_strings: '{UnsafeAllowanceChange,OnlyAdmin,"Cannot burn more than the target''s balance.",NotEnoughAllowance,NotEnoughBalance,DontSendTez}' + hardcoded: '{}' + hash: e5214eaf1ddcf5380cde10e6198c9b24e0bca6051443da2d7ae3adc7f36f8b1d + id: 1 + level: 1 + parameter: '[{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%spender"]},{"prim":"nat","annots":["%value"]}],"annots":["%approve"]},{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"address","annots":["%spender"]}],"annots":["%request"]},{"prim":"contract","args":[{"prim":"nat"}],"annots":["%callback"]}],"annots":["%getAllowance"]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"contract","args":[{"prim":"nat"}],"annots":["%callback"]}],"annots":["%getBalance"]},{"prim":"pair","args":[{"prim":"unit","annots":["%request"]},{"prim":"contract","args":[{"prim":"nat"}],"annots":["%callback"]}],"annots":["%getTotalSupply"]}]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"int","annots":["%quantity"]},{"prim":"address","annots":["%target"]}],"annots":["%mintOrBurn"]},{"prim":"pair","args":[{"prim":"address","annots":["%from"]},{"prim":"address","annots":["%to"]},{"prim":"nat","annots":["%value"]}],"annots":["%transfer"]}]}]}]' + storage: '[{"prim":"pair","args":[{"prim":"big_map","args":[{"prim":"address"},{"prim":"nat"}],"annots":["%tokens"]},{"prim":"big_map","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"address","annots":["%spender"]}]},{"prim":"nat"}],"annots":["%allowances"]},{"prim":"address","annots":["%admin"]},{"prim":"nat","annots":["%total_supply"]}]}]' + tags: 192 + views: null +- annotations: null + code: '[]' + entrypoints: null + fail_strings: null + hardcoded: null + hash: 8436dde35bd56644cd4f40c5f26839cb8f4b51052e415da2b9fadcd9bddcb03e + id: 5 + level: 2 + parameter: '[{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"pair","args":[{"prim":"nat","annots":["%minLqtMinted"]},{"prim":"pair","args":[{"prim":"nat","annots":["%maxTokensDeposited"]},{"prim":"timestamp","annots":["%deadline"]}]}]}],"annots":["%addLiquidity"]},{"prim":"unit","annots":["%default"]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%to"]},{"prim":"pair","args":[{"prim":"nat","annots":["%lqtBurned"]},{"prim":"pair","args":[{"prim":"mutez","annots":["%minXtzWithdrawn"]},{"prim":"pair","args":[{"prim":"nat","annots":["%minTokensWithdrawn"]},{"prim":"timestamp","annots":["%deadline"]}]}]}]}],"annots":["%removeLiquidity"]},{"prim":"pair","args":[{"prim":"address","annots":["%outputDexterContract"]},{"prim":"pair","args":[{"prim":"nat","annots":["%minTokensBought"]},{"prim":"pair","args":[{"prim":"address","annots":["%to"]},{"prim":"pair","args":[{"prim":"nat","annots":["%tokensSold"]},{"prim":"timestamp","annots":["%deadline"]}]}]}]}],"annots":["%tokenToToken"]}]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%to"]},{"prim":"pair","args":[{"prim":"nat","annots":["%tokensSold"]},{"prim":"pair","args":[{"prim":"mutez","annots":["%minXtzBought"]},{"prim":"timestamp","annots":["%deadline"]}]}]}],"annots":["%tokenToXtz"]},{"prim":"pair","args":[{"prim":"address","annots":["%to"]},{"prim":"pair","args":[{"prim":"nat","annots":["%minTokensBought"]},{"prim":"timestamp","annots":["%deadline"]}]}],"annots":["%xtzToToken"]}]}]}]' + storage: '[{"prim":"pair","args":[{"prim":"nat","annots":["%tokenPool"]},{"prim":"pair","args":[{"prim":"mutez","annots":["%xtzPool"]},{"prim":"pair","args":[{"prim":"nat","annots":["%lqtTotal"]},{"prim":"pair","args":[{"prim":"address","annots":["%tokenAddress"]},{"prim":"address","annots":["%lqtAddress"]}]}]}]}]}]' + tags: 0 + views: null +- annotations: null + code: '[]' + entrypoints: null + fail_strings: null + hardcoded: null + hash: 8707507942346132a1813c61b99197b4eb569a20b0099f0640d5cefda0bcf105 + id: 4 + level: 2 + parameter: '[{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%spender"]},{"prim":"nat","annots":["%value"]}],"annots":["%approve"]},{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"address","annots":["%spender"]}],"annots":["%request"]},{"prim":"contract","args":[{"prim":"nat"}],"annots":["%callback"]}],"annots":["%getAllowance"]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"contract","args":[{"prim":"nat"}],"annots":["%callback"]}],"annots":["%getBalance"]},{"prim":"pair","args":[{"prim":"unit","annots":["%request"]},{"prim":"contract","args":[{"prim":"nat"}],"annots":["%callback"]}],"annots":["%getTotalSupply"]}]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"int","annots":["%quantity"]},{"prim":"address","annots":["%target"]}],"annots":["%mintOrBurn"]},{"prim":"pair","args":[{"prim":"address","annots":["%from"]},{"prim":"pair","args":[{"prim":"address","annots":["%to"]},{"prim":"nat","annots":["%value"]}]}],"annots":["%transfer"]}]}]}]' + storage: '[{"prim":"pair","args":[{"prim":"big_map","args":[{"prim":"address"},{"prim":"nat"}],"annots":["%tokens"]},{"prim":"pair","args":[{"prim":"big_map","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"address","annots":["%spender"]}]},{"prim":"nat"}],"annots":["%allowances"]},{"prim":"pair","args":[{"prim":"address","annots":["%admin"]},{"prim":"nat","annots":["%total_supply"]}]}]}]}]' + tags: 0 + views: null +- annotations: '{%requests,%balance,%new_exchange_order,%token_total_supply,%admin,%ledger,%token_amount_to_buy,%token_to_buy,%metadata,%transfer,%txs,%seller,%buy_xtz_wrapper,%remove_operator,%buyer,%token_id,%confirm_buy_from_exchange,%token_info,%order_type,%sell,%tokens_to_mint,%last_token_id,%token_metadata,%create_new_order,%buyer_balance,%balance_of,%callback,%update_operators,%token_id_to_buy,%mint_more_tokens,%redeem_xtz_wrapper,%token_metadata_registry,%exchange_address,%operators,%fulfill_order,%owner,%buy_from_exchange,%status,%add_operator,%token_admins,%buy,%amount,%token_ids,%can_mint_more,%operator,%amount_to_buy,%token_id_to_sell,%burn_tokens,%total_supply,%request,%order_id,%token_amount_to_sell,%from_,%to_,%mint_tokens,%total_token_amount,%update_exchange_address}' + code: '[]' + entrypoints: '{balance_of,burn_tokens,buy_from_exchange,buy_xtz_wrapper,confirm_buy_from_exchange,mint_more_tokens,mint_tokens,new_exchange_order,redeem_xtz_wrapper,token_metadata_registry,transfer,update_exchange_address,update_operators}' + fail_strings: '{INSUFFICIENT_TOTAL_SUPPLY,NO_BALANCE,NO_BALANCE_FOUND,NO_TOTAL_SUPPLY_FOUND,UNCONFIRMED_EXCHANGE,BUYER_INSUFFICIENT_BALANCE,NO_ACCOUNT,FA2_NOT_OPERATOR,FA2_NOT_OWNER,INSUFFICIENT_BALANCE,NO_AMOUNT_PROVIDED,"DIV by 0",UNKNOWN_CONTRACT,NO_WTOKEN,FA2_TX_DENIED,SELLER_INSUFFICIENT_BALANCE,FIXED_TOTAL_SUPPLY,CONTRACT_ERROR,NO_TOKEN_FOUND,UNAUTHORIZED_ACTION}' + hardcoded: '{}' + hash: 73293b1eaa14a9209dc9bfcb2058d6cd43ad3a8d575156baa9b7419a9f1ec60f + id: 10 + level: 33 + parameter: '[{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%requests"]},{"prim":"contract","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"nat","annots":["%token_id"]}],"annots":["%request"]},{"prim":"nat","annots":["%balance"]}]}]}],"annots":["%callback"]}],"annots":["%balance_of"]},{"prim":"pair","args":[{"prim":"nat"},{"prim":"nat"}],"annots":["%burn_tokens"]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"nat","annots":["%order_id"]},{"prim":"pair","args":[{"prim":"nat","annots":["%token_to_buy"]},{"prim":"nat","annots":["%amount"]}]}],"annots":["%buy_from_exchange"]},{"prim":"unit","annots":["%buy_xtz_wrapper"]}]}]},{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"nat","annots":["%order_id"]},{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"nat"},{"prim":"nat"}],"annots":["%token_ids"]},{"prim":"pair","args":[{"prim":"bool","annots":["%status"]},{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"nat","annots":["%token_id"]}],"annots":["%from_"]},{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"nat","annots":["%token_id"]}],"annots":["%to_"]}]}]}]}],"annots":["%confirm_buy_from_exchange"]},{"prim":"pair","args":[{"prim":"nat","annots":["%token_id"]},{"prim":"nat","annots":["%tokens_to_mint"]}],"annots":["%mint_more_tokens"]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"bytes","annots":["%metadata"]},{"prim":"pair","args":[{"prim":"nat","annots":["%total_supply"]},{"prim":"bool","annots":["%can_mint_more"]}]}],"annots":["%mint_tokens"]},{"prim":"pair","args":[{"prim":"or","args":[{"prim":"unit","annots":["%buy"]},{"prim":"unit","annots":["%sell"]}],"annots":["%order_type"]},{"prim":"pair","args":[{"prim":"nat","annots":["%token_id_to_sell"]},{"prim":"pair","args":[{"prim":"nat","annots":["%token_amount_to_sell"]},{"prim":"pair","args":[{"prim":"nat","annots":["%token_id_to_buy"]},{"prim":"pair","args":[{"prim":"nat","annots":["%token_amount_to_buy"]},{"prim":"pair","args":[{"prim":"nat","annots":["%total_token_amount"]},{"prim":"address","annots":["%seller"]}]}]}]}]}]}],"annots":["%new_exchange_order"]}]}]}]},{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"nat","annots":["%redeem_xtz_wrapper"]},{"prim":"contract","args":[{"prim":"address"}],"annots":["%token_metadata_registry"]}]},{"prim":"or","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%from_"]},{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%to_"]},{"prim":"pair","args":[{"prim":"nat","annots":["%token_id"]},{"prim":"nat","annots":["%amount"]}]}]}],"annots":["%txs"]}]}],"annots":["%transfer"]},{"prim":"address","annots":["%update_exchange_address"]}]}]},{"prim":"list","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"pair","args":[{"prim":"address","annots":["%operator"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%add_operator"]},{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"pair","args":[{"prim":"address","annots":["%operator"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%remove_operator"]}]}],"annots":["%update_operators"]}]}]}]' + storage: '[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%admin"]},{"prim":"address","annots":["%exchange_address"]}]},{"prim":"pair","args":[{"prim":"nat","annots":["%last_token_id"]},{"prim":"big_map","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"nat","annots":["%token_id"]}]},{"prim":"nat"}],"annots":["%ledger"]}]}]},{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"big_map","args":[{"prim":"string"},{"prim":"bytes"}],"annots":["%metadata"]},{"prim":"big_map","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"pair","args":[{"prim":"address","annots":["%operator"]},{"prim":"nat","annots":["%token_id"]}]}]},{"prim":"unit"}],"annots":["%operators"]}]},{"prim":"pair","args":[{"prim":"big_map","args":[{"prim":"nat"},{"prim":"pair","args":[{"prim":"address"},{"prim":"bool"}]}],"annots":["%token_admins"]},{"prim":"big_map","args":[{"prim":"nat"},{"prim":"pair","args":[{"prim":"nat","annots":["%token_id"]},{"prim":"map","args":[{"prim":"string"},{"prim":"bytes"}],"annots":["%token_info"]}]}],"annots":["%token_metadata"]}]}]}]},{"prim":"big_map","args":[{"prim":"nat"},{"prim":"nat"}],"annots":["%token_total_supply"]}]}]' + tags: 16640 + views: null +- annotations: '{%metadata}' + code: '[[{"prim":"PUSH","args":[{"prim":"nat"},{"int":"42"}]},{"prim":"FAILWITH"}]]' + entrypoints: '{default}' + fail_strings: '{}' + hardcoded: '{}' + hash: 2f6e929c1f8e4f59dd98e16e675d3d4e20710803fa5545e24bb585815b7a4156 + id: 11 + level: 33 + parameter: '[{"prim":"unit"}]' + storage: '[{"prim":"pair","args":[{"prim":"nat"},{"prim":"big_map","args":[{"prim":"string"},{"prim":"bytes"}],"annots":["%metadata"]}]}]' + tags: 0 + views: null +- annotations: '{}' + code: '[[[],[[[[{"prim":"DUP"}],{"prim":"CAR"}],[[[[{"prim":"DIP","args":[[{"prim":"DUP"}]]},{"prim":"SWAP"}]],{"prim":"CDR"}],[{"prim":"PUSH","args":[{"prim":"unit"},{"prim":"Unit"}]},[[[[[{"prim":"DIP","args":[[[{"prim":"DIP","args":[[{"prim":"DUP"}]]},{"prim":"SWAP"}]]]},{"prim":"SWAP"}],[{"prim":"DIP","args":[[[{"prim":"DIP","args":[[{"prim":"DUP"}]]},{"prim":"SWAP"}]]]},{"prim":"SWAP"}]],{"prim":"ADD"}],{"prim":"NIL","args":[{"prim":"operation"}]}],{"prim":"PAIR"}]],[],{"prim":"DIP","args":[[[{"prim":"DIP","args":[[[{"prim":"DIP","args":[[{"prim":"DIP","args":[[{"prim":"DIP","args":[[[]]]}]]}]]},{"prim":"DROP"}]]]},{"prim":"DROP"}]]]}],[],{"prim":"DIP","args":[[[{"prim":"DIP","args":[[{"prim":"DIP","args":[[[]]]}]]},{"prim":"DROP"}]]]}],{"prim":"DIP","args":[[[{"prim":"DIP","args":[[[]]]},{"prim":"DROP"}]]]}]]]' + entrypoints: '{default}' + fail_strings: '{}' + hardcoded: '{}' + hash: 5fb5c920caf3b0cff8ec27c181b24cc6270f88c27f0a3c31f3e0c31eee16aa0f + id: 7 + level: 33 + parameter: '[{"prim":"int"}]' + storage: '[{"prim":"int"}]' + tags: 0 + views: null +- annotations: '{%default,%do}' + code: '[[[[{"prim":"DUP"},{"prim":"CAR"},{"prim":"DIP","args":[[{"prim":"CDR"}]]}]],{"prim":"IF_LEFT","args":[[{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"0"}]},{"prim":"AMOUNT"},[[{"prim":"COMPARE"},{"prim":"EQ"}],{"prim":"IF","args":[[],[[{"prim":"UNIT"},{"prim":"FAILWITH"}]]]}],[{"prim":"DIP","args":[[{"prim":"DUP"}]]},{"prim":"SWAP"}],{"prim":"IMPLICIT_ACCOUNT"},{"prim":"ADDRESS"},{"prim":"SENDER"},[[{"prim":"COMPARE"},{"prim":"EQ"}],{"prim":"IF","args":[[],[[{"prim":"UNIT"},{"prim":"FAILWITH"}]]]}],{"prim":"UNIT"},{"prim":"EXEC"},{"prim":"PAIR"}],[{"prim":"DROP"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PAIR"}]]}]]' + entrypoints: '{do,default}' + fail_strings: '{}' + hardcoded: '{}' + hash: 1709f72d4862d37c5068588c313c13205d7e28b472a3ef5f12af031211a68140 + id: 14 + level: 34 + parameter: '[{"prim":"or","args":[{"prim":"lambda","args":[{"prim":"unit"},{"prim":"list","args":[{"prim":"operation"}]}],"annots":["%do"]},{"prim":"unit","annots":["%default"]}]}]' + storage: '[{"prim":"key_hash"}]' + tags: 4 + views: null +- annotations: '{}' + code: '[[{"prim":"CAR"},{"prim":"UNPAIR"},{"prim":"ADD"},{"prim":"SOME"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PAIR"}]]' + entrypoints: '{default}' + fail_strings: '{}' + hardcoded: '{}' + hash: d514378f4976181f0b86c764bbd7877496479fcd942c2736471363d3cb300073 + id: 17 + level: 36 + parameter: '[{"prim":"pair","args":[{"prim":"bls12_381_fr"},{"prim":"bls12_381_fr"}]}]' + storage: '[{"prim":"option","args":[{"prim":"bls12_381_fr"}]}]' + tags: 0 + views: null +- annotations: '{%transfer,%ledger,%allowances,%balance,%getAllowance,%getBalance,%getTotalSupply,%mint,%owner,%totalSupply,%approve}' + code: '[]' + entrypoints: '{approve,getAllowance,getBalance,getTotalSupply,mint,transfer}' + fail_strings: '{UnsafeAllowanceChange,UnauthorizedAccess,SameOriginAndDestination,NotEnoughAllowance,NotEnoughBalance,"This contract do not accept token",SameOwnerAndSpender,NoAccount}' + hardcoded: '{}' + hash: 8123a8335833ab7cf7e30f3d18dc0c9c8f152c938717162adfa1446d33985775 + id: 18 + level: 36 + parameter: '[{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address"},{"prim":"nat"}],"annots":["%approve"]},{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address"},{"prim":"address"}]},{"prim":"contract","args":[{"prim":"nat"}]}],"annots":["%getAllowance"]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address"},{"prim":"contract","args":[{"prim":"nat"}]}],"annots":["%getBalance"]},{"prim":"pair","args":[{"prim":"unit"},{"prim":"contract","args":[{"prim":"nat"}]}],"annots":["%getTotalSupply"]}]}]},{"prim":"or","args":[{"prim":"nat","annots":["%mint"]},{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address"},{"prim":"address"}]},{"prim":"nat"}],"annots":["%transfer"]}]}]}]' + storage: '[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"big_map","args":[{"prim":"address"},{"prim":"pair","args":[{"prim":"map","args":[{"prim":"address"},{"prim":"nat"}],"annots":["%allowances"]},{"prim":"nat","annots":["%balance"]}]}],"annots":["%ledger"]},{"prim":"address","annots":["%owner"]}]},{"prim":"nat","annots":["%totalSupply"]}]}]' + tags: 0 + views: null +- annotations: '{}' + code: '[[{"prim":"CAR"},{"prim":"UNPAIR"},{"prim":"MUL"},{"prim":"SOME"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PAIR"}]]' + entrypoints: '{default}' + fail_strings: '{}' + hardcoded: '{}' + hash: 963ee7133564ad8fd16ceeb76ee0ac5ad16e42c75674ed7811d9b50a2af12917 + id: 19 + level: 38 + parameter: '[{"prim":"pair","args":[{"prim":"bls12_381_g1"},{"prim":"bls12_381_fr"}]}]' + storage: '[{"prim":"option","args":[{"prim":"bls12_381_g1"}]}]' + tags: 0 + views: null +- annotations: '{}' + code: '[[{"prim":"CAR"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PAIR"}]]' + entrypoints: '{default}' + fail_strings: '{}' + hardcoded: '{}' + hash: 95d118c83ad81586ba4a39c07a47ff7804f5e6d1ebe1a943016d0c61b4940fb6 + id: 21 + level: 39 + parameter: '[{"prim":"chest"}]' + storage: '[{"prim":"chest"}]' + tags: 0 + views: null +- annotations: '{}' + code: '[[{"prim":"CAR"},{"prim":"SOME"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PAIR"}]]' + entrypoints: '{default}' + fail_strings: '{}' + hardcoded: '{}' + hash: 0ec97cb0766fb3c6a092769e54e87cbe15d595b70c37e984df316c65e74d2196 + id: 22 + level: 40 + parameter: '[{"prim":"bls12_381_g2"}]' + storage: '[{"prim":"option","args":[{"prim":"bls12_381_g2"}]}]' + tags: 0 + views: null +- annotations: '{}' + code: '[[{"prim":"PUSH","args":[{"prim":"mutez"},{"int":"1000000"}]},{"prim":"AMOUNT"},[{"prim":"COMPARE"},{"prim":"GE"},{"prim":"IF","args":[[],[{"prim":"PUSH","args":[{"prim":"string"},{"string":"You did not provide enough tez."}]},{"prim":"FAILWITH"}]]}],{"prim":"UNPAIR"},{"prim":"SWAP"},{"prim":"DUP"},{"prim":"CAR"},{"prim":"DIP","args":[[{"prim":"PUSH","args":[{"prim":"int"},{"int":"15"}]}]]},[{"prim":"COMPARE"},{"prim":"LT"},{"prim":"IF","args":[[{"prim":"SWAP"},{"prim":"PUSH","args":[{"prim":"int"},{"int":"34"}]},[{"prim":"COMPARE"},{"prim":"EQ"},{"prim":"IF","args":[[{"prim":"SENDER"},{"prim":"CONTRACT","args":[{"prim":"unit"}]},[{"prim":"IF_NONE","args":[[{"prim":"FAILWITH"}],[]]}],{"prim":"BALANCE"},{"prim":"UNIT"},{"prim":"TRANSFER_TOKENS"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"SWAP"},{"prim":"CONS"},{"prim":"PAIR"}],[{"prim":"UNPAIR"},{"prim":"PUSH","args":[{"prim":"int"},{"int":"1"}]},{"prim":"ADD"},{"prim":"PAIR"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PAIR"}]]}]],[{"prim":"DIP","args":[[{"prim":"DROP"}]]},{"prim":"DUP"},{"prim":"CDR"},{"prim":"CONTRACT","args":[{"prim":"unit"}]},[{"prim":"IF_NONE","args":[[{"prim":"FAILWITH"}],[]]}],{"prim":"BALANCE"},{"prim":"UNIT"},{"prim":"TRANSFER_TOKENS"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"SWAP"},{"prim":"CONS"},{"prim":"PAIR"}]]}]]]' + entrypoints: '{default}' + fail_strings: '{"You did not provide enough tez."}' + hardcoded: '{}' + hash: 12cedb44977e89ba5ef4600c23598fe0b992db15e63b88691a5f835eb391acd6 + id: 16 + level: 35 + parameter: '[{"prim":"int"}]' + storage: '[{"prim":"pair","args":[{"prim":"int"},{"prim":"address"}]}]' + tags: 0 + views: null +- annotations: '{}' + code: '[[{"prim":"CAR"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PAIR"}]]' + entrypoints: '{default}' + fail_strings: '{}' + hardcoded: '{}' + hash: 12fac86327a687810a7f70c5fab1eb650bb44c63eb7526628171f4e72b0711a1 + id: 23 + level: 40 + parameter: '[{"prim":"chest_key"}]' + storage: '[{"prim":"chest_key"}]' + tags: 0 + views: null +- annotations: '{@stored_counter,@keys,@new_counter,%main,%change_keys,%keys,:payload,%threshold,@counter,@valid,%default,:action,@threshold,%counter,%operation,%sigs,%stored_counter}' + code: '[]' + entrypoints: '{default,main}' + fail_strings: '{}' + hardcoded: '{}' + hash: f997eb0b0553c611bc5fcb7a42c9241be54ee6e3823989ff17d8701d879a9c62 + id: 25 + level: 41 + parameter: '[{"prim":"or","args":[{"prim":"unit","annots":["%default"]},{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"nat","annots":["%counter"]},{"prim":"or","args":[{"prim":"lambda","args":[{"prim":"unit"},{"prim":"list","args":[{"prim":"operation"}]}],"annots":["%operation"]},{"prim":"pair","args":[{"prim":"nat","annots":["%threshold"]},{"prim":"list","args":[{"prim":"key"}],"annots":["%keys"]}],"annots":["%change_keys"]}],"annots":[":action"]}],"annots":[":payload"]},{"prim":"list","args":[{"prim":"option","args":[{"prim":"signature"}]}],"annots":["%sigs"]}],"annots":["%main"]}]}]' + storage: '[{"prim":"pair","args":[{"prim":"nat","annots":["%stored_counter"]},{"prim":"pair","args":[{"prim":"nat","annots":["%threshold"]},{"prim":"list","args":[{"prim":"key"}],"annots":["%keys"]}]}]}]' + tags: 16 + views: null +- annotations: '{%remove_operator,%ledger,%name,%add_operator,%balance_of,%owner,%token_metadata_registry,%update_operators,%token_metadata,%symbol,%decimals,%extras,%requests,%token_id,%amount,%allowances,%total_supply,%from_,%txs,%to_,%operator,%callback,%request,%balance,%transfer}' + code: '[]' + entrypoints: '{balance_of,token_metadata_registry,transfer,update_operators}' + fail_strings: '{FA2_TOKEN_UNDEFINED,FA2_NOT_OPERATOR,FA2_INSUFFICIENT_BALANCE,FA2_NOT_OWNER}' + hardcoded: '{}' + hash: e833c5869c45dd62a74874e1c6aefde2d305f14049d91fee6bc0619995d85c95 + id: 24 + level: 40 + parameter: '[{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%requests"]},{"prim":"contract","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"nat","annots":["%token_id"]}],"annots":["%request"]},{"prim":"nat","annots":["%balance"]}]}]}],"annots":["%callback"]}],"annots":["%balance_of"]},{"prim":"contract","args":[{"prim":"address"}],"annots":["%token_metadata_registry"]}]},{"prim":"or","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%from_"]},{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%to_"]},{"prim":"pair","args":[{"prim":"nat","annots":["%token_id"]},{"prim":"nat","annots":["%amount"]}]}]}],"annots":["%txs"]}]}],"annots":["%transfer"]},{"prim":"list","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"pair","args":[{"prim":"address","annots":["%operator"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%add_operator"]},{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"pair","args":[{"prim":"address","annots":["%operator"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%remove_operator"]}]}],"annots":["%update_operators"]}]}]}]' + storage: '[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"big_map","args":[{"prim":"address"},{"prim":"pair","args":[{"prim":"set","args":[{"prim":"address"}],"annots":["%allowances"]},{"prim":"nat","annots":["%balance"]}]}],"annots":["%ledger"]},{"prim":"big_map","args":[{"prim":"nat"},{"prim":"pair","args":[{"prim":"nat","annots":["%token_id"]},{"prim":"pair","args":[{"prim":"string","annots":["%symbol"]},{"prim":"pair","args":[{"prim":"string","annots":["%name"]},{"prim":"pair","args":[{"prim":"nat","annots":["%decimals"]},{"prim":"map","args":[{"prim":"string"},{"prim":"string"}],"annots":["%extras"]}]}]}]}]}],"annots":["%token_metadata"]}]},{"prim":"nat","annots":["%total_supply"]}]}]' + tags: 256 + views: null +- annotations: '{%transfer,:to,%getAllowance,:remaining,%getAdministrator,%burn,:from,:balance,%getTotalSupply,:totalSupply,%setAdministrator,:administrator,:value,:owner,%getBalance,%setPause,%mint,%approve,:spender}' + code: '[]' + entrypoints: '{transfer,approve,getAllowance,getBalance,getTotalSupply,setPause,setAdministrator,getAdministrator,mint,burn}' + fail_strings: |- + {NotEnoughAllowance,"Unexpected failure: Negative total supply + CallStack (from HasCallStack): + failUnexpected, called at src/Lorentz/Contracts/ManagedLedger.hs:313:27 in lorentz-contracts-0.2.0.1-HpDIkWsKofu3zAjntLgs8J:Lorentz.Contracts.ManagedLedger",NotEnoughBalance,UnsafeAllowanceChange} + hardcoded: '{}' + hash: 63a6b481bda1e305164a6f8a4cf9ae74f6c1b40539ea7725bbf152e0e1e7e568 + id: 27 + level: 41 + parameter: '[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":[":from"]},{"prim":"pair","args":[{"prim":"address","annots":[":to"]},{"prim":"nat","annots":[":value"]}]}],"annots":["%transfer"]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":[":spender"]},{"prim":"nat","annots":[":value"]}],"annots":["%approve"]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":[":owner"]},{"prim":"address","annots":[":spender"]}]},{"prim":"contract","args":[{"prim":"nat","annots":[":remaining"]}]}],"annots":["%getAllowance"]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":[":owner"]},{"prim":"contract","args":[{"prim":"nat","annots":[":balance"]}]}],"annots":["%getBalance"]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"unit"},{"prim":"contract","args":[{"prim":"nat","annots":[":totalSupply"]}]}],"annots":["%getTotalSupply"]},{"prim":"or","args":[{"prim":"bool","annots":["%setPause"]},{"prim":"or","args":[{"prim":"address","annots":["%setAdministrator"]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"unit"},{"prim":"contract","args":[{"prim":"address","annots":[":administrator"]}]}],"annots":["%getAdministrator"]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":[":to"]},{"prim":"nat","annots":[":value"]}],"annots":["%mint"]},{"prim":"pair","args":[{"prim":"address","annots":[":from"]},{"prim":"nat","annots":[":value"]}],"annots":["%burn"]}]}]}]}]}]}]}]}]}]}]' + storage: '[{"prim":"pair","args":[{"prim":"big_map","args":[{"prim":"address"},{"prim":"pair","args":[{"prim":"nat"},{"prim":"map","args":[{"prim":"address"},{"prim":"nat"}]}]}]},{"prim":"pair","args":[{"prim":"address"},{"prim":"pair","args":[{"prim":"bool"},{"prim":"nat"}]}]}]}]' + tags: 192 + views: null +- annotations: '{%balance_of,%k,%update_operators,%remove_operator,%request,%operator,%mint,%address,%all_tokens,%balance,%total_supply,%amount,%add_operator,%owner,%v,%from_,%tokens,%token_id,%requests,%mutez_transfer,%ledger,%operators,%metadata_map,%set_pause,%transfer,%destination,%txs,%to_,%paused,%callback,%metadata,%set_administrator,%set_metdata,%administrator}' + code: '[]' + entrypoints: '{balance_of,mint,mutez_transfer,set_administrator,set_metdata,set_pause,transfer,update_operators}' + fail_strings: '{FA2_TOKEN_UNDEFINED,"Token-IDs should be consecutive",FA2_NOT_OPERATOR,FA2_INSUFFICIENT_BALANCE}' + hardcoded: '{}' + hash: 605dc88b24035972f0d606d26cd22f089300c53002682c4364fa0023567b6c64 + id: 15 + level: 34 + parameter: '[{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%requests"]},{"prim":"contract","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"nat","annots":["%token_id"]}],"annots":["%request"]},{"prim":"nat","annots":["%balance"]}]}]}],"annots":["%callback"]}],"annots":["%balance_of"]},{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%address"]},{"prim":"nat","annots":["%amount"]}]},{"prim":"pair","args":[{"prim":"map","args":[{"prim":"string"},{"prim":"bytes"}],"annots":["%metadata"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%mint"]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"mutez","annots":["%amount"]},{"prim":"address","annots":["%destination"]}],"annots":["%mutez_transfer"]},{"prim":"address","annots":["%set_administrator"]}]}]},{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"string","annots":["%k"]},{"prim":"bytes","annots":["%v"]}],"annots":["%set_metdata"]},{"prim":"bool","annots":["%set_pause"]}]},{"prim":"or","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%from_"]},{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%to_"]},{"prim":"pair","args":[{"prim":"nat","annots":["%token_id"]},{"prim":"nat","annots":["%amount"]}]}]}],"annots":["%txs"]}]}],"annots":["%transfer"]},{"prim":"list","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"pair","args":[{"prim":"address","annots":["%operator"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%add_operator"]},{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"pair","args":[{"prim":"address","annots":["%operator"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%remove_operator"]}]}],"annots":["%update_operators"]}]}]}]}]' + storage: '[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%administrator"]},{"prim":"pair","args":[{"prim":"nat","annots":["%all_tokens"]},{"prim":"big_map","args":[{"prim":"pair","args":[{"prim":"address"},{"prim":"nat"}]},{"prim":"nat"}],"annots":["%ledger"]}]}]},{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"big_map","args":[{"prim":"string"},{"prim":"bytes"}],"annots":["%metadata"]},{"prim":"big_map","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"pair","args":[{"prim":"address","annots":["%operator"]},{"prim":"nat","annots":["%token_id"]}]}]},{"prim":"unit"}],"annots":["%operators"]}]},{"prim":"pair","args":[{"prim":"bool","annots":["%paused"]},{"prim":"big_map","args":[{"prim":"nat"},{"prim":"pair","args":[{"prim":"map","args":[{"prim":"string"},{"prim":"bytes"}],"annots":["%metadata_map"]},{"prim":"nat","annots":["%total_supply"]}]}],"annots":["%tokens"]}]}]}]}]' + tags: 16640 + views: null +- annotations: '{%max_price,%metadata,%taco_shop_storage,%current_stock}' + code: '[[{"prim":"DUP"},{"prim":"CAR"},{"prim":"SWAP"},{"prim":"CDR"},{"prim":"DUP"},{"prim":"CDR"},{"prim":"DIG","args":[{"int":"2"}]},{"prim":"DUP"},{"prim":"DUG","args":[{"int":"3"}]},{"prim":"GET"},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"Unknown kind of taco."}]},{"prim":"FAILWITH"}],[]]},{"prim":"DUP"},{"prim":"CAR"},{"prim":"SWAP"},{"prim":"DUP"},{"prim":"DUG","args":[{"int":"2"}]},{"prim":"CDR"},{"prim":"EDIV"},{"prim":"IF_NONE","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"DIV by 0"}]},{"prim":"FAILWITH"}],[]]},{"prim":"CAR"},{"prim":"AMOUNT"},{"prim":"COMPARE"},{"prim":"NEQ"},{"prim":"IF","args":[[{"prim":"PUSH","args":[{"prim":"string"},{"string":"Sorry, the taco you are trying to purchase has a different price"}]},{"prim":"FAILWITH"}],[]]},{"prim":"DUP"},{"prim":"PUSH","args":[{"prim":"nat"},{"int":"1"}]},{"prim":"DIG","args":[{"int":"2"}]},{"prim":"CAR"},{"prim":"SUB"},{"prim":"ABS"},{"prim":"SWAP"},{"prim":"CDR"},{"prim":"SWAP"},{"prim":"PAIR"},{"prim":"SWAP"},{"prim":"DUP"},{"prim":"CDR"},{"prim":"DIG","args":[{"int":"2"}]},{"prim":"DIG","args":[{"int":"3"}]},{"prim":"SWAP"},{"prim":"SOME"},{"prim":"SWAP"},{"prim":"UPDATE"},{"prim":"SWAP"},{"prim":"CAR"},{"prim":"PAIR"},{"prim":"NIL","args":[{"prim":"operation"}]},{"prim":"PAIR"}]]' + entrypoints: '{default}' + fail_strings: '{"Sorry, the taco you are trying to purchase has a different price","Unknown kind of taco.","DIV by 0"}' + hardcoded: '{}' + hash: 621506fddbe82712919f68b8b52bcc684cff7bdc650409f4b038cffd2da1e018 + id: 8 + level: 33 + parameter: '[{"prim":"nat"}]' + storage: '[{"prim":"pair","args":[{"prim":"big_map","args":[{"prim":"string"},{"prim":"bytes"}],"annots":["%metadata"]},{"prim":"map","args":[{"prim":"nat"},{"prim":"pair","args":[{"prim":"nat","annots":["%current_stock"]},{"prim":"mutez","annots":["%max_price"]}]}],"annots":["%taco_shop_storage"]}]}]' + tags: 8192 + views: null +- annotations: '{%update_operators,%operator,%mint,%remove_minter,%permits,%balance_of,%expiry,%owner,%callback,%configure_minter,%transfer_ownership,%from,%call_FA2,%roles,%add_operator,%pause,%permit,%created_at,%amount,%balance,%txs,%minter,%master_minter,%accept_ownership,%remove_operator,%change_pauser,%current_minting_allowance,%default_expiry,%ledger,%tos,%minting_allowances,%permit_counter,%transfer,%paused,%request,%token_metadata_registry,%assertReceivers,%metadata,%change_master_minter,%to_,%token_id,%set_transferlist,%unpause,%assertTransfers,%operators,%pauser,%burn,%set_expiry,%from_,%requests,%transferlist_contract,%new_minting_allowance,%pending_owner}' + code: '[]' + entrypoints: '{accept_ownership,burn,balance_of,token_metadata_registry,transfer,update_operators,change_master_minter,change_pauser,configure_minter,mint,pause,permit,remove_minter,set_expiry,set_transferlist,transfer_ownership,unpause}' + fail_strings: '{NO_PENDING_OWNER_SET,FA2_NOT_OPERATOR,CURRENT_ALLOWANCE_REQUIRED,ALLOWANCE_MISMATCH,DUP_PERMIT,EXPIRY_TOO_BIG,BAD_TRANSFERLIST,NOT_MINTER,EXPIRED_PERMIT,ADDR_NOT_MINTER,ALLOWANCE_EXCEEDED,MISSIGNED,FA2_TOKEN_UNDEFINED,BAD_TRANSFERLIST_CONTRACT,MINTER_LIMIT_REACHED,FA2_INSUFFICIENT_BALANCE}' + hardcoded: '{}' + hash: 0610bd7b273554377e05bae4779d46350935e792e85b915ba5f72d6044133bee + id: 12 + level: 33 + parameter: '[{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"unit","annots":["%accept_ownership"]},{"prim":"list","args":[{"prim":"nat"}],"annots":["%burn"]}]},{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%requests"]},{"prim":"contract","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"nat","annots":["%token_id"]}],"annots":["%request"]},{"prim":"nat","annots":["%balance"]}]}]}],"annots":["%callback"]}],"annots":["%balance_of"]},{"prim":"contract","args":[{"prim":"address"}],"annots":["%token_metadata_registry"]}]},{"prim":"or","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%from_"]},{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%to_"]},{"prim":"pair","args":[{"prim":"nat","annots":["%token_id"]},{"prim":"nat","annots":["%amount"]}]}]}],"annots":["%txs"]}]}],"annots":["%transfer"]},{"prim":"list","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"pair","args":[{"prim":"address","annots":["%operator"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%add_operator"]},{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"pair","args":[{"prim":"address","annots":["%operator"]},{"prim":"nat","annots":["%token_id"]}]}],"annots":["%remove_operator"]}]}],"annots":["%update_operators"]}]}],"annots":["%call_FA2"]},{"prim":"address","annots":["%change_master_minter"]}]}]},{"prim":"or","args":[{"prim":"or","args":[{"prim":"address","annots":["%change_pauser"]},{"prim":"pair","args":[{"prim":"address","annots":["%minter"]},{"prim":"pair","args":[{"prim":"option","args":[{"prim":"nat"}],"annots":["%current_minting_allowance"]},{"prim":"nat","annots":["%new_minting_allowance"]}]}],"annots":["%configure_minter"]}]},{"prim":"or","args":[{"prim":"list","args":[{"prim":"pair","args":[{"prim":"address","annots":["%to_"]},{"prim":"nat","annots":["%amount"]}]}],"annots":["%mint"]},{"prim":"unit","annots":["%pause"]}]}]}]},{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"key"},{"prim":"pair","args":[{"prim":"signature"},{"prim":"bytes"}]}],"annots":["%permit"]},{"prim":"address","annots":["%remove_minter"]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address"},{"prim":"pair","args":[{"prim":"nat"},{"prim":"option","args":[{"prim":"bytes"}]}]}],"annots":["%set_expiry"]},{"prim":"option","args":[{"prim":"address"}],"annots":["%set_transferlist"]}]}]},{"prim":"or","args":[{"prim":"address","annots":["%transfer_ownership"]},{"prim":"unit","annots":["%unpause"]}]}]}]}]' + storage: '[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"nat","annots":["%default_expiry"]},{"prim":"big_map","args":[{"prim":"address"},{"prim":"nat"}],"annots":["%ledger"]}]},{"prim":"pair","args":[{"prim":"big_map","args":[{"prim":"string"},{"prim":"bytes"}],"annots":["%metadata"]},{"prim":"map","args":[{"prim":"address"},{"prim":"nat"}],"annots":["%minting_allowances"]}]}]},{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"big_map","args":[{"prim":"pair","args":[{"prim":"address"},{"prim":"address"}]},{"prim":"unit"}],"annots":["%operators"]},{"prim":"bool","annots":["%paused"]}]},{"prim":"pair","args":[{"prim":"nat","annots":["%permit_counter"]},{"prim":"big_map","args":[{"prim":"address"},{"prim":"pair","args":[{"prim":"option","args":[{"prim":"nat"}],"annots":["%expiry"]},{"prim":"map","args":[{"prim":"bytes"},{"prim":"pair","args":[{"prim":"timestamp","annots":["%created_at"]},{"prim":"option","args":[{"prim":"nat"}],"annots":["%expiry"]}]}],"annots":["%permits"]}]}],"annots":["%permits"]}]}]}]},{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%master_minter"]},{"prim":"address","annots":["%owner"]}]},{"prim":"pair","args":[{"prim":"address","annots":["%pauser"]},{"prim":"option","args":[{"prim":"address"}],"annots":["%pending_owner"]}]}],"annots":["%roles"]},{"prim":"address","annots":["%token_metadata_registry"]}]},{"prim":"option","args":[{"prim":"address"}],"annots":["%transferlist_contract"]}]}]}]' + tags: 16664 + views: null +- annotations: '{%f,%setAdministrator,%amount,%getAdministrator,%transfer,%whitelist,%spender,%target,%whitelisted,%approve,%getAllowance,%arg,%blacklist,%setPause,%owner,%burn,%totalSupply,%balances,%paused,%address,%getTotalSupply,%mint,%administrator,%getWhitelist,%approvals,%balance,%t,%getBalance}' + code: '[]' + entrypoints: '{approve,blacklist,burn,getAdministrator,getAllowance,getBalance,getTotalSupply,getWhitelist,mint,setAdministrator,setPause,transfer,whitelist}' + fail_strings: '{Get-item:56,"WrongCondition: self.data.balances[params.address].balance >= params.amount",Get-item:-1,"WrongCondition: (sp.sender == self.data.administrator) | ((~ self.data.paused) & ((params.f == sp.sender) | (self.data.balances[params.f].approvals[sp.sender] >= params.amount)))","WrongCondition: (sp.sender == self.data.administrator) | ((~ self.data.paused) & (params.f == sp.sender))","WrongCondition: self.data.balances[params.f].whitelisted",Get-item:71,Get-item:84,Get-item:50,Get-item:35,set_in_top-any,"WrongCondition: (self.data.balances[params.f].approvals.get(params.t, 0) == 0) | (params.amount == 0)",Get-item:23,Get-item:32,"WrongCondition: self.data.balances[params.t].whitelisted",Get-item:17,"WrongCondition: self.data.balances[params.f].balance >= params.amount","WrongCondition: sp.sender == self.data.administrator",Get-item:64}' + hardcoded: '{}' + hash: 9c584198b127e405160e3b7e2b3c4b3fdd92590a20bbdf10a1f5ea59be30b3e9 + id: 20 + level: 38 + parameter: '[{"prim":"or","args":[{"prim":"or","args":[{"prim":"or","args":[{"prim":"pair","args":[{"prim":"int","annots":["%amount"]},{"prim":"pair","args":[{"prim":"address","annots":["%f"]},{"prim":"address","annots":["%t"]}]}],"annots":["%approve"]},{"prim":"or","args":[{"prim":"address","annots":["%blacklist"]},{"prim":"pair","args":[{"prim":"address","annots":["%address"]},{"prim":"int","annots":["%amount"]}],"annots":["%burn"]}]}]},{"prim":"or","args":[{"prim":"address","annots":["%getAdministrator"]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"address","annots":["%spender"]}],"annots":["%arg"]},{"prim":"address","annots":["%target"]}],"annots":["%getAllowance"]},{"prim":"pair","args":[{"prim":"address","annots":["%owner"]},{"prim":"contract","args":[{"prim":"pair","args":[{"prim":"nat","annots":["%balance"]},{"prim":"address","annots":["%owner"]}]}],"annots":["%target"]}],"annots":["%getBalance"]}]}]}]},{"prim":"or","args":[{"prim":"or","args":[{"prim":"contract","args":[{"prim":"int"}],"annots":["%getTotalSupply"]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"address","annots":["%address"]},{"prim":"address","annots":["%target"]}],"annots":["%getWhitelist"]},{"prim":"pair","args":[{"prim":"address","annots":["%address"]},{"prim":"int","annots":["%amount"]}],"annots":["%mint"]}]}]},{"prim":"or","args":[{"prim":"or","args":[{"prim":"address","annots":["%setAdministrator"]},{"prim":"bool","annots":["%setPause"]}]},{"prim":"or","args":[{"prim":"pair","args":[{"prim":"int","annots":["%amount"]},{"prim":"pair","args":[{"prim":"address","annots":["%f"]},{"prim":"address","annots":["%t"]}]}],"annots":["%transfer"]},{"prim":"address","annots":["%whitelist"]}]}]}]}]}]' + storage: '[{"prim":"pair","args":[{"prim":"pair","args":[{"prim":"address","annots":["%administrator"]},{"prim":"big_map","args":[{"prim":"address"},{"prim":"pair","args":[{"prim":"map","args":[{"prim":"address"},{"prim":"int"}],"annots":["%approvals"]},{"prim":"pair","args":[{"prim":"int","annots":["%balance"]},{"prim":"bool","annots":["%whitelisted"]}]}]}],"annots":["%balances"]}]},{"prim":"pair","args":[{"prim":"bool","annots":["%paused"]},{"prim":"int","annots":["%totalSupply"]}]}]}]' + tags: 0 + views: '[]' diff --git a/internal/postgres/tests/fixtures/smart_rollup.yml b/internal/postgres/tests/fixtures/smart_rollup.yml new file mode 100644 index 000000000..6bc174469 --- /dev/null +++ b/internal/postgres/tests/fixtures/smart_rollup.yml @@ -0,0 +1,90 @@ +- id: 1 + level: 7049 + timestamp: 2023-04-21 08:12:08+00 + size: 6552 + address_id: 344 + genesis_commitment_hash: src14NYMAZ2imKQ5HpG25HZEZJuUC8H6rKYXL2hpq5vArk4Ayy5W8Z + pvm_kind: wasm_2_0_0 + kernel: 0061736d0100000001280760037f7f + type: 7b227072696d223a226279746573227d +- id: 2 + level: 7854 + timestamp: 2023-04-21 10:11:28+00 + size: 6552 + address_id: 345 + genesis_commitment_hash: src14JZYZXvqs9i3CDr3MaWuJj8yxsxkhhorCzt9k1BxYyNPJLLrxh + pvm_kind: wasm_2_0_0 + kernel: 0061736d0100000001280760037f7f + type: 7b227072696d223a226279746573227d +- id: 3 + level: 8218 + timestamp: 2023-04-21 11:06:09+00 + size: 6552 + address_id: 346 + genesis_commitment_hash: src131RsXj71miKm35DabLwzaJs2AgpQKYXQGRvw16AwXz3yvmXUHL + pvm_kind: wasm_2_0_0 + kernel: 0061736d0100000001280760037f7f + type: 7b227072696d223a226279746573227d +- id: 4 + level: 10011 + timestamp: 2023-04-21 15:36:26+00 + size: 6552 + address_id: 347 + genesis_commitment_hash: src14HfiGSyWUV4moG8rN9qDKTQYWR1XQXcm5URrfkxJE4t1S41v1z + pvm_kind: wasm_2_0_0 + kernel: 0061736d0100000001280760037f7f + type: 7b227072696d223a226279746573227d +- id: 5 + level: 10129 + timestamp: 2023-04-21 15:53:24+00 + size: 6552 + address_id: 348 + genesis_commitment_hash: src13fnBT9vaT31CKgS7EtQ1dnPWWeQo7scUTwrZBSK8rt4DB5UMKK + pvm_kind: wasm_2_0_0 + kernel: 0061736d0100000001280760037f7f + type: 7b227072696d223a226279746573227d +- id: 6 + level: 10377 + timestamp: 2023-04-21 16:29:05+00 + size: 6552 + address_id: 349 + genesis_commitment_hash: src13yxntBY5NLqvHQafaRLcfevP2i1Q4nHJ9cHntnYr45AgQi9arg + pvm_kind: wasm_2_0_0 + kernel: 0061736d0100000001280760037f7f + type: 7b227072696d223a226279746573227d +- id: 7 + level: 105547 + timestamp: 2023-05-01 13:38:01+00 + size: 6552 + address_id: 350 + genesis_commitment_hash: src14KuoLebrjcw3nSW2dJCS5xYC8zo4ZHDWwHP75PPJJAqa9ESG51 + pvm_kind: wasm_2_0_0 + kernel: 0061736d0100000001610e60037f7f7f017f60027f7f017f60027f7f0060057f7f + type: 7b227072696d223a22756e6974227d +- id: 8 + level: 106805 + timestamp: 2023-05-01 16:27:21+00 + size: 6552 + address_id: 351 + genesis_commitment_hash: src14BMi8FNeynQcUvc6TDeAvxMkBpoBrRskkTNuhn8wsdnKFBKQgc + pvm_kind: wasm_2_0_0 + kernel: 0061736d0100000001610e60037f7f7f017f60027f7f017f60027f7f0060 + type: 7b227072696d223a22756e6974227d +- id: 9 + level: 114998 + timestamp: 2023-05-02 10:48:58+00 + size: 6552 + address_id: 352 + genesis_commitment_hash: src13cdt3tdz7GPyo6r49NvDEga6dfQRUy1P5UMCTHxLbSnc3BHLLT + pvm_kind: wasm_2_0_0 + kernel: 0061736d0100000001610e60037f7f7f017f60027f7f017f60027f70 + type: 7b227072696d223a22756e6974227d +- id: 10 + level: 117106 + timestamp: 2023-05-02 15:31:52+00 + size: 6552 + address_id: 353 + genesis_commitment_hash: src13ePc8kx6YT7wpK4gLJ2qNLRgcL5pwWkTMaea5x1UUVH5MXK9Qy + pvm_kind: wasm_2_0_0 + kernel: 0061736d0100000001610e60037f7f7f017f60027f7f017f60027f7f00 + type: 7b227072696d223a22756e6974227d diff --git a/internal/postgres/tests/fixtures/stats.yml b/internal/postgres/tests/fixtures/stats.yml new file mode 100644 index 000000000..3c0d9346d --- /dev/null +++ b/internal/postgres/tests/fixtures/stats.yml @@ -0,0 +1,7 @@ +- id: 1 + contracts_count: 120 + operations_count: 192 + tx_count: 72 + originations_count: 118 + sr_originations_count: 0 + events_count: 2 \ No newline at end of file diff --git a/internal/postgres/tests/fixtures/ticket_balances.yml b/internal/postgres/tests/fixtures/ticket_balances.yml new file mode 100644 index 000000000..64151c996 --- /dev/null +++ b/internal/postgres/tests/fixtures/ticket_balances.yml @@ -0,0 +1,9 @@ +- ticket_id: 1 + account_id: 105 + amount: 42 +- ticket_id: 1 + account_id: 131 + amount: 43 +- ticket_id: 2 + account_id: 131 + amount: 43 \ No newline at end of file diff --git a/internal/postgres/tests/fixtures/ticket_updates.yml b/internal/postgres/tests/fixtures/ticket_updates.yml new file mode 100644 index 000000000..76435188d --- /dev/null +++ b/internal/postgres/tests/fixtures/ticket_updates.yml @@ -0,0 +1,21 @@ +- id: 1 + operation_id: 104 + level: 40 + timestamp: '2022-01-23 17:06:04+00' + ticket_id: 1 + account_id: 105 + amount: 42 +- id: 2 + operation_id: 104 + level: 40 + timestamp: '2022-01-23 17:06:04+00' + ticket_id: 1 + account_id: 131 + amount: 43 +- id: 3 + operation_id: 102 + level: 40 + timestamp: '2022-01-23 17:08:31+00' + ticket_id: 2 + account_id: 131 + amount: 43 diff --git a/internal/postgres/tests/fixtures/tickets.yml b/internal/postgres/tests/fixtures/tickets.yml new file mode 100644 index 000000000..6bb3d4bbf --- /dev/null +++ b/internal/postgres/tests/fixtures/tickets.yml @@ -0,0 +1,12 @@ +- id: 1 + ticketer_id: 133 + content_type: '{"prim":"string"}' + content: '{"string":"abc"}' + updates_count: 2 + level: 40 +- id: 2 + updates_count: 1 + level: 40 + ticketer_id: 251 + content_type: '{"prim":"int"}' + content: '{"int":"1"}' \ No newline at end of file diff --git a/internal/postgres/tests/global_constants_test.go b/internal/postgres/tests/global_constants_test.go new file mode 100644 index 000000000..2f39252fc --- /dev/null +++ b/internal/postgres/tests/global_constants_test.go @@ -0,0 +1,60 @@ +package tests + +import ( + "context" + "time" +) + +func (s *StorageTestSuite) TestGCGet() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + constant, err := s.globalConstants.Get(ctx, "expruv45XuhGc4fdRzTwwXpmp2ZyqwmUYeMmnKbxkCn5Q8uCtwkhM6") + s.Require().NoError(err) + + s.Require().EqualValues(1, constant.ID) + s.Require().EqualValues("expruv45XuhGc4fdRzTwwXpmp2ZyqwmUYeMmnKbxkCn5Q8uCtwkhM6", constant.Address) + s.Require().EqualValues("2022-01-23T17:10:55Z", constant.Timestamp.Format(time.RFC3339)) + s.Require().NotEmpty(constant.Value) + s.Require().EqualValues(30, constant.Level) +} + +func (s *StorageTestSuite) TestGCAll() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + constants, err := s.globalConstants.All( + ctx, + "expruv45XuhGc4fdRzTwwXpmp2ZyqwmUYeMmnKbxkCn5Q8uCtwkhM6", + "expru5X5fvCer8tbRkSAtwyVCs9FUCq46JQG7QCAkhZSumjbZBUGzb", + ) + s.Require().NoError(err) + s.Require().Len(constants, 2) +} + +func (s *StorageTestSuite) TestGCList() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + constants, err := s.globalConstants.List(ctx, 10, 0, "links_count", "desc") + s.Require().NoError(err) + s.Require().Len(constants, 3) +} + +func (s *StorageTestSuite) TestGCForContract() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + constants, err := s.globalConstants.ForContract(ctx, "KT1AafHA1C1vk959wvHWBispY9Y2f3fxBUUo", 10, 0) + s.Require().NoError(err) + s.Require().Len(constants, 2) +} + +func (s *StorageTestSuite) TestGCContractList() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + contracts, err := s.globalConstants.ContractList(ctx, "expruv45XuhGc4fdRzTwwXpmp2ZyqwmUYeMmnKbxkCn5Q8uCtwkhM6", 10, 0) + s.Require().NoError(err) + s.Require().Len(contracts, 1) +} diff --git a/internal/postgres/tests/migrations_test.go b/internal/postgres/tests/migrations_test.go new file mode 100644 index 000000000..50f5205b1 --- /dev/null +++ b/internal/postgres/tests/migrations_test.go @@ -0,0 +1,25 @@ +package tests + +import ( + "context" + "time" + + "github.com/baking-bad/bcdhub/internal/models/types" +) + +func (s *StorageTestSuite) TestMigrationGet() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + migrations, err := s.migrations.Get(ctx, 1) + s.Require().NoError(err) + s.Require().Len(migrations, 2) + + m := migrations[0] + s.Require().EqualValues(4, m.ID) + s.Require().EqualValues(3, m.ProtocolID) + s.Require().EqualValues(1, m.PrevProtocolID) + s.Require().EqualValues(1, m.ContractID) + s.Require().EqualValues(2, m.Level) + s.Require().EqualValues(types.MigrationKindUpdate, m.Kind) +} diff --git a/internal/postgres/tests/operations_test.go b/internal/postgres/tests/operations_test.go new file mode 100644 index 000000000..e1b6df470 --- /dev/null +++ b/internal/postgres/tests/operations_test.go @@ -0,0 +1,211 @@ +package tests + +import ( + "context" + "time" + + "github.com/baking-bad/bcdhub/internal/models/types" + "github.com/baking-bad/bcdhub/internal/testsuite" +) + +func (s *StorageTestSuite) TestOperationsLast() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + operation, err := s.operations.Last(ctx, map[string]interface{}{ + "destination_id": 88, + }, -1) + s.Require().NoError(err) + + s.Require().EqualValues(67, operation.ID) + s.Require().EqualValues(0, operation.ContentIndex) + s.Require().EqualValues(37, operation.Level) + s.Require().EqualValues(540, operation.Counter) + s.Require().EqualValues(518, operation.Fee) + s.Require().EqualValues(2155, operation.GasLimit) + s.Require().EqualValues(0, operation.StorageLimit) + s.Require().EqualValues(0, operation.Amount) + s.Require().EqualValues(2054659, operation.ConsumedGas) + s.Require().EqualValues(87, operation.StorageSize) + s.Require().EqualValues(92, operation.InitiatorID) + s.Require().EqualValues(92, operation.SourceID) + s.Require().EqualValues(88, operation.DestinationID) + s.Require().EqualValues(types.OperationStatusApplied, operation.Status) + s.Require().EqualValues(types.OperationKindTransaction, operation.Kind) + s.Require().EqualValues("@entrypoint_0", operation.Entrypoint.String()) + s.Require().NotEmpty(operation.Parameters) + s.Require().NotEmpty(operation.DeffatedStorage) + s.Require().Equal(testsuite.MustHexDecode("a47ce950e17c7f06af8e9e992ae10ad2b7aca0cf8a72c0ce451684f673f20324"), operation.Hash) +} + +func (s *StorageTestSuite) TestOperationsGetByHash() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + hash := testsuite.MustHexDecode("a47ce950e17c7f06af8e9e992ae10ad2b7aca0cf8a72c0ce451684f673f20324") + + operations, err := s.operations.GetByHash(ctx, hash) + s.Require().NoError(err) + s.Require().Len(operations, 1) + + operation := operations[0] + + s.Require().EqualValues(67, operation.ID) + s.Require().EqualValues(0, operation.ContentIndex) + s.Require().EqualValues(37, operation.Level) + s.Require().EqualValues(540, operation.Counter) + s.Require().EqualValues(518, operation.Fee) + s.Require().EqualValues(2155, operation.GasLimit) + s.Require().EqualValues(0, operation.StorageLimit) + s.Require().EqualValues(0, operation.Amount) + s.Require().EqualValues(2054659, operation.ConsumedGas) + s.Require().EqualValues(87, operation.StorageSize) + s.Require().EqualValues(92, operation.InitiatorID) + s.Require().EqualValues(92, operation.SourceID) + s.Require().EqualValues(88, operation.DestinationID) + s.Require().EqualValues(types.OperationStatusApplied, operation.Status) + s.Require().EqualValues(types.OperationKindTransaction, operation.Kind) + s.Require().EqualValues("@entrypoint_0", operation.Entrypoint.String()) + s.Require().NotEmpty(operation.Parameters) + s.Require().NotEmpty(operation.DeffatedStorage) + s.Require().Equal(testsuite.MustHexDecode("a47ce950e17c7f06af8e9e992ae10ad2b7aca0cf8a72c0ce451684f673f20324"), operation.Hash) +} + +func (s *StorageTestSuite) TestOperationsGetById() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + operation, err := s.operations.GetByID(ctx, 67) + s.Require().NoError(err) + + s.Require().EqualValues(67, operation.ID) + s.Require().EqualValues(0, operation.ContentIndex) + s.Require().EqualValues(37, operation.Level) + s.Require().EqualValues(540, operation.Counter) + s.Require().EqualValues(518, operation.Fee) + s.Require().EqualValues(2155, operation.GasLimit) + s.Require().EqualValues(0, operation.StorageLimit) + s.Require().EqualValues(0, operation.Amount) + s.Require().EqualValues(2054659, operation.ConsumedGas) + s.Require().EqualValues(87, operation.StorageSize) + s.Require().EqualValues(92, operation.InitiatorID) + s.Require().EqualValues(92, operation.SourceID) + s.Require().EqualValues(88, operation.DestinationID) + s.Require().EqualValues(types.OperationStatusApplied, operation.Status) + s.Require().EqualValues(types.OperationKindTransaction, operation.Kind) + s.Require().EqualValues("@entrypoint_0", operation.Entrypoint.String()) + s.Require().NotEmpty(operation.Parameters) + s.Require().NotEmpty(operation.DeffatedStorage) + s.Require().Equal(testsuite.MustHexDecode("a47ce950e17c7f06af8e9e992ae10ad2b7aca0cf8a72c0ce451684f673f20324"), operation.Hash) +} + +func (s *StorageTestSuite) TestOperationGroups() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + opg, err := s.operations.OPG(ctx, "KT18sWFGnjvobw9BiHrm9bjpWr3AFAAVas9w", 10, -1) + s.Require().NoError(err) + s.Require().Len(opg, 2) + + operation := opg[0] + s.Require().EqualValues(67, operation.LastID) + s.Require().EqualValues(0, operation.ContentIndex) + s.Require().EqualValues(37, operation.Level) + s.Require().EqualValues(540, operation.Counter) + s.Require().EqualValues(0, operation.Flow) + s.Require().EqualValues(518, operation.TotalCost) + s.Require().EqualValues(0, operation.Internals) + s.Require().EqualValues(types.OperationStatusApplied, operation.Status) + s.Require().EqualValues(types.OperationKindTransaction, operation.Kind) + s.Require().Equal(testsuite.MustHexDecode("a47ce950e17c7f06af8e9e992ae10ad2b7aca0cf8a72c0ce451684f673f20324"), operation.Hash) +} + +func (s *StorageTestSuite) TestOperationGetByHashAndCounter() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + hash := testsuite.MustHexDecode("a47ce950e17c7f06af8e9e992ae10ad2b7aca0cf8a72c0ce451684f673f20324") + operations, err := s.operations.GetByHashAndCounter(ctx, hash, 540) + s.Require().NoError(err) + s.Require().Len(operations, 1) + + operation := operations[0] + s.Require().EqualValues(67, operation.ID) + s.Require().EqualValues(0, operation.ContentIndex) + s.Require().EqualValues(37, operation.Level) + s.Require().EqualValues(540, operation.Counter) + s.Require().EqualValues(518, operation.Fee) + s.Require().EqualValues(2155, operation.GasLimit) + s.Require().EqualValues(0, operation.StorageLimit) + s.Require().EqualValues(0, operation.Amount) + s.Require().EqualValues(2054659, operation.ConsumedGas) + s.Require().EqualValues(87, operation.StorageSize) + s.Require().EqualValues(92, operation.InitiatorID) + s.Require().EqualValues(92, operation.SourceID) + s.Require().EqualValues(88, operation.DestinationID) + s.Require().EqualValues(types.OperationStatusApplied, operation.Status) + s.Require().EqualValues(types.OperationKindTransaction, operation.Kind) + s.Require().EqualValues("@entrypoint_0", operation.Entrypoint.String()) + s.Require().NotEmpty(operation.Parameters) + s.Require().NotEmpty(operation.DeffatedStorage) + s.Require().Equal(testsuite.MustHexDecode("a47ce950e17c7f06af8e9e992ae10ad2b7aca0cf8a72c0ce451684f673f20324"), operation.Hash) +} + +func (s *StorageTestSuite) TestOperationGetImplicitOperation() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + operations, err := s.operations.GetByHashAndCounter(ctx, nil, 2) + s.Require().NoError(err) + s.Require().Len(operations, 1) + + operation := operations[0] + + s.Require().EqualValues(1, operation.ID) + s.Require().EqualValues(0, operation.ContentIndex) + s.Require().EqualValues(2, operation.Level) + s.Require().EqualValues(2, operation.Counter) + s.Require().EqualValues(0, operation.Fee) + s.Require().EqualValues(0, operation.GasLimit) + s.Require().EqualValues(0, operation.StorageLimit) + s.Require().EqualValues(0, operation.Amount) + s.Require().EqualValues(2468, operation.ConsumedGas) + s.Require().EqualValues(4630, operation.StorageSize) + s.Require().EqualValues(0, operation.InitiatorID) + s.Require().EqualValues(0, operation.SourceID) + s.Require().EqualValues(2, operation.DestinationID) + s.Require().EqualValues(types.OperationStatusApplied, operation.Status) + s.Require().EqualValues(types.OperationKindTransaction, operation.Kind) + s.Require().Empty(operation.Parameters) + s.Require().NotEmpty(operation.DeffatedStorage) + s.Require().Empty(operation.Hash) +} + +func (s *StorageTestSuite) TestOperationListEvents() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + operations, err := s.operations.ListEvents(ctx, 37, 10, 0) + s.Require().NoError(err) + s.Require().Len(operations, 2) + + operation := operations[0] + s.Require().EqualValues(192, operation.ID) + s.Require().EqualValues(0, operation.ContentIndex) + s.Require().EqualValues(41, operation.Level) + s.Require().EqualValues(136723, operation.Counter) + s.Require().EqualValues(0, operation.Fee) + s.Require().EqualValues(1818, operation.GasLimit) + s.Require().EqualValues(60000, operation.StorageLimit) + s.Require().EqualValues(0, operation.Amount) + s.Require().EqualValues(100000, operation.ConsumedGas) + s.Require().EqualValues(0, operation.StorageSize) + s.Require().EqualValues(42, operation.InitiatorID) + s.Require().EqualValues(37, operation.SourceID) + s.Require().EqualValues(types.OperationStatusApplied, operation.Status) + s.Require().EqualValues(types.OperationKindEvent, operation.Kind) + s.Require().EqualValues("add_account_event", operation.Tag.String()) + s.Require().NotEmpty(operation.Payload) + s.Require().NotEmpty(operation.PayloadType) + s.Require().Equal(testsuite.MustHexDecode("3006fe3748e23bee8499ddd4ef69c3f910b1de0aa04080cc5be242b5123c1207"), operation.Hash) +} diff --git a/internal/postgres/tests/protocols_test.go b/internal/postgres/tests/protocols_test.go new file mode 100644 index 000000000..73919dc60 --- /dev/null +++ b/internal/postgres/tests/protocols_test.go @@ -0,0 +1,45 @@ +package tests + +import ( + "context" + "time" +) + +func (s *StorageTestSuite) TestProtocolGet() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + protocol, err := s.protocols.Get(ctx, "PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx", -1) + s.Require().NoError(err) + + s.Require().EqualValues(3, protocol.ID) + s.Require().EqualValues(2, protocol.StartLevel) + s.Require().EqualValues("PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx", protocol.Hash) + s.Require().EqualValues("NetXnHfVqm9iesp", protocol.ChainID) +} + +func (s *StorageTestSuite) TestProtocolGetByLevel() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + protocol, err := s.protocols.Get(ctx, "", 3) + s.Require().NoError(err) + + s.Require().EqualValues(3, protocol.ID) + s.Require().EqualValues(2, protocol.StartLevel) + s.Require().EqualValues("PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx", protocol.Hash) + s.Require().EqualValues("NetXnHfVqm9iesp", protocol.ChainID) +} + +func (s *StorageTestSuite) TestProtocolGetById() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + protocol, err := s.protocols.GetByID(ctx, 3) + s.Require().NoError(err) + + s.Require().EqualValues(3, protocol.ID) + s.Require().EqualValues(2, protocol.StartLevel) + s.Require().EqualValues("PtHangz2aRngywmSRGGvrcTyMbbdpWdpFKuS4uMWxg2RaH9i1qx", protocol.Hash) + s.Require().EqualValues("NetXnHfVqm9iesp", protocol.ChainID) +} diff --git a/internal/postgres/tests/rollback_test.go b/internal/postgres/tests/rollback_test.go new file mode 100644 index 000000000..763bc3df6 --- /dev/null +++ b/internal/postgres/tests/rollback_test.go @@ -0,0 +1,377 @@ +package tests + +import ( + "context" + "time" + + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/block" + "github.com/baking-bad/bcdhub/internal/models/protocol" + "github.com/baking-bad/bcdhub/internal/models/stats" + "github.com/baking-bad/bcdhub/internal/models/ticket" + "github.com/baking-bad/bcdhub/internal/models/types" + "github.com/baking-bad/bcdhub/internal/postgres" + "github.com/baking-bad/bcdhub/internal/testsuite" + "github.com/shopspring/decimal" +) + +func (s *StorageTestSuite) TestDeleteAll() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + count, err := saver.DeleteAll(ctx, (*block.Block)(nil), 47) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + s.Require().EqualValues(1, count) + + var block block.Block + err = s.storage.DB.NewSelect().Model(&block).Order("id desc").Limit(1).Scan(ctx) + s.Require().NoError(err) + + s.Require().EqualValues(46, block.Level) +} + +func (s *StorageTestSuite) TestStatesChangedAtLevel() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + diff, err := saver.StatesChangedAtLevel(ctx, 40) + s.Require().NoError(err) + s.Require().Len(diff, 6) + + err = saver.Commit() + s.Require().NoError(err) +} + +func (s *StorageTestSuite) TestLastDiff() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + diff, err := saver.LastDiff(ctx, 41, "exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX", true) + s.Require().NoError(err) + + s.Require().EqualValues(54, diff.ID) + s.Require().EqualValues(41, diff.Ptr) + s.Require().EqualValues(40, diff.Level) + s.Require().EqualValues(3, diff.ProtocolID) + s.Require().EqualValues(109, diff.OperationID) + s.Require().EqualValues("KT1NSpRTVR4MUwx64XCADXDUmpMGQw5yVNK1", diff.Contract) + s.Require().Equal("exprurUjYU5axnk1qjE6F2t7uDtqR64bnsxGu3AHfWiVREftRDcRPX", diff.KeyHash) + + err = saver.Commit() + s.Require().NoError(err) +} + +func (s *StorageTestSuite) TestDeleteBigMapState() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + err = saver.DeleteBigMapState(ctx, bigmapdiff.BigMapState{ID: 54}) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + var state bigmapdiff.BigMapState + err = s.storage.DB.NewSelect().Model(&state).Where("id = 54").Scan(ctx) + s.Require().Error(err) +} + +func (s *StorageTestSuite) TestSaveBigMapState() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + ts := time.Now().UTC() + + err = saver.SaveBigMapState(ctx, bigmapdiff.BigMapState{ + ID: 54, + LastUpdateLevel: 1000, + LastUpdateTime: ts, + Value: types.MustNewBytes("1122"), + Removed: true, + Key: types.MustNewBytes("7b226279746573223a223030303062333932376530353637626539643736396362666336376564653138613166303430313135313336227d"), + }) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + var state bigmapdiff.BigMapState + err = s.storage.DB.NewSelect().Model(&state).Where("id = 54").Scan(ctx) + s.Require().NoError(err) + s.Require().EqualValues(1000, state.LastUpdateLevel) + s.Require().EqualValues(true, state.Removed) + s.Require().Equal([]byte{0x11, 0x22}, []byte(state.Value)) + s.Require().Equal(ts.Format(time.RFC3339), state.LastUpdateTime.Format(time.RFC3339)) +} + +func (s *StorageTestSuite) TestGetOperations() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + ops, err := saver.GetOperations(ctx, 40) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + s.Require().Len(ops, 13) +} + +func (s *StorageTestSuite) TestGetLastAction() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + actions, err := saver.GetLastAction(ctx, 43, 46) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + s.Require().Len(actions, 2) + + s.Require().EqualValues(43, actions[0].AccountId) + s.Require().EqualValues("2022-01-25T16:45:09Z", actions[0].Time.Format(time.RFC3339)) + s.Require().EqualValues(46, actions[1].AccountId) + s.Require().EqualValues("2022-01-25T16:45:09Z", actions[1].Time.Format(time.RFC3339)) +} + +func (s *StorageTestSuite) TestUpdateAccountStats() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + ts := time.Now().UTC() + + err = saver.UpdateAccountStats(ctx, account.Account{ + ID: 43, + LastAction: ts, + OperationsCount: 1, + }) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + var acc account.Account + err = s.storage.DB.NewSelect().Model(&acc).Where("id = 43").Scan(ctx) + s.Require().NoError(err) + s.Require().EqualValues(1, acc.OperationsCount) + s.Require().EqualValues(ts.Format(time.RFC3339), acc.LastAction.Format(time.RFC3339)) +} + +func (s *StorageTestSuite) TestProtocols() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + err = saver.Protocols(ctx, 2) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + var proto protocol.Protocol + err = s.storage.DB.NewSelect().Model(&proto).Order("id desc").Limit(1).Scan(ctx) + s.Require().NoError(err) + s.Require().EqualValues(0, proto.EndLevel) + s.Require().EqualValues("Ps9mPmXaRzmzk35gbAYNCAw6UXdE2qoABTHbN2oEEc1qM7CwT9P", proto.Hash) +} + +func (s *StorageTestSuite) TestRollbackUpdateStats() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + err = saver.UpdateStats(ctx, stats.Stats{ + ID: 1, + ContractsCount: 1, + OperationsCount: 188, + OriginationsCount: 119, + TransactionsCount: 71, + EventsCount: 1, + }) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + var stats stats.Stats + err = s.storage.DB.NewSelect().Model(&stats).Limit(1).Scan(ctx) + s.Require().NoError(err) + s.Require().EqualValues(1, stats.ContractsCount) + s.Require().EqualValues(188, stats.OperationsCount) + s.Require().EqualValues(71, stats.TransactionsCount) + s.Require().EqualValues(119, stats.OriginationsCount) + s.Require().EqualValues(1, stats.EventsCount) + s.Require().EqualValues(0, stats.SrOriginationsCount) +} + +func (s *StorageTestSuite) TestGetMigrations() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + migrations, err := saver.GetMigrations(ctx, 2) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + s.Require().Len(migrations, 3) + + migration := migrations[0] + s.Require().EqualValues(1, migration.Contract.AccountID) +} + +func (s *StorageTestSuite) TestGetTicketUpdates() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + updates, err := saver.GetTicketUpdates(ctx, 40) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + s.Require().Len(updates, 3) + + update := updates[0] + s.Require().EqualValues(105, update.AccountId) + s.Require().EqualValues(133, update.Ticket.TicketerID) +} + +func (s *StorageTestSuite) TestUpdateTicket() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + err = saver.UpdateTicket(ctx, ticket.Ticket{ + ID: 1, + ContentType: testsuite.MustHexDecode("7b227072696d223a22737472696e67227d"), + Content: testsuite.MustHexDecode("7b22737472696e67223a22616263227d"), + TicketerID: 133, + UpdatesCount: 1, + }) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + var t ticket.Ticket + err = s.storage.DB.NewSelect().Model(&t).Where("id = 1").Scan(ctx) + s.Require().NoError(err) + s.Require().EqualValues(133, t.TicketerID) + s.Require().EqualValues(1, t.UpdatesCount) +} + +func (s *StorageTestSuite) TestGetLastActionNoRows() { + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + actions, err := saver.GetLastAction(ctx, 1000000) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + s.Require().Len(actions, 0) +} + +func (s *StorageTestSuite) TestTicketBalancesRollback() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + err = saver.TicketBalances(ctx, &ticket.Balance{ + TicketId: 1, + AccountId: 131, + Amount: decimal.RequireFromString("43"), + }) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + var balances []ticket.Balance + err = s.storage.DB.NewSelect().Model(&balances).Where("amount > 0").Where("ticket_id = 1").Scan(ctx) + s.Require().NoError(err) + s.Require().Len(balances, 1) +} + +func (s *StorageTestSuite) TestDeleteTickets() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + ids, err := saver.DeleteTickets(ctx, 40) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + s.Require().Len(ids, 2) + s.Require().ElementsMatch([]int64{1, 2}, ids) +} + +func (s *StorageTestSuite) TestDeleteTicketBalances() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + saver, err := postgres.NewRollback(s.storage.DB) + s.Require().NoError(err) + + err = saver.DeleteTicketBalances(ctx, []int64{1}) + s.Require().NoError(err) + + err = saver.Commit() + s.Require().NoError(err) + + var balances []ticket.Balance + err = s.storage.DB.NewSelect().Model(&balances).Where("ticket_id = 1").Scan(ctx) + s.Require().NoError(err) + s.Require().Len(balances, 0) +} diff --git a/internal/postgres/tests/smart_rollup_test.go b/internal/postgres/tests/smart_rollup_test.go new file mode 100644 index 000000000..4422d9f6f --- /dev/null +++ b/internal/postgres/tests/smart_rollup_test.go @@ -0,0 +1,38 @@ +package tests + +import ( + "context" + "time" +) + +func (s *StorageTestSuite) TestSrList() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + smartRollups, err := s.smartRollups.List(ctx, 3, 0, "ASC") + s.Require().NoError(err) + s.Require().Len(smartRollups, 3) + + sr := smartRollups[0] + s.Require().EqualValues(1, sr.ID) + s.Require().NotEmpty(sr.Type) + s.Require().NotEmpty(sr.Kernel) + s.Require().Equal("wasm_2_0_0", sr.PvmKind) + s.Require().EqualValues(6552, sr.Size) + s.Require().EqualValues("sr1BP9kkXc1T4sRpX4kZuQoWKauLkMjijEDv", sr.Address.Address) +} + +func (s *StorageTestSuite) TestSrGet() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + sr, err := s.smartRollups.Get(ctx, "sr1BP9kkXc1T4sRpX4kZuQoWKauLkMjijEDv") + s.Require().NoError(err) + + s.Require().EqualValues(1, sr.ID) + s.Require().NotEmpty(sr.Type) + s.Require().NotEmpty(sr.Kernel) + s.Require().Equal("wasm_2_0_0", sr.PvmKind) + s.Require().EqualValues(6552, sr.Size) + s.Require().EqualValues("sr1BP9kkXc1T4sRpX4kZuQoWKauLkMjijEDv", sr.Address.Address) +} diff --git a/internal/postgres/tests/stats_test.go b/internal/postgres/tests/stats_test.go new file mode 100644 index 000000000..790d0287f --- /dev/null +++ b/internal/postgres/tests/stats_test.go @@ -0,0 +1,21 @@ +package tests + +import ( + "context" + "time" +) + +func (s *StorageTestSuite) TestRollbackStats() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + stats, err := s.stats.Get(ctx) + s.Require().NoError(err) + + s.Require().EqualValues(120, stats.ContractsCount) + s.Require().EqualValues(192, stats.OperationsCount) + s.Require().EqualValues(72, stats.TransactionsCount) + s.Require().EqualValues(118, stats.OriginationsCount) + s.Require().EqualValues(2, stats.EventsCount) + s.Require().EqualValues(0, stats.SrOriginationsCount) +} diff --git a/internal/postgres/tests/suite_test.go b/internal/postgres/tests/suite_test.go new file mode 100644 index 000000000..7184015fa --- /dev/null +++ b/internal/postgres/tests/suite_test.go @@ -0,0 +1,119 @@ +package tests + +import ( + "context" + "database/sql" + "testing" + "time" + + "github.com/baking-bad/bcdhub/internal/postgres/account" + "github.com/baking-bad/bcdhub/internal/postgres/bigmapaction" + "github.com/baking-bad/bcdhub/internal/postgres/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/postgres/block" + "github.com/baking-bad/bcdhub/internal/postgres/contract" + "github.com/baking-bad/bcdhub/internal/postgres/core" + "github.com/baking-bad/bcdhub/internal/postgres/domains" + "github.com/baking-bad/bcdhub/internal/postgres/global_constant" + "github.com/baking-bad/bcdhub/internal/postgres/migration" + "github.com/baking-bad/bcdhub/internal/postgres/operation" + "github.com/baking-bad/bcdhub/internal/postgres/protocol" + smartrollup "github.com/baking-bad/bcdhub/internal/postgres/smart_rollup" + "github.com/baking-bad/bcdhub/internal/postgres/stats" + "github.com/baking-bad/bcdhub/internal/postgres/ticket" + "github.com/dipdup-net/go-lib/database" + "github.com/go-testfixtures/testfixtures/v3" + "github.com/stretchr/testify/suite" +) + +// StorageTestSuite - +type StorageTestSuite struct { + suite.Suite + psqlContainer *database.PostgreSQLContainer + storage *core.Postgres + + accounts *account.Storage + bigMapActions *bigmapaction.Storage + bigMapDiffs *bigmapdiff.Storage + blocks *block.Storage + contracts *contract.Storage + domains *domains.Storage + globalConstants *global_constant.Storage + migrations *migration.Storage + operations *operation.Storage + protocols *protocol.Storage + smartRollups *smartrollup.Storage + ticketUpdates *ticket.Storage + stats *stats.Storage +} + +// SetupSuite - +func (s *StorageTestSuite) SetupSuite() { + ctx, ctxCancel := context.WithTimeout(context.Background(), 60*time.Second) + defer ctxCancel() + + psqlContainer, err := database.NewPostgreSQLContainer(ctx, database.PostgreSQLContainerConfig{ + User: "user", + Password: "password", + Database: "db_test", + Port: 5432, + Image: "timescale/timescaledb:latest-pg15", + }) + s.Require().NoError(err) + s.psqlContainer = psqlContainer + + strg, err := core.New(core.Config{ + User: s.psqlContainer.Config.User, + DBName: s.psqlContainer.Config.Database, + Password: s.psqlContainer.Config.Password, + Host: s.psqlContainer.Config.Host, + Port: s.psqlContainer.MappedPort().Int(), + SslMode: "disable", + }, "public", "bcd") + s.Require().NoError(err) + s.storage = strg + + err = strg.InitDatabase(ctx) + s.Require().NoError(err) + + s.accounts = account.NewStorage(strg) + s.bigMapActions = bigmapaction.NewStorage(strg) + s.bigMapDiffs = bigmapdiff.NewStorage(strg) + s.blocks = block.NewStorage(strg) + s.contracts = contract.NewStorage(strg) + s.domains = domains.NewStorage(strg) + s.globalConstants = global_constant.NewStorage(strg) + s.migrations = migration.NewStorage(strg) + s.operations = operation.NewStorage(strg) + s.protocols = protocol.NewStorage(strg) + s.smartRollups = smartrollup.NewStorage(strg) + s.ticketUpdates = ticket.NewStorage(strg) + s.stats = stats.NewStorage(strg) +} + +// TearDownSuite - +func (s *StorageTestSuite) TearDownSuite() { + ctx, ctxCancel := context.WithTimeout(context.Background(), 5*time.Second) + defer ctxCancel() + + s.Require().NoError(s.storage.Close()) + s.Require().NoError(s.psqlContainer.Terminate(ctx)) +} + +func (s *StorageTestSuite) SetupTest() { + db, err := sql.Open("postgres", s.psqlContainer.GetDSN()) + s.Require().NoError(err) + + fixtures, err := testfixtures.New( + testfixtures.Database(db), + testfixtures.Dialect("timescaledb"), + testfixtures.Directory("./fixtures"), + testfixtures.UseAlterConstraint(), + ) + s.Require().NoError(err) + s.Require().NoError(fixtures.Load()) + s.Require().NoError(db.Close()) +} + +func TestSuiteStorage_Run(t *testing.T) { + suite.Run(t, new(StorageTestSuite)) +} diff --git a/internal/postgres/tests/ticket_test.go b/internal/postgres/tests/ticket_test.go new file mode 100644 index 000000000..3d8476794 --- /dev/null +++ b/internal/postgres/tests/ticket_test.go @@ -0,0 +1,143 @@ +package tests + +import ( + "context" + "time" + + "github.com/baking-bad/bcdhub/internal/models/ticket" + "github.com/baking-bad/bcdhub/internal/testsuite" +) + +func (s *StorageTestSuite) TestTicketUpdates() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + updates, err := s.ticketUpdates.Updates(ctx, ticket.UpdatesRequest{ + Ticketer: "KT1SM849krq9FFxGWCZyc7X5GvAz8XnRmXnf", + Limit: 10, + Offset: 0, + }) + s.Require().NoError(err) + s.Require().Len(updates, 2) + + update := updates[0] + s.Require().EqualValues(2, update.ID) + s.Require().EqualValues(104, update.OperationId) + s.Require().EqualValues(40, update.Level) + s.Require().EqualValues(1, update.TicketId) + s.Require().EqualValues(131, update.AccountId) + s.Require().EqualValues("43", update.Amount.String()) + s.Require().EqualValues("KT1SM849krq9FFxGWCZyc7X5GvAz8XnRmXnf", update.Ticket.Ticketer.Address) +} + +func (s *StorageTestSuite) TestTicketUpdatesForAccount() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + updates, err := s.ticketUpdates.Updates(ctx, ticket.UpdatesRequest{ + Account: "tz2GGf91VB3gK7MaaP8Xua6ohhHAhH4hTC11", + Limit: 10, + Offset: 0, + }) + s.Require().NoError(err) + s.Require().Len(updates, 2) + + update := updates[1] + s.Require().EqualValues(2, update.ID) + s.Require().EqualValues(104, update.OperationId) + s.Require().EqualValues(40, update.Level) + s.Require().EqualValues(1, update.TicketId) + s.Require().EqualValues(131, update.AccountId) + s.Require().EqualValues("43", update.Amount.String()) + s.Require().EqualValues("KT1SM849krq9FFxGWCZyc7X5GvAz8XnRmXnf", update.Ticket.Ticketer.Address) +} + +func (s *StorageTestSuite) TestTicketUpdatesByTicketId() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + updates, err := s.ticketUpdates.Updates(ctx, ticket.UpdatesRequest{ + TicketId: testsuite.Ptr(uint64(1)), + Limit: 10, + Offset: 0, + }) + s.Require().NoError(err) + s.Require().Len(updates, 2) + + update := updates[0] + s.Require().EqualValues(2, update.ID) + s.Require().EqualValues(104, update.OperationId) + s.Require().EqualValues(40, update.Level) + s.Require().EqualValues(1, update.TicketId) + s.Require().EqualValues(131, update.AccountId) + s.Require().EqualValues("43", update.Amount.String()) + s.Require().EqualValues("KT1SM849krq9FFxGWCZyc7X5GvAz8XnRmXnf", update.Ticket.Ticketer.Address) +} + +func (s *StorageTestSuite) TestTicketForOperation() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + updates, err := s.ticketUpdates.UpdatesForOperation(ctx, 104) + s.Require().NoError(err) + s.Require().Len(updates, 2) + + update := updates[1] + s.Require().EqualValues(2, update.ID) + s.Require().EqualValues(104, update.OperationId) + s.Require().EqualValues(40, update.Level) + s.Require().EqualValues(1, update.TicketId) + s.Require().EqualValues(131, update.AccountId) + s.Require().EqualValues("43", update.Amount.String()) + s.Require().EqualValues("KT1SM849krq9FFxGWCZyc7X5GvAz8XnRmXnf", update.Ticket.Ticketer.Address) +} + +func (s *StorageTestSuite) TestBalancesForAccount() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + balances, err := s.ticketUpdates.BalancesForAccount(ctx, 131, ticket.BalanceRequest{ + Limit: 10, + WithoutZeroBalances: true, + }) + s.Require().NoError(err) + s.Require().Len(balances, 2) + + balance := balances[0] + s.Require().EqualValues(131, balance.AccountId) + s.Require().EqualValues(1, balance.TicketId) + s.Require().EqualValues("43", balance.Amount.String()) + s.Require().NotEmpty(balance.Ticket.Content) + s.Require().NotEmpty(balance.Ticket.ContentType) + s.Require().EqualValues("KT1SM849krq9FFxGWCZyc7X5GvAz8XnRmXnf", balance.Ticket.Ticketer.Address) +} + +func (s *StorageTestSuite) TestBalancesForAccountEmpty() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + balances, err := s.ticketUpdates.BalancesForAccount(ctx, 12, ticket.BalanceRequest{ + Limit: 10, + }) + s.Require().NoError(err) + s.Require().Len(balances, 0) +} + +func (s *StorageTestSuite) TestTicketsList() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tickets, err := s.ticketUpdates.List(ctx, "KT1SM849krq9FFxGWCZyc7X5GvAz8XnRmXnf", 10, 0) + s.Require().NoError(err) + s.Require().Len(tickets, 1) + + ticket := tickets[0] + s.Require().EqualValues(1, ticket.ID) + s.Require().EqualValues(133, ticket.TicketerID) + s.Require().EqualValues(133, ticket.Ticketer.ID) + s.Require().EqualValues("KT1SM849krq9FFxGWCZyc7X5GvAz8XnRmXnf", ticket.Ticketer.Address) + s.Require().EqualValues(2, ticket.UpdatesCount) + s.Require().EqualValues(40, ticket.Level) + s.Require().Equal([]byte(`{"prim":"string"}`), ticket.ContentType) + s.Require().Equal([]byte(`{"string":"abc"}`), ticket.Content) +} diff --git a/internal/postgres/tests/transaction_test.go b/internal/postgres/tests/transaction_test.go new file mode 100644 index 000000000..bc39d03b0 --- /dev/null +++ b/internal/postgres/tests/transaction_test.go @@ -0,0 +1,446 @@ +package tests + +import ( + "context" + "time" + + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/contract" + "github.com/baking-bad/bcdhub/internal/models/migration" + "github.com/baking-bad/bcdhub/internal/models/protocol" + "github.com/baking-bad/bcdhub/internal/models/stats" + "github.com/baking-bad/bcdhub/internal/models/ticket" + "github.com/baking-bad/bcdhub/internal/models/types" + "github.com/baking-bad/bcdhub/internal/postgres/core" + "github.com/baking-bad/bcdhub/internal/testsuite" + "github.com/shopspring/decimal" +) + +func (s *StorageTestSuite) TestSave() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + account := account.Account{ + Address: "address", + Type: types.AccountTypeContract, + Level: 100, + } + err = tx.Save(ctx, &account) + s.Require().NoError(err) + s.Require().Positive(account.ID) + + err = tx.Commit() + s.Require().NoError(err) +} + +func (s *StorageTestSuite) TestMigrations() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + m := migration.Migration{ + ProtocolID: 1, + PrevProtocolID: 0, + Hash: []byte{0, 1, 2, 3, 4}, + Timestamp: time.Now(), + Level: 100, + Kind: types.MigrationKindBootstrap, + ContractID: 1, + } + err = tx.Migrations(ctx, &m) + s.Require().NoError(err) + s.Require().Positive(m.ID) + + err = tx.Commit() + s.Require().NoError(err) +} + +func (s *StorageTestSuite) TestProtocol() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + p := protocol.Protocol{ + Hash: "protocol_hash", + StartLevel: 100, + EndLevel: 200, + SymLink: "symlink", + Alias: "alias", + ChainID: "chain_id", + Constants: &protocol.Constants{}, + } + err = tx.Protocol(ctx, &p) + s.Require().NoError(err) + s.Require().Positive(p.ID) + + err = tx.Commit() + s.Require().NoError(err) +} + +func (s *StorageTestSuite) TestScriptConstants() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + sc := []*contract.ScriptConstants{ + { + ScriptId: 1, + GlobalConstantId: 1, + }, { + ScriptId: 2, + GlobalConstantId: 1, + }, { + ScriptId: 1, + GlobalConstantId: 2, + }, + } + err = tx.ScriptConstant(ctx, sc...) + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) +} + +func (s *StorageTestSuite) TestScripts() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + sc := []*contract.Script{ + { + Hash: "hash_1", + }, { + Hash: "hash_2", + }, { + Hash: "hash_3", + }, + } + err = tx.Scripts(ctx, sc...) + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) +} + +func (s *StorageTestSuite) TestScriptsConflict() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + update := contract.Script{ + Hash: "8436dde35bd56644cd4f40c5f26839cb8f4b51052e415da2b9fadcd9bddcb03e", + } + err = tx.Scripts(ctx, &update) + s.Require().NoError(err) + s.Require().EqualValues(5, update.ID) + + err = tx.Commit() + s.Require().NoError(err) +} + +func (s *StorageTestSuite) TestAccounts() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + sc := []*account.Account{ + { + Address: "address_1", + Type: types.AccountTypeContract, + Level: 100, + TicketUpdatesCount: 2, + }, { + Address: "address_12", + Type: types.AccountTypeSmartRollup, + Level: 100, + MigrationsCount: 2, + }, { + Address: "address_2", + Type: types.AccountTypeTz, + Level: 100, + EventsCount: 2, + }, + } + err = tx.Accounts(ctx, sc...) + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) +} + +func (s *StorageTestSuite) TestBigMapStates() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + sc := []*bigmapdiff.BigMapState{ + { + Key: []byte{0, 1, 2, 3}, + KeyHash: "hash 1", + Ptr: 100000, + LastUpdateLevel: 100, + Count: 1, + Removed: false, + Contract: "contract 1", + }, { + Key: []byte{0, 1, 2, 3, 4}, + KeyHash: "hash 2", + Ptr: 100000, + LastUpdateLevel: 100, + Count: 1, + Removed: false, + Contract: "contract 2", + }, { + Key: []byte{0, 1, 2, 3, 5}, + KeyHash: "hash 3", + Ptr: 100000, + LastUpdateLevel: 100, + Count: 1, + Removed: false, + Contract: "contract 3"}, + } + err = tx.BigMapStates(ctx, sc...) + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) + + var result []bigmapdiff.BigMapState + err = s.storage.DB.NewSelect().Model(&result).Where("ptr = 100000").Scan(ctx) + s.Require().NoError(err) + s.Require().Len(result, 3) +} + +func (s *StorageTestSuite) TestBabylonUpdateNonDelegator() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + c := contract.Contract{ + ID: 2, + BabylonID: 10, + } + + err = tx.BabylonUpdateNonDelegator(ctx, &c) + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) + + var newContract contract.Contract + err = s.storage.DB.NewSelect().Model(&newContract).Where("id = 2").Scan(ctx) + s.Require().NoError(err) + s.Require().EqualValues(10, newContract.BabylonID) +} + +func (s *StorageTestSuite) TestJakartaVesting() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + c := contract.Contract{ + ID: 2, + } + + err = tx.JakartaVesting(ctx, &c) + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) + + var newContract contract.Contract + err = s.storage.DB.NewSelect().Model(&newContract).Where("id = 2").Scan(ctx) + s.Require().NoError(err) + s.Require().EqualValues(5, newContract.JakartaID) +} + +func (s *StorageTestSuite) TestJakartaUpdateNonDelegator() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + c := contract.Contract{ + ID: 2, + JakartaID: 100, + } + + err = tx.JakartaUpdateNonDelegator(ctx, &c) + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) + + var newContract contract.Contract + err = s.storage.DB.NewSelect().Model(&newContract).Where("id = 2").Scan(ctx) + s.Require().NoError(err) + s.Require().EqualValues(100, newContract.JakartaID) +} + +func (s *StorageTestSuite) TestToJakarta() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + err = tx.ToJakarta(ctx) + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) + + var newContract contract.Contract + err = s.storage.DB.NewSelect().Model(&newContract).Where("id = 16").Scan(ctx) + s.Require().NoError(err) + s.Require().EqualValues(14, newContract.JakartaID) +} + +func (s *StorageTestSuite) TestDeleteBigMapStates() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + states, err := tx.DeleteBigMapStatesByContract(ctx, "KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7") + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) + s.Require().Len(states, 9) + + s.Require().Equal("KT1Pz65ssbPF7Zv9Dh7ggqUkgAYNSuJ9iia7", states[0].Contract) +} + +func (s *StorageTestSuite) TestUpdateStats() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + err = tx.UpdateStats(ctx, stats.Stats{ + ID: 1, + ContractsCount: 1, + OperationsCount: 4, + OriginationsCount: 1, + TransactionsCount: 1, + EventsCount: 1, + SrOriginationsCount: 1, + }) + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) + + var stats stats.Stats + err = s.storage.DB.NewSelect().Model(&stats).Limit(1).Scan(ctx) + s.Require().NoError(err) + s.Require().EqualValues(121, stats.ContractsCount) + s.Require().EqualValues(196, stats.OperationsCount) + s.Require().EqualValues(73, stats.TransactionsCount) + s.Require().EqualValues(119, stats.OriginationsCount) + s.Require().EqualValues(3, stats.EventsCount) + s.Require().EqualValues(1, stats.SrOriginationsCount) +} + +func (s *StorageTestSuite) TestTickets() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + err = tx.Tickets(ctx, &ticket.Ticket{ + ContentType: testsuite.MustHexDecode("7b227072696d223a22737472696e67227d"), + Content: testsuite.MustHexDecode("7b22737472696e67223a22616263227d"), + TicketerID: 133, + UpdatesCount: 1, + }, &ticket.Ticket{ + ContentType: testsuite.MustHexDecode("7b227072696d223a22737472696e67227d"), + Content: testsuite.MustHexDecode("7b22737472696e67223a22616263227d"), + TicketerID: 132, + UpdatesCount: 2, + }) + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) + + var tickets []ticket.Ticket + err = s.storage.DB.NewSelect().Model(&tickets).Scan(ctx) + s.Require().NoError(err) + s.Require().Len(tickets, 3) +} + +func (s *StorageTestSuite) TestTicketBalances() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + err = tx.TicketBalances(ctx, &ticket.Balance{ + TicketId: 1, + AccountId: 131, + Amount: decimal.RequireFromString("17"), + }, &ticket.Balance{ + TicketId: 1, + AccountId: 10, + Amount: decimal.RequireFromString("1"), + }) + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) + + var balances []ticket.Balance + err = s.storage.DB.NewSelect().Model(&balances).Where("ticket_id = 1").Scan(ctx) + s.Require().NoError(err) + s.Require().Len(balances, 3) +} + +func (s *StorageTestSuite) TestBabylonUpdateBigMapDiffs() { + ctx, cancel := context.WithTimeout(context.Background(), time.Second) + defer cancel() + + tx, err := core.NewTransaction(ctx, s.storage.DB) + s.Require().NoError(err) + + count, err := tx.BabylonUpdateBigMapDiffs(ctx, "KT1R9BdHMfGTwKnbCHii8akcB7DqzfdnD9AD", 10000) + s.Require().NoError(err) + + err = tx.Commit() + s.Require().NoError(err) + + s.Require().EqualValues(4, count) + + var diffs []bigmapdiff.BigMapDiff + err = s.storage.DB.NewSelect().Model(&diffs).Where("ptr = 10000").Scan(ctx) + s.Require().NoError(err) + s.Require().Len(diffs, 4) +} diff --git a/internal/postgres/ticket/storage.go b/internal/postgres/ticket/storage.go index 3fd970030..63e315fc9 100644 --- a/internal/postgres/ticket/storage.go +++ b/internal/postgres/ticket/storage.go @@ -1,8 +1,12 @@ package ticket import ( + "context" + + "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/ticket" "github.com/baking-bad/bcdhub/internal/postgres/core" + "github.com/uptrace/bun" ) // Storage - @@ -15,53 +19,124 @@ func NewStorage(pg *core.Postgres) *Storage { return &Storage{pg} } -// Get - -func (storage *Storage) Get(ticketer string, limit, offset int64) ([]ticket.TicketUpdate, error) { +// Updates - +func (storage *Storage) Updates(ctx context.Context, req ticket.UpdatesRequest) (response []ticket.TicketUpdate, err error) { query := storage.DB. - Model((*ticket.TicketUpdate)(nil)). - Relation("Ticketer"). - Relation("Account"). - Where("ticketer.address = ?", ticketer) + NewSelect(). + Model(&response). + Relation("Ticket"). + Relation("Ticket.Ticketer"). + Relation("Account", func(sq *bun.SelectQuery) *bun.SelectQuery { + return sq.Column("address") + }). + Limit(storage.GetPageSize(req.Limit)) - if offset > 0 { - query.Offset(int(offset)) - } - if limit > 0 { - query.Limit(storage.GetPageSize(limit)) + if req.Ticketer != "" { + var ticketerId uint64 + if err := storage.DB.NewSelect(). + Model((*account.Account)(nil)). + Column("id"). + Where("address = ?", req.Ticketer). + Limit(1). + Scan(ctx, &ticketerId); err != nil { + return nil, err + } + query.Where("ticket.ticketer_id = ?", ticketerId) } - var response []ticket.TicketUpdate - err := query.Order("id desc").Select(&response) - return response, err -} + if req.Account != "" { + var accountId uint64 + if err := storage.DB.NewSelect(). + Model((*account.Account)(nil)). + Column("id"). + Where("address = ?", req.Account). + Limit(1). + Scan(ctx, &accountId); err != nil { + return nil, err + } + query.Where("account_id = ?", accountId) + } -// Has - -func (storage *Storage) Has(contractID int64) (bool, error) { - var id int64 - err := storage.DB. - Model((*ticket.TicketUpdate)(nil)). - Column("id"). - Where("ticketer_id = ?", contractID). - OrderExpr("id ASC"). - Limit(1). - Select(&id) + if req.TicketId != nil { + query.Where("ticket_id = ?", *req.TicketId) + } - if err != nil { - if storage.IsRecordNotFound(err) { - return false, nil - } - return false, err + if req.Offset > 0 { + query.Offset(int(req.Offset)) } - return true, nil + + err = query.Order("id desc").Scan(ctx) + return } // ForOperation - -func (storage *Storage) ForOperation(operationId int64) (response []ticket.TicketUpdate, err error) { +func (storage *Storage) UpdatesForOperation(ctx context.Context, operationId int64) (response []ticket.TicketUpdate, err error) { err = storage.DB. + NewSelect(). Model(&response). - Relation("Ticketer"). + Relation("Ticket"). + Relation("Ticket.Ticketer"). Relation("Account"). Where("operation_id = ?", operationId). - Select() + Scan(ctx) + return +} + +func (storage *Storage) BalancesForAccount(ctx context.Context, accountId int64, req ticket.BalanceRequest) (balances []ticket.Balance, err error) { + query := storage.DB. + NewSelect(). + Model(&balances). + Relation("Ticket"). + Relation("Ticket.Ticketer", func(sq *bun.SelectQuery) *bun.SelectQuery { + return sq.Column("address") + }). + Where("account_id = ?", accountId) + + if req.Offset > 0 { + query.Offset(int(req.Offset)) + } + + if req.Limit > 0 && req.Limit < 100 { + query.Limit(int(req.Limit)) + } else { + query.Limit(10) + } + + if req.WithoutZeroBalances { + query.Where("amount > 0") + } + + err = query.Scan(ctx) + return +} + +func (storage *Storage) List(ctx context.Context, ticketer string, limit, offset int64) (tickets []ticket.Ticket, err error) { + var ticketerId uint64 + if err := storage.DB.NewSelect(). + Model((*account.Account)(nil)). + Column("id"). + Where("address = ?", ticketer). + Limit(1). + Scan(ctx, &ticketerId); err != nil { + return nil, err + } + + query := storage.DB. + NewSelect(). + Model(&tickets). + Where("ticketer_id = ?", ticketerId). + Relation("Ticketer") + + if offset > 0 { + query.Offset(int(offset)) + } + + if limit > 0 && limit < 100 { + query.Limit(int(limit)) + } else { + query.Limit(10) + } + + err = query.Scan(ctx) return } diff --git a/internal/rollback/big_map_states.go b/internal/rollback/big_map_states.go new file mode 100644 index 000000000..45499ee43 --- /dev/null +++ b/internal/rollback/big_map_states.go @@ -0,0 +1,52 @@ +package rollback + +import ( + "context" + + "github.com/rs/zerolog/log" +) + +func (rm Manager) rollbackBigMapState(ctx context.Context, level int64) error { + log.Info().Msg("rollback big map states...") + states, err := rm.rollback.StatesChangedAtLevel(ctx, level) + if err != nil { + return err + } + + for i, state := range states { + diff, err := rm.rollback.LastDiff(ctx, state.Ptr, state.KeyHash, false) + if err != nil { + if rm.storage.IsRecordNotFound(err) { + if err := rm.rollback.DeleteBigMapState(ctx, states[i]); err != nil { + return err + } + continue + } + return err + } + states[i].LastUpdateLevel = diff.Level + states[i].LastUpdateTime = diff.Timestamp + states[i].IsRollback = true + + if len(diff.Value) > 0 { + states[i].Value = diff.ValueBytes() + states[i].Removed = false + } else { + states[i].Removed = true + valuedDiff, err := rm.rollback.LastDiff(ctx, state.Ptr, state.KeyHash, true) + if err != nil { + if !rm.storage.IsRecordNotFound(err) { + return err + } + } else { + states[i].Value = valuedDiff.ValueBytes() + } + } + + if err := rm.rollback.SaveBigMapState(ctx, states[i]); err != nil { + return err + } + } + + return nil +} diff --git a/internal/rollback/context.go b/internal/rollback/context.go new file mode 100644 index 000000000..c4e6ec5cb --- /dev/null +++ b/internal/rollback/context.go @@ -0,0 +1,110 @@ +package rollback + +import ( + "context" + + "github.com/baking-bad/bcdhub/internal/models" + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/baking-bad/bcdhub/internal/models/stats" +) + +type rollbackContext struct { + generalStats stats.Stats + accountStats map[int64]*account.Account +} + +func newRollbackContext(ctx context.Context, statsRepo stats.Repository) (rollbackContext, error) { + stats, err := statsRepo.Get(ctx) + if err != nil { + return rollbackContext{}, err + } + return rollbackContext{ + generalStats: stats, + accountStats: make(map[int64]*account.Account), + }, nil +} + +func (rCtx *rollbackContext) applyMigration(accountId int64) { + if acc, ok := rCtx.accountStats[accountId]; ok { + acc.MigrationsCount += 1 + } else { + rCtx.accountStats[accountId] = &account.Account{ + ID: accountId, + MigrationsCount: 1, + } + } +} + +func (rCtx *rollbackContext) applyEvent(accountId int64) { + if acc, ok := rCtx.accountStats[accountId]; ok { + acc.EventsCount += 1 + } else { + rCtx.accountStats[accountId] = &account.Account{ + ID: accountId, + EventsCount: 1, + } + } +} + +func (rCtx *rollbackContext) applyTicketUpdates(accountId int64, count int64) { + if count < 1 { + return + } + + if acc, ok := rCtx.accountStats[accountId]; ok { + acc.TicketUpdatesCount += count + } else { + rCtx.accountStats[accountId] = &account.Account{ + ID: accountId, + TicketUpdatesCount: count, + } + } +} + +func (rCtx *rollbackContext) applyOperationsCount(accountId int64, count int64) { + if acc, ok := rCtx.accountStats[accountId]; ok { + acc.OperationsCount += count + } else { + rCtx.accountStats[accountId] = &account.Account{ + ID: accountId, + OperationsCount: count, + } + } +} + +func (rCtx *rollbackContext) getLastActions(ctx context.Context, rollback models.Rollback) error { + addresses := make([]int64, 0, len(rCtx.accountStats)) + for _, acc := range rCtx.accountStats { + addresses = append(addresses, acc.ID) + } + + actions, err := rollback.GetLastAction(ctx, addresses...) + if err != nil { + return err + } + + for i := range actions { + if acc, ok := rCtx.accountStats[actions[i].AccountId]; ok { + acc.LastAction = actions[i].Time + } else { + rCtx.accountStats[actions[i].AccountId] = &account.Account{ + ID: actions[i].AccountId, + LastAction: actions[i].Time, + } + } + } + return nil +} + +func (rCtx *rollbackContext) update(ctx context.Context, rollback models.Rollback) error { + if err := rollback.UpdateStats(ctx, rCtx.generalStats); err != nil { + return err + } + + for _, acc := range rCtx.accountStats { + if err := rollback.UpdateAccountStats(ctx, *acc); err != nil { + return err + } + } + return nil +} diff --git a/internal/rollback/operations.go b/internal/rollback/operations.go new file mode 100644 index 000000000..e13eabd81 --- /dev/null +++ b/internal/rollback/operations.go @@ -0,0 +1,69 @@ +package rollback + +import ( + "context" + + "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/types" + "github.com/pkg/errors" + "github.com/rs/zerolog/log" +) + +func (rm Manager) rollbackOperations(ctx context.Context, level int64, rCtx *rollbackContext) error { + log.Info().Msg("rollback operations...") + + ops, err := rm.rollback.GetOperations(ctx, level) + if err != nil { + return err + } + if len(ops) == 0 { + return nil + } + + for i := range ops { + if ops[i].DestinationID > 0 { + rCtx.applyOperationsCount(ops[i].DestinationID, 1) + rCtx.applyTicketUpdates(ops[i].DestinationID, int64(ops[i].TicketUpdatesCount)) + } + + if ops[i].SourceID > 0 { + rCtx.applyOperationsCount(ops[i].SourceID, 1) + } + + switch ops[i].Kind { + case types.OperationKindEvent: + rCtx.generalStats.EventsCount -= 1 + rCtx.applyEvent(ops[i].SourceID) + + case types.OperationKindOrigination: + rCtx.generalStats.OriginationsCount -= 1 + + case types.OperationKindSrOrigination: + rCtx.generalStats.SrOriginationsCount -= 1 + + case types.OperationKindTransaction: + rCtx.generalStats.TransactionsCount -= 1 + + case types.OperationKindRegisterGlobalConstant: + rCtx.generalStats.RegisterGlobalConstantCount -= 1 + + case types.OperationKindSrExecuteOutboxMessage: + rCtx.generalStats.SrExecutesCount -= 1 + + case types.OperationKindTransferTicket: + rCtx.generalStats.TransferTicketsCount -= 1 + } + } + + count, err := rm.rollback.DeleteAll(ctx, (*operation.Operation)(nil), level) + if err != nil { + return errors.Wrap(err, "deleting operations") + } + rCtx.generalStats.OperationsCount -= count + + if err := rCtx.getLastActions(ctx, rm.rollback); err != nil { + return errors.Wrap(err, "receiving last actions") + } + + return nil +} diff --git a/internal/rollback/rollback.go b/internal/rollback/rollback.go index 80c9a0f98..1f3c93c7f 100644 --- a/internal/rollback/rollback.go +++ b/internal/rollback/rollback.go @@ -2,227 +2,145 @@ package rollback import ( "context" - "time" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models" + "github.com/baking-bad/bcdhub/internal/models/account" "github.com/baking-bad/bcdhub/internal/models/bigmapaction" "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" "github.com/baking-bad/bcdhub/internal/models/block" "github.com/baking-bad/bcdhub/internal/models/contract" "github.com/baking-bad/bcdhub/internal/models/migration" - "github.com/baking-bad/bcdhub/internal/models/operation" + smartrollup "github.com/baking-bad/bcdhub/internal/models/smart_rollup" + "github.com/baking-bad/bcdhub/internal/models/stats" "github.com/baking-bad/bcdhub/internal/models/types" - "github.com/baking-bad/bcdhub/internal/noderpc" - "github.com/go-pg/pg/v10" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) // Manager - type Manager struct { - rpc noderpc.INode storage models.GeneralRepository blockRepo block.Repository - bmdRepo bigmapdiff.Repository + rollback models.Rollback + statsRepo stats.Repository } // NewManager - -func NewManager(rpc noderpc.INode, storage models.GeneralRepository, blockRepo block.Repository, bmdRepo bigmapdiff.Repository) Manager { +func NewManager( + storage models.GeneralRepository, + blockRepo block.Repository, + rollback models.Rollback, + statsRepo stats.Repository, +) Manager { return Manager{ - rpc, storage, blockRepo, bmdRepo, + storage: storage, + blockRepo: blockRepo, + rollback: rollback, + statsRepo: statsRepo, } } // Rollback - rollback indexer state to level -func (rm Manager) Rollback(ctx context.Context, db pg.DBI, network types.Network, fromState block.Block, toLevel int64) error { +func (rm Manager) Rollback(ctx context.Context, network types.Network, fromState block.Block, toLevel int64) error { if toLevel >= fromState.Level { return errors.Errorf("To level must be less than from level: %d >= %d", toLevel, fromState.Level) } for level := fromState.Level; level > toLevel; level-- { - logger.Info().Msgf("Rollback to %d block", level) + log.Info().Str("network", network.String()).Msgf("start rollback to %d", level) - if _, err := rm.blockRepo.Get(level); err != nil { + if _, err := rm.blockRepo.Get(ctx, level); err != nil { if rm.storage.IsRecordNotFound(err) { continue } return err } - err := db.RunInTransaction(ctx, func(tx *pg.Tx) error { - if err := rm.rollbackAll(tx, level); err != nil { - return err - } - if err := rm.rollbackOperations(tx, level); err != nil { - return err - } - if err := rm.rollbackMigrations(tx, level); err != nil { - return err - } - if err := rm.rollbackBigMapState(tx, level); err != nil { - return err - } - return nil - }) - if err != nil { - return err + if err := rm.rollbackBlock(ctx, level); err != nil { + log.Err(err).Str("network", network.String()).Msg("rollback error") + return rm.rollback.Rollback() } - } - return nil -} -func (rm Manager) rollbackAll(tx pg.DBI, level int64) error { - for _, index := range []models.Model{ - &block.Block{}, &contract.Contract{}, &bigmapdiff.BigMapDiff{}, - &bigmapaction.BigMapAction{}, &contract.GlobalConstant{}, - } { - if _, err := tx.Model(index). - Where("level = ?", level). - Delete(index); err != nil { - return err - } - - logger.Info(). - Str("model", index.GetIndex()). - Msg("rollback") + log.Info().Str("network", network.String()).Msgf("rolled back to %d", level) } - return nil -} -func (rm Manager) rollbackMigrations(tx pg.DBI, level int64) error { - logger.Info().Msg("rollback migrations...") - if _, err := tx.Model(new(migration.Migration)). - Where("contract_id IN (?)", tx.Model(new(contract.Contract)).Column("id").Where("level > ?", level)). - Where("level = ?", level). - Delete(); err != nil { - return err - } - return nil + return rm.rollback.Commit() } -func (rm Manager) rollbackBigMapState(tx pg.DBI, level int64) error { - logger.Info().Msg("rollback big map states...") - states, err := rm.bmdRepo.StatesChangedAfter(level) +func (rm Manager) rollbackBlock(ctx context.Context, level int64) error { + rollbackCtx, err := newRollbackContext(ctx, rm.statsRepo) if err != nil { return err } - for i, state := range states { - diff, err := rm.bmdRepo.LastDiff(state.Ptr, state.KeyHash, false) - if err != nil { - if rm.storage.IsRecordNotFound(err) { - if _, err := tx.Model(&states[i]).Delete(); err != nil { - return err - } - continue - } - return err - } - states[i].LastUpdateLevel = diff.Level - states[i].LastUpdateTime = diff.Timestamp - states[i].IsRollback = true - - if len(diff.Value) > 0 { - states[i].Value = diff.ValueBytes() - states[i].Removed = false - } else { - states[i].Removed = true - valuedDiff, err := rm.bmdRepo.LastDiff(state.Ptr, state.KeyHash, true) - if err != nil { - if !rm.storage.IsRecordNotFound(err) { - return err - } - } else { - states[i].Value = valuedDiff.ValueBytes() - } - } - - if err := states[i].Save(tx); err != nil { - return err - } + if err := rm.rollbackOperations(ctx, level, &rollbackCtx); err != nil { + return err + } + if err := rm.rollbackBigMapState(ctx, level); err != nil { + return err + } + if err := rm.rollbackScripts(ctx, level); err != nil { + return err + } + if err := rm.rollbackMigrations(ctx, level, &rollbackCtx); err != nil { + return err + } + if err := rm.rollbackTickets(ctx, level); err != nil { + return err + } + if err := rm.rollbackAll(ctx, level, &rollbackCtx); err != nil { + return err + } + if err := rm.rollback.Protocols(ctx, level); err != nil { + return err + } + if err := rollbackCtx.update(ctx, rm.rollback); err != nil { + return err } return nil } -type lastAction struct { - Address string `pg:"address"` - Time time.Time `pg:"time"` -} - -func (rm Manager) rollbackOperations(tx pg.DBI, level int64) error { - logger.Info().Msg("rollback operations...") - var ops []operation.Operation - if err := tx.Model(&operation.Operation{}). - Where("level = ?", level). - Select(&ops); err != nil { - return err +func (rm Manager) rollbackMigrations(ctx context.Context, level int64, rCtx *rollbackContext) error { + migrations, err := rm.rollback.GetMigrations(ctx, level) + if err != nil { + return nil } - if len(ops) == 0 { + if len(migrations) == 0 { return nil } - ids := make([]int64, len(ops)) - for i := range ops { - ids[i] = ops[i].ID + for i := range migrations { + rCtx.applyMigration(migrations[i].Contract.AccountID) } - if _, err := tx.Model(&operation.Operation{}). - WhereIn("id IN (?)", ids). - Delete(); err != nil { + if _, err := rm.rollback.DeleteAll(ctx, (*migration.Migration)(nil), level); err != nil { return err } + log.Info().Msg("rollback migrations") + return nil +} - contracts := make(map[string]uint64) - for i := range ops { - if ops[i].IsOrigination() { - continue - } - if ops[i].Destination.Type == types.AccountTypeContract { - if _, ok := contracts[ops[i].Destination.Address]; !ok { - contracts[ops[i].Destination.Address] = 1 - } else { - contracts[ops[i].Destination.Address] += 1 - } - } - if ops[i].Source.Type == types.AccountTypeContract { - if _, ok := contracts[ops[i].Source.Address]; !ok { - contracts[ops[i].Source.Address] = 1 - } else { - contracts[ops[i].Source.Address] += 1 - } - } - } - - if len(contracts) > 0 { - addresses := make([]string, 0, len(contracts)) - for address := range contracts { - addresses = append(addresses, address) - } - length := len(addresses) * 10 - - var actions []lastAction - - if _, err := tx.Query(&actions, `select max(foo.ts) as time, foo.address from ( - (select "timestamp" as ts, source as address from operations where source in (?) order by id desc limit ?) - union all - (select "timestamp" as ts, destination as address from operations where destination in (?) order by id desc limit ?) - ) as foo - group by address - `, addresses, length, addresses, length); err != nil { +func (rm Manager) rollbackAll(ctx context.Context, level int64, rCtx *rollbackContext) error { + for _, model := range []models.Model{ + (*block.Block)(nil), + (*bigmapdiff.BigMapDiff)(nil), + (*bigmapaction.BigMapAction)(nil), + (*smartrollup.SmartRollup)(nil), + (*account.Account)(nil), + } { + if _, err := rm.rollback.DeleteAll(ctx, model, level); err != nil { return err } + log.Info().Msgf("rollback: %T", model) + } - for i := range actions { - count, ok := contracts[actions[i].Address] - if !ok { - count = 1 - } - if _, err := tx.Exec(`update contracts set tx_count = tx_count - ?, last_action = ? where address = ?;`, count, actions[i].Time.UTC(), actions[i].Address); err != nil { - return err - } - } + contractsCount, err := rm.rollback.DeleteAll(ctx, (*contract.Contract)(nil), level) + if err != nil { + return err } + rCtx.generalStats.ContractsCount -= contractsCount + log.Info().Msgf("rollback contracts") return nil } diff --git a/internal/rollback/rollback_test.go b/internal/rollback/rollback_test.go new file mode 100644 index 000000000..4a8d713b0 --- /dev/null +++ b/internal/rollback/rollback_test.go @@ -0,0 +1,420 @@ +package rollback + +import ( + "context" + "database/sql" + "testing" + "time" + + "github.com/baking-bad/bcdhub/internal/models" + "github.com/baking-bad/bcdhub/internal/models/account" + "github.com/baking-bad/bcdhub/internal/models/bigmapdiff" + "github.com/baking-bad/bcdhub/internal/models/block" + "github.com/baking-bad/bcdhub/internal/models/contract" + "github.com/baking-bad/bcdhub/internal/models/migration" + "github.com/baking-bad/bcdhub/internal/models/mock" + mock_block "github.com/baking-bad/bcdhub/internal/models/mock/block" + mock_stats "github.com/baking-bad/bcdhub/internal/models/mock/stats" + "github.com/baking-bad/bcdhub/internal/models/operation" + "github.com/baking-bad/bcdhub/internal/models/stats" + "github.com/baking-bad/bcdhub/internal/models/ticket" + "github.com/baking-bad/bcdhub/internal/models/types" + "github.com/baking-bad/bcdhub/internal/testsuite" + "github.com/shopspring/decimal" + "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" +) + +func TestManager_Rollback(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + level := int64(11) + storage := mock.NewMockGeneralRepository(ctrl) + rb := mock.NewMockRollback(ctrl) + blockRepo := mock_block.NewMockRepository(ctrl) + statsRepo := mock_stats.NewMockRepository(ctrl) + + blockRepo.EXPECT(). + Get(gomock.Any(), level). + Return(block.Block{ + Level: 11, + }, nil). + Times(1) + + storage.EXPECT().IsRecordNotFound(sql.ErrNoRows).Return(true).AnyTimes() + + statsRepo.EXPECT(). + Get(gomock.Any()). + Return(stats.Stats{ + ID: 1, + ContractsCount: 100, + OperationsCount: 100, + EventsCount: 10, + TransactionsCount: 70, + OriginationsCount: 10, + SrOriginationsCount: 10, + TransferTicketsCount: 11, + }, nil). + Times(1) + + rb.EXPECT(). + GetOperations(gomock.Any(), level). + Return([]operation.Operation{ + { + Destination: account.Account{ + ID: 1, + Address: "address_1", + Type: types.AccountTypeContract, + }, + DestinationID: 1, + Source: account.Account{ + ID: 3, + Address: "address_3", + Type: types.AccountTypeTz, + }, + SourceID: 3, + Kind: types.OperationKindOrigination, + }, { + Destination: account.Account{ + ID: 1, + Address: "address_1", + Type: types.AccountTypeContract, + }, + DestinationID: 1, + Source: account.Account{ + ID: 2, + Address: "address_2", + Type: types.AccountTypeTz, + }, + SourceID: 2, + Kind: types.OperationKindTransaction, + }, { + Destination: account.Account{ + ID: 3, + Address: "address_3", + Type: types.AccountTypeTz, + }, + DestinationID: 3, + Source: account.Account{ + ID: 2, + Address: "address_2", + Type: types.AccountTypeTz, + }, + SourceID: 2, + Kind: types.OperationKindTransaction, + }, { + Destination: account.Account{ + ID: 4, + Address: "address_4", + Type: types.AccountTypeContract, + }, + DestinationID: 4, + Source: account.Account{ + ID: 2, + Address: "address_2", + Type: types.AccountTypeTz, + }, + SourceID: 2, + Kind: types.OperationKindTransaction, + }, { + Destination: account.Account{ + ID: 1, + Address: "address_1", + Type: types.AccountTypeContract, + }, + DestinationID: 1, + Source: account.Account{ + ID: 3, + Address: "address_3", + Type: types.AccountTypeTz, + }, + SourceID: 3, + Kind: types.OperationKindTransaction, + }, { + Source: account.Account{ + ID: 1, + Address: "address_1", + Type: types.AccountTypeContract, + }, + SourceID: 1, + Kind: types.OperationKindEvent, + }, { + Destination: account.Account{ + ID: 1, + Address: "address_1", + Type: types.AccountTypeContract, + }, + DestinationID: 1, + Source: account.Account{ + ID: 3, + Address: "address_3", + Type: types.AccountTypeTz, + }, + SourceID: 3, + Kind: types.OperationKindTransferTicket, + TicketUpdatesCount: 2, + }, + }, nil). + Times(1) + + rb.EXPECT(). + DeleteAll(gomock.Any(), (*operation.Operation)(nil), level). + Return(5, nil). + Times(1) + + rb.EXPECT(). + DeleteAll(gomock.Any(), (*ticket.TicketUpdate)(nil), level). + Return(0, nil). + Times(1) + + rb.EXPECT(). + GetMigrations(gomock.Any(), level). + Return([]migration.Migration{ + { + ContractID: 1, + Contract: contract.Contract{ + AccountID: 1, + }, + }, + }, nil). + Times(1) + + ts := time.Now().UTC() + rb.EXPECT(). + GetLastAction(gomock.Any(), gomock.Any()). + Return([]models.LastAction{ + { + AccountId: 4, + Time: ts, + }, { + AccountId: 3, + Time: ts, + }, { + AccountId: 2, + Time: ts, + }, { + AccountId: 1, + Time: ts, + }, + }, nil). + Times(1) + + rb.EXPECT(). + GetTicketUpdates(gomock.Any(), gomock.Any()). + Return([]ticket.TicketUpdate{ + { + AccountId: 4, + TicketId: 1, + Amount: decimal.RequireFromString("100"), + }, { + AccountId: 1, + TicketId: 1, + Amount: decimal.RequireFromString("-100"), + }, + }, nil). + Times(1) + + rb.EXPECT(). + TicketBalances(gomock.Any(), gomock.Any()). + Return(nil). + Times(1) + + rb.EXPECT(). + DeleteTickets(gomock.Any(), level). + Return([]int64{1}, nil). + Times(1) + + rb.EXPECT(). + DeleteTicketBalances(gomock.Any(), []int64{1}). + Return(nil). + Times(1) + + rb.EXPECT(). + UpdateAccountStats(gomock.Any(), account.Account{ + ID: 4, + LastAction: ts, + OperationsCount: 1, + }). + Return(nil). + Times(1) + + rb.EXPECT(). + UpdateAccountStats(gomock.Any(), account.Account{ + ID: 3, + LastAction: ts, + OperationsCount: 4, + }). + Return(nil). + Times(1) + + rb.EXPECT(). + UpdateAccountStats(gomock.Any(), account.Account{ + ID: 2, + LastAction: ts, + OperationsCount: 3, + }). + Return(nil). + Times(1) + + rb.EXPECT(). + UpdateAccountStats(gomock.Any(), account.Account{ + ID: 1, + LastAction: ts, + OperationsCount: 5, + MigrationsCount: 1, + EventsCount: 1, + TicketUpdatesCount: 2, + }). + Times(1) + + rb.EXPECT(). + StatesChangedAtLevel(gomock.Any(), level). + Return([]bigmapdiff.BigMapState{ + { + ID: 1, + Ptr: 10, + LastUpdateLevel: 11, + Count: 10, + LastUpdateTime: ts, + KeyHash: "key_hash", + Contract: "address_1", + Key: types.MustNewBytes("deadbeaf"), + Value: types.MustNewBytes("00112233"), + Removed: false, + }, { + ID: 2, + Ptr: 10, + LastUpdateLevel: 11, + Count: 10, + LastUpdateTime: ts, + KeyHash: "key_hash_2", + Contract: "address_1", + Key: types.MustNewBytes("deadbeaf0011"), + Value: types.MustNewBytes("001122334455"), + Removed: false, + }, + }, nil). + Times(1) + + ptr := int64(10) + rb.EXPECT(). + LastDiff(gomock.Any(), ptr, "key_hash", false). + Return(bigmapdiff.BigMapDiff{ + ID: 1, + Ptr: ptr, + KeyHash: "key_hash", + Contract: "address_1", + Key: types.MustNewBytes("deadbeaf"), + Value: types.MustNewBytes("deadbeaf"), + Level: 9, + Timestamp: ts, + ProtocolID: 2, + OperationID: 10, + }, nil). + Times(1) + + rb.EXPECT(). + LastDiff(gomock.Any(), ptr, "key_hash_2", false). + Return(bigmapdiff.BigMapDiff{}, sql.ErrNoRows). + Times(1) + + rb.EXPECT(). + DeleteBigMapState(gomock.Any(), bigmapdiff.BigMapState{ + ID: 2, + Ptr: ptr, + LastUpdateLevel: 11, + Count: 10, + LastUpdateTime: ts, + KeyHash: "key_hash_2", + Contract: "address_1", + Key: types.MustNewBytes("deadbeaf0011"), + Value: types.MustNewBytes("001122334455"), + Removed: false, + }). + Return(nil). + Times(1) + + rb.EXPECT(). + SaveBigMapState(gomock.Any(), bigmapdiff.BigMapState{ + ID: 1, + Ptr: 10, + LastUpdateLevel: 9, + Count: 10, + LastUpdateTime: ts, + KeyHash: "key_hash", + Contract: "address_1", + Key: types.MustNewBytes("deadbeaf"), + Value: types.MustNewBytes("deadbeaf"), + Removed: false, + IsRollback: true, + }). + Return(nil). + Times(1) + + rb.EXPECT(). + GlobalConstants(gomock.Any(), level). + Return([]contract.GlobalConstant{ + { + ID: 1, + Timestamp: ts, + Level: 11, + Address: "address_1", + Value: testsuite.MustHexDecode("deadbeaf"), + }, + }, nil). + Times(1) + + rb.EXPECT(). + Scripts(gomock.Any(), level). + Return([]contract.Script{}, nil). + Times(1) + + rb.EXPECT(). + DeleteScriptsConstants(gomock.Any(), []int64{}, []int64{1}). + Return(nil). + Times(1) + + rb.EXPECT(). + DeleteAll(gomock.Any(), nil, level). + Return(0, nil). + Times(8) + + rb.EXPECT(). + Protocols(gomock.Any(), level). + Return(nil). + Times(1) + + rb.EXPECT(). + UpdateStats(gomock.Any(), stats.Stats{ + ID: 1, + ContractsCount: 100, + OperationsCount: 95, + EventsCount: 9, + TransactionsCount: 66, + OriginationsCount: 9, + SrOriginationsCount: 10, + TransferTicketsCount: 10, + }). + Return(nil). + Times(1) + + rb.EXPECT(). + Commit(). + Return(nil). + Times(1) + + t.Run("Rollback", func(t *testing.T) { + state := block.Block{ + Level: 11, + } + err := NewManager(storage, blockRepo, rb, statsRepo). + Rollback( + context.Background(), + types.Mainnet, + state, + 10, + ) + require.NoError(t, err) + }) +} diff --git a/internal/rollback/scripts.go b/internal/rollback/scripts.go new file mode 100644 index 000000000..34c1e9f8f --- /dev/null +++ b/internal/rollback/scripts.go @@ -0,0 +1,46 @@ +package rollback + +import ( + "context" + + "github.com/baking-bad/bcdhub/internal/models/contract" + "github.com/rs/zerolog/log" +) + +func (rm Manager) rollbackScripts(ctx context.Context, level int64) error { + log.Info().Msg("rollback scripts and global constants...") + constants, err := rm.rollback.GlobalConstants(ctx, level) + if err != nil { + return err + } + scripts, err := rm.rollback.Scripts(ctx, level) + if err != nil { + return err + } + + constantIds := make([]int64, len(constants)) + for i := range constants { + constantIds[i] = constants[i].ID + } + scriptIds := make([]int64, len(scripts)) + for i := range scripts { + scriptIds[i] = scripts[i].ID + } + + if err := rm.rollback.DeleteScriptsConstants(ctx, scriptIds, constantIds); err != nil { + return err + } + + if len(scripts) > 0 { + if _, err := rm.rollback.DeleteAll(ctx, (*contract.Script)(nil), level); err != nil { + return err + } + } + if len(constants) > 0 { + if _, err := rm.rollback.DeleteAll(ctx, (*contract.GlobalConstant)(nil), level); err != nil { + return err + } + } + + return nil +} diff --git a/internal/rollback/tickets.go b/internal/rollback/tickets.go new file mode 100644 index 000000000..e0cdcb409 --- /dev/null +++ b/internal/rollback/tickets.go @@ -0,0 +1,60 @@ +package rollback + +import ( + "context" + "fmt" + + "github.com/baking-bad/bcdhub/internal/models/ticket" +) + +func (rm Manager) rollbackTicketUpdates(ctx context.Context, level int64) error { + updates, err := rm.rollback.GetTicketUpdates(ctx, level) + if err != nil { + return err + } + + if len(updates) == 0 { + return nil + } + + balances := make(map[string]*ticket.Balance) + for i := range updates { + key := fmt.Sprintf("%d_%d", updates[i].AccountId, updates[i].TicketId) + if b, ok := balances[key]; ok { + b.Amount = b.Amount.Add(updates[i].Amount) + } else { + balances[key] = &ticket.Balance{ + AccountId: updates[i].AccountId, + TicketId: updates[i].TicketId, + Amount: updates[i].Amount.Copy(), + } + } + } + + arr := make([]*ticket.Balance, 0, len(balances)) + for _, balance := range balances { + arr = append(arr, balance) + } + + return rm.rollback.TicketBalances(ctx, arr...) +} + +func (rm Manager) rollbackTickets(ctx context.Context, level int64) error { + if err := rm.rollbackTicketUpdates(ctx, level); err != nil { + return err + } + + if _, err := rm.rollback.DeleteAll(ctx, (*ticket.TicketUpdate)(nil), level); err != nil { + return err + } + + ticketsIds, err := rm.rollback.DeleteTickets(ctx, level) + if err != nil { + return err + } + if len(ticketsIds) == 0 { + return nil + } + + return rm.rollback.DeleteTicketBalances(ctx, ticketsIds) +} diff --git a/internal/services/mempool/mempool.go b/internal/services/mempool/mempool.go index 1cc23b14a..a98bf32f5 100644 --- a/internal/services/mempool/mempool.go +++ b/internal/services/mempool/mempool.go @@ -27,7 +27,7 @@ func NewMempool(url string) *Mempool { } // Get - -func (m *Mempool) Get(address string) (result PendingOperations, err error) { +func (m *Mempool) Get(ctx context.Context, address string) (result PendingOperations, err error) { req := graphql.NewRequest(` query ($address: String!) { originations(where: {source: {_eq: $address}, _not: {status: {_eq: "in_chain"}}}) { @@ -83,12 +83,12 @@ func (m *Mempool) Get(address string) (result PendingOperations, err error) { req.Var("address", address) req.Header.Set("Cache-Control", "no-cache") - err = m.client.Run(context.Background(), req, &result) + err = m.client.Run(ctx, req, &result) return } // GetByHash - -func (m *Mempool) GetByHash(hash string) (result PendingOperations, err error) { +func (m *Mempool) GetByHash(ctx context.Context, hash string) (result PendingOperations, err error) { req := graphql.NewRequest(` query ($hash: String!) { originations(where: {hash: {_eq: $hash}, _not: {status: {_eq: "in_chain"}}}) { @@ -142,6 +142,6 @@ func (m *Mempool) GetByHash(hash string) (result PendingOperations, err error) { req.Var("hash", hash) req.Header.Set("Cache-Control", "no-cache") - err = m.client.Run(context.Background(), req, &result) + err = m.client.Run(ctx, req, &result) return } diff --git a/internal/testsuite/functions.go b/internal/testsuite/functions.go index 70c5a6e4c..7166e74f7 100644 --- a/internal/testsuite/functions.go +++ b/internal/testsuite/functions.go @@ -1,5 +1,15 @@ package testsuite +import "encoding/hex" + func Ptr[T any](val T) *T { return &val } + +func MustHexDecode(s string) []byte { + data, err := hex.DecodeString(s) + if err != nil { + panic(err) + } + return data +} diff --git a/scripts/bcdctl/main.go b/scripts/bcdctl/main.go index ab494b745..4c004e512 100644 --- a/scripts/bcdctl/main.go +++ b/scripts/bcdctl/main.go @@ -6,8 +6,8 @@ import ( "strings" "github.com/baking-bad/bcdhub/internal/config" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/jessevdk/go-flags" + "github.com/rs/zerolog/log" ) var ctxs config.Contexts @@ -15,12 +15,12 @@ var ctxs config.Contexts func main() { cfg, err := config.LoadDefaultConfig() if err != nil { - logger.Err(err) + log.Err(err).Msg("load config") return } ctxs = config.NewContexts(cfg, cfg.Scripts.Networks, - config.WithStorage(cfg.Storage, "bcdctl", 0, cfg.Scripts.Connections.Open, cfg.Scripts.Connections.Idle, false), + config.WithStorage(cfg.Storage, "bcdctl", 0), config.WithConfigCopy(cfg), config.WithRPC(cfg.RPC), ) @@ -32,7 +32,7 @@ func main() { "Rollback state", "Rollback network state to certain level", &rollbackCmd); err != nil { - logger.Err(err) + log.Err(err).Msg("add rollback command") return } diff --git a/scripts/bcdctl/rollback.go b/scripts/bcdctl/rollback.go index 845332b41..03e7f399f 100644 --- a/scripts/bcdctl/rollback.go +++ b/scripts/bcdctl/rollback.go @@ -3,14 +3,15 @@ package main import ( "context" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models/types" + "github.com/baking-bad/bcdhub/internal/postgres" "github.com/baking-bad/bcdhub/internal/rollback" + "github.com/rs/zerolog/log" ) type rollbackCommand struct { - Level int64 `short:"l" long:"level" description:"Level to rollback"` - Network string `short:"n" long:"network" description:"Network"` + Level int64 `description:"Level to rollback" long:"level" short:"l"` + Network string `description:"Network" long:"network" short:"n"` } var rollbackCmd rollbackCommand @@ -23,22 +24,30 @@ func (x *rollbackCommand) Execute(_ []string) error { panic(err) } - state, err := ctx.Blocks.Last() + state, err := ctx.Blocks.Last(context.Background()) if err != nil { panic(err) } - logger.Warning().Msgf("Do you want to rollback '%s' from %d to %d? (yes - continue. no - cancel)", network.String(), state.Level, x.Level) + log.Warn().Msgf("Do you want to rollback '%s' from %d to %d? (yes - continue. no - cancel)", network.String(), state.Level, x.Level) if !yes() { - logger.Info().Msg("Cancelled") + log.Info().Msg("Cancelled") return nil } - manager := rollback.NewManager(ctx.RPC, ctx.Storage, ctx.Blocks, ctx.BigMapDiffs) - if err = manager.Rollback(context.Background(), ctx.StorageDB.DB, network, state, x.Level); err != nil { + if err := ctx.Storage.InitDatabase(context.Background()); err != nil { return err } - logger.Info().Msg("Done") + + saver, err := postgres.NewRollback(ctx.StorageDB.DB) + if err != nil { + return err + } + manager := rollback.NewManager(ctx.Storage, ctx.Blocks, saver, ctx.Stats) + if err = manager.Rollback(context.Background(), network, state, x.Level); err != nil { + return err + } + log.Info().Msg("Done") return nil } diff --git a/scripts/migration/main.go b/scripts/migration/main.go index 4301bc641..e87a7cf21 100644 --- a/scripts/migration/main.go +++ b/scripts/migration/main.go @@ -8,9 +8,9 @@ import ( "time" "github.com/baking-bad/bcdhub/internal/config" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/scripts/migration/migrations" "github.com/pkg/errors" + "github.com/rs/zerolog/log" ) var migrationsList = []migrations.Migration{} @@ -18,13 +18,13 @@ var migrationsList = []migrations.Migration{} func main() { migration, err := chooseMigration() if err != nil { - logger.Err(err) + log.Err(err).Msg("choose migration") return } cfg, err := config.LoadDefaultConfig() if err != nil { - logger.Err(err) + log.Err(err).Msg("load config") return } @@ -32,7 +32,7 @@ func main() { ctxs := config.NewContexts( cfg, cfg.Scripts.Networks, - config.WithStorage(cfg.Storage, "migrations", 0, cfg.Scripts.Connections.Open, cfg.Scripts.Connections.Idle, false), + config.WithStorage(cfg.Storage, "migrations", 0), config.WithRPC(cfg.RPC), config.WithConfigCopy(cfg), config.WithLoadErrorDescriptions(), @@ -40,14 +40,14 @@ func main() { defer ctxs.Close() for _, ctx := range ctxs { - logger.Info().Msgf("Starting %v migration for %s...", migration.Key(), ctx.Network.String()) + log.Info().Msgf("Starting %v migration for %s...", migration.Key(), ctx.Network.String()) if err := migration.Do(ctx); err != nil { - logger.Err(err) + log.Err(err).Msg("migration execution") return } } - logger.Info().Msgf("%s migration done. Spent: %v", migration.Key(), time.Since(start)) + log.Info().Msgf("%s migration done. Spent: %v", migration.Key(), time.Since(start)) } func chooseMigration() (migrations.Migration, error) { diff --git a/scripts/newman/tests.json b/scripts/newman/tests.json index 2f4bd081b..1374c4b1c 100644 --- a/scripts/newman/tests.json +++ b/scripts/newman/tests.json @@ -1101,8 +1101,6 @@ "", " pm.expect(response.network).to.be.eql('mainnet');", " pm.expect(response.address).to.be.eql('KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn');", - " pm.expect(response.alias).to.be.eql('tzBTC');", - " pm.expect(response.slug).to.be.eql('tzbtc');", "", " pm.expect(response).to.have.property('level');", " pm.expect(response).to.have.property('timestamp');", @@ -1619,7 +1617,6 @@ " const account = pm.response.json();", "", " pm.expect(account.address).to.eql('KT1PWx2mnDueood7fEmfbBDKx1D9BAnnXitn');", - " pm.expect(account.alias).to.eql('tzBTC');", "", " pm.expect(account).to.have.property('balance');", " pm.expect(account).to.have.property('tx_count');", @@ -1660,7 +1657,6 @@ " const account = pm.response.json();", "", " pm.expect(account.address).to.eql('KT1LN4LPSqTMS7Sd2CJw4bbDGRkMv2t68Fy9');", - " pm.expect(account.alias).to.eql('USDtz');", "", " pm.expect(account).to.have.property('balance');", " pm.expect(account).to.have.property('tx_count');", diff --git a/scripts/nginx/main.go b/scripts/nginx/main.go index bac3ed186..5835387d9 100644 --- a/scripts/nginx/main.go +++ b/scripts/nginx/main.go @@ -5,20 +5,20 @@ import ( "os" "github.com/baking-bad/bcdhub/internal/config" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/internal/models/types" + "github.com/rs/zerolog/log" ) func main() { cfg, err := config.LoadDefaultConfig() if err != nil { - logger.Err(err) + log.Err(err).Msg("load config") return } ctx := config.NewContext( types.Mainnet, - config.WithStorage(cfg.Storage, "nginx", 0, cfg.Scripts.Connections.Open, cfg.Scripts.Connections.Idle, false), + config.WithStorage(cfg.Storage, "nginx", 0), config.WithConfigCopy(cfg), ) defer ctx.Close() @@ -28,19 +28,19 @@ func main() { env := os.Getenv("BCD_ENV") if env == "" { - logger.Err(fmt.Errorf("BCD_ENV env var is empty")) + log.Error().Msg("BCD_ENV env var is empty") return } nginxConfigFilename := fmt.Sprintf("%s/default.%s.conf", outputDir, env) if err := makeNginxConfig(nginxConfigFilename, ctx.Config.BaseURL); err != nil { - logger.Err(err) + log.Err(err).Msg("make nginx config") return } sitemapFilename := fmt.Sprintf("%s/sitemap.%s.xml", outputDir, env) if err := makeSitemap(sitemapFilename, ctx.Config); err != nil { - logger.Err(err) + log.Err(err).Msg("make sitemap") return } } diff --git a/scripts/nginx/nginx.go b/scripts/nginx/nginx.go index f293723ce..7f15faf31 100644 --- a/scripts/nginx/nginx.go +++ b/scripts/nginx/nginx.go @@ -5,7 +5,7 @@ import ( "os" "strings" - "github.com/baking-bad/bcdhub/internal/logger" + "github.com/rs/zerolog/log" ) const defaultConfTemplate = `server { @@ -40,7 +40,7 @@ func makeNginxConfig(filepath, baseURL string) error { return err } - logger.Info().Msgf("Nginx default config created in %s", filepath) + log.Info().Msgf("Nginx default config created in %s", filepath) return nil } diff --git a/scripts/nginx/sitemap.go b/scripts/nginx/sitemap.go index 5f57f599a..3bbbc6c87 100644 --- a/scripts/nginx/sitemap.go +++ b/scripts/nginx/sitemap.go @@ -4,8 +4,8 @@ import ( "fmt" "github.com/baking-bad/bcdhub/internal/config" - "github.com/baking-bad/bcdhub/internal/logger" "github.com/baking-bad/bcdhub/scripts/nginx/pkg/sitemap" + "github.com/rs/zerolog/log" ) func makeSitemap(filepath string, cfg config.Config) error { @@ -23,7 +23,7 @@ func makeSitemap(filepath string, cfg config.Config) error { return err } - logger.Info().Msgf("Sitemap created in %s", filepath) + log.Info().Msgf("Sitemap created in %s", filepath) return nil }