diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e8ad79cfd..23fa25af0 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -28,7 +28,7 @@ jobs: - name: Set up Go environment uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23' - name: Tidy go module run: | go mod tidy @@ -81,7 +81,7 @@ jobs: - uses: benjlevesque/short-sha@v3.0 # sets env.SHA to the first 7 chars of github.sha - uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23' - run: mkdir -p "$PWD/gocoverage-unit/" - name: Run Go test -race id: go-test-race @@ -151,7 +151,7 @@ jobs: - uses: actions/download-artifact@v4 - uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23' cache: false - name: Convert gocoverage format run: | @@ -190,7 +190,7 @@ jobs: name: gocoverage-all-textfmt@${{ env.SHA }} - uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23' cache: false - name: Send coverage to coveralls.io (unit) if: ${{ always() }} diff --git a/.github/workflows/scan_vulns_deps.yml b/.github/workflows/scan_vulns_deps.yml deleted file mode 100644 index 3145cc711..000000000 --- a/.github/workflows/scan_vulns_deps.yml +++ /dev/null @@ -1,250 +0,0 @@ -name: scan-vulns-deps - -on: - workflow_dispatch: - push: - branches: - - '**' - -jobs: - - build-and-deploy: - runs-on: ubuntu-latest - outputs: - BRANCH_NAME: ${{ steps.myvars.outputs.BRANCH_NAME }} - GIT_HASH_SHORT: ${{ steps.myvars.outputs.GIT_HASH_SHORT }} - DATE_IN_SECS: ${{ steps.myvars.outputs.DATE_IN_SECS }} - CONTAINER_TAG: ${{ steps.myvars.outputs.CONTAINER_TAG }} - SHORT_ENV_OUT: ${{ steps.myvars.outputs.SHORT_ENV_OUT }} - CONTAINER_NAME: ${{ steps.myvars.outputs.CONTAINER_NAME }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set myvars - id: myvars - run: | - branchname=$(echo ${GITHUB_REF#refs/heads/} | tr '/' '-' ) - dateinsecs=$(date +%s) - githashshort=$(git rev-parse --short HEAD) - echo "BRANCH_NAME=$branchname" >> $GITHUB_OUTPUT - echo "GIT_HASH_SHORT=$githashshort" >> $GITHUB_OUTPUT - echo "DATE_IN_SECS=$dateinsecs" >> $GITHUB_OUTPUT - if [ "$branchname" = "develop" ]; then - echo "CURRENT_ENVIRONMENT=development" >> $GITHUB_OUTPUT - echo "SHORT_ENV_OUT=DEV" >> $GITHUB_OUTPUT - containertag="commit-race-$githashshort" - elif [ "$branchname" = "main" ]; then - echo "CURRENT_ENVIRONMENT=production" >> $GITHUB_OUTPUT - echo "SHORT_ENV_OUT=PROD" >> $GITHUB_OUTPUT - containertag="commit-race-$githashshort" - else - echo "BRANCH_NAME=test" >> $GITHUB_OUTPUT - echo "CURRENT_ENVIRONMENT=testing" >> $GITHUB_OUTPUT - echo "SHORT_ENV_OUT=TEST" >> $GITHUB_OUTPUT - containertag="commit-$githashshort" - fi - echo "CONTAINER_NAME=vocdoni-node" >> $GITHUB_OUTPUT - echo "CONTAINER_TAG=$containertag" >> $GITHUB_OUTPUT - - - name: Set up Go environment - uses: actions/setup-go@v5 - with: - go-version: '1.22' - - - name: Setup Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Push Docker image to ghcr.io - uses: docker/build-push-action@v5 - with: - context: . - #push: true - push: false - tags: | - ghcr.io/vocdoni/go-dvote:latest, - ghcr.io/vocdoni/go-dvote:${{ steps.myvars.outputs.BRANCH_NAME }}, - ghcr.io/vocdoni/go-dvote:commit-${{ steps.myvars.outputs.GIT_HASH_SHORT }}, - ghcr.io/vocdoni/go-dvote:${{ steps.myvars.outputs.BRANCH_NAME }}-${{ steps.myvars.outputs.DATE_IN_SECS }} - cache-from: type=gha - cache-to: type=gha,mode=max - #outputs: type=tar,dest=${{ steps.myvars.outputs.CONTAINER_NAME }}-${{ steps.myvars.outputs.CONTAINER_TAG }}-tar - outputs: type=docker,dest=${{ steps.myvars.outputs.CONTAINER_NAME }}-${{ steps.myvars.outputs.CONTAINER_TAG }}-oci-tar - - - name: Push Docker image to ghcr.io (race enabled) - uses: docker/build-push-action@v5 - if: github.ref == 'refs/heads/dev' || github.ref == 'refs/heads/main' - with: - context: . - #push: true - push: false - build-args: | - BUILDARGS=-race - tags: | - ghcr.io/vocdoni/go-dvote:latest-race, - ghcr.io/vocdoni/go-dvote:${{ steps.myvars.outputs.BRANCH_NAME }}-race, - ghcr.io/vocdoni/go-dvote:commit-${{ steps.myvars.outputs.GIT_HASH_SHORT }}, - ghcr.io/vocdoni/go-dvote:${{ steps.myvars.outputs.BRANCH_NAME }}-race-${{ steps.myvars.outputs.DATE_IN_SECS }} - cache-from: type=gha - cache-to: type=gha,mode=max - #outputs: type=tar,dest=${{ steps.myvars.outputs.CONTAINER_NAME }}-${{ steps.myvars.outputs.CONTAINER_TAG }}-tar - outputs: type=docker,dest=${{ steps.myvars.outputs.CONTAINER_NAME }}-${{ steps.myvars.outputs.CONTAINER_TAG }}-oci-tar - - - name: Upload Container Img Tarball as Artifact - uses: actions/upload-artifact@v4 - if: success() || failure() - with: - name: ${{ steps.myvars.outputs.CONTAINER_NAME }}-${{ steps.myvars.outputs.CONTAINER_TAG }}-docker-img - path: ${{ steps.myvars.outputs.CONTAINER_NAME }}-${{ steps.myvars.outputs.CONTAINER_TAG }}-oci-tar - - - scan-vulns-repo: - name: Scan Vulns in Repo - runs-on: ubuntu-latest - needs: [build-and-deploy] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Go environment - uses: actions/setup-go@v5 - with: - go-version: '1.22' - - - name: Scan in Repo (html) - uses: aquasecurity/trivy-action@master - if: success() || failure() - with: - scan-type: fs - scanners: vuln,secret,config - scan-ref: . - format: template - template: '@/contrib/html.tpl' - output: trivy-results-repo-${{ needs.build-and-deploy.outputs.GIT_HASH_SHORT }}.html - env: - TRIVY_USERNAME: ${{ github.repository_owner }} - TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} - - - name: Scan in Repo (sarif) - uses: aquasecurity/trivy-action@master - if: success() || failure() - with: - scan-type: fs - scanners: vuln,secret,config - scan-ref: . - format: sarif - output: trivy-results-repo-${{ needs.build-and-deploy.outputs.GIT_HASH_SHORT }}.sarif - env: - TRIVY_USERNAME: ${{ github.repository_owner }} - TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} - - - name: Publish Repo Scan Results as Artifact - uses: actions/upload-artifact@v4 - if: success() || failure() - with: - name: trivy-results-repo-${{ needs.build-and-deploy.outputs.DATE_IN_SECS }} - path: trivy-results-repo-${{ needs.build-and-deploy.outputs.GIT_HASH_SHORT }}.* - - - name: Load Repo Scan Results (sarif) to Github - uses: github/codeql-action/upload-sarif@v2 - if: always() - #if: false ## false = bypass - with: - sarif_file: trivy-results-repo-${{ needs.build-and-deploy.outputs.GIT_HASH_SHORT }}.sarif - category: vulns-in-repo - - - scan-vulns-docker: - name: Scan Vulns in Docker - runs-on: ubuntu-latest - needs: [build-and-deploy] - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Download Container Img Tarball as Artifact - uses: actions/download-artifact@v4 - id: container_img_tar - with: - name: ${{ needs.build-and-deploy.outputs.CONTAINER_NAME }}-${{ needs.build-and-deploy.outputs.CONTAINER_TAG }}-docker-img - path: _tmp/ - - - name: Check Container Image Tarball - run: | - cd _tmp/ - mkdir _tar/ - ls -la - file ${{ needs.build-and-deploy.outputs.CONTAINER_NAME }}-${{ needs.build-and-deploy.outputs.CONTAINER_TAG }}-oci-tar - ## we remove 'z' flag because file is not compressed (gz), only archived (tar) - tar -xvf ${{ needs.build-and-deploy.outputs.CONTAINER_NAME }}-${{ needs.build-and-deploy.outputs.CONTAINER_TAG }}-oci-tar -C _tar/ - ls -la _tar/ - - - name: Vuln scan in Docker (table) - uses: aquasecurity/trivy-action@master - if: always() - with: - scan-type: image - scanners: vuln,secret,config - ## it can be the dir with content of untar file or it can be the tar file - input: _tmp/_tar/ - ##input: _tmp/${{ needs.build-and-deploy.outputs.CONTAINER_NAME }}-${{ needs.build-and-deploy.outputs.CONTAINER_TAG }}-oci-tar - format: table - env: - TRIVY_USERNAME: ${{ github.repository_owner }} - TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} - - - name: Vuln scan in Docker (html) - uses: aquasecurity/trivy-action@master - if: always() - with: - scan-type: image - scanners: vuln,secret,config - ## it can be the dir with content of untar file or it can be the tar file - ## input: _tmp/_tar/ - input: _tmp/${{ needs.build-and-deploy.outputs.CONTAINER_NAME }}-${{ needs.build-and-deploy.outputs.CONTAINER_TAG }}-oci-tar - format: template - template: '@/contrib/html.tpl' - output: trivy-results-docker-${{ needs.build-and-deploy.outputs.GIT_HASH_SHORT }}.html - env: - TRIVY_USERNAME: ${{ github.repository_owner }} - TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} - - - name: Vuln scan in Docker (sarif) - uses: aquasecurity/trivy-action@master - if: always() - with: - scan-type: image - scanners: vuln,secret,config - ## it can be the dir with content of untar file or it can be the tar file - ## input: _tmp/_tar/ - input: _tmp/${{ needs.build-and-deploy.outputs.CONTAINER_NAME }}-${{ needs.build-and-deploy.outputs.CONTAINER_TAG }}-oci-tar - format: sarif - output: trivy-results-docker-${{ needs.build-and-deploy.outputs.GIT_HASH_SHORT }}.sarif - env: - TRIVY_USERNAME: ${{ github.repository_owner }} - TRIVY_PASSWORD: ${{ secrets.GITHUB_TOKEN }} - - - name: Publish Docker Scan Results as Artifact - uses: actions/upload-artifact@v4 - if: success() || failure() - with: - name: trivy-results-docker-${{ needs.build-and-deploy.outputs.DATE_IN_SECS }} - path: trivy-results-docker-${{ needs.build-and-deploy.outputs.GIT_HASH_SHORT }}.* - - - name: Load Docker Scan Results (sarif) to Github - uses: github/codeql-action/upload-sarif@v2 - if: always() - #if: false ## false = bypass - with: - sarif_file: trivy-results-docker-${{ needs.build-and-deploy.outputs.GIT_HASH_SHORT }}.sarif - category: vulns-in-docker diff --git a/.github/workflows/swagger.yml b/.github/workflows/swagger.yml index cfc62f81f..54bc119dd 100644 --- a/.github/workflows/swagger.yml +++ b/.github/workflows/swagger.yml @@ -15,9 +15,16 @@ jobs: steps: - name: Checkout code uses: actions/checkout@v4 + - uses: benjlevesque/short-sha@v3.0 # sets env.SHA to the first 7 chars of github.sha + - name: Checkout developer-portal repo + uses: actions/checkout@v4 + with: + repository: vocdoni/developer-portal + ref: main + path: developer-portal - uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23' cache: false - name: Install swag run: | @@ -33,37 +40,46 @@ jobs: with: cmd: | yq '.components.schemas."api.GenericTransactionWithInfo".properties.tx = load("api/docs/models/transactions.yaml").target' \ - api/docs/oas3.yaml > api/docs/vocdoni-api.yaml + api/docs/oas3.yaml > developer-portal/swaggers/vocdoni-api.yaml + - name: Publish Artifact uses: actions/upload-artifact@v4 with: name: vocdoni-api.yaml - path: api/docs/vocdoni-api.yaml + path: developer-portal/swaggers/vocdoni-api.yaml - developer-portal-pr: - name: Open PR to developer-portal repo - runs-on: ubuntu-latest - if: ${{ github.event_name != 'pull_request' }} - needs: api-swagger - steps: - - name: Checkout developer-portal repo - uses: actions/checkout@v4 + - name: Check if there is a difference + uses: mathiasvr/command-output@v2.0.0 + id: diff with: - repository: vocdoni/developer-portal - ref: main - - name: Remove old yaml - run: rm swaggers/vocdoni-api.yaml - - name: Pull new yaml - uses: actions/download-artifact@v4 + run: git -C developer-portal diff --no-color swaggers/vocdoni-api.yaml + + - name: Mark previous comment as outdated if no diff + if: ${{ github.event_name == 'pull_request' && steps.diff.outputs.stdout == '' }} + uses: marocchino/sticky-pull-request-comment@v2 with: - name: vocdoni-api.yaml - path: swaggers + header: diff + hide: true + hide_classify: "OUTDATED" + + - name: Post comment with diff in original PR + if: ${{ github.event_name == 'pull_request' && steps.diff.outputs.stdout }} + uses: marocchino/sticky-pull-request-comment@v2 + with: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + header: diff + message: | + This PR introduces the following changes in the developer-portal documentation: + ```diff + ${{ steps.diff.outputs.stdout }} + ``` - - uses: benjlevesque/short-sha@v3.0 # sets env.SHA to the first 7 chars of github.sha - name: Create PR to developer-portal repo id: cpr uses: peter-evans/create-pull-request@v6 + if: ${{ github.event_name == 'push' }} with: + path: developer-portal token: ${{ secrets.VOCDONIBOT_PAT }} commit-message: "Update vocdoni-api docs by commit ${{ env.SHA }}" committer: "Arabot-1 " diff --git a/Dockerfile b/Dockerfile index fbd7f2dc2..d96e5693c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ # syntax=docker/dockerfile:experimental -FROM golang:1.22 AS builder +FROM golang:1.23 AS builder ARG BUILDARGS diff --git a/README.md b/README.md index 365115464..0ee58438c 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,7 @@ To run a Vocdoni-node as a gateway, it's recommended to have at least 4 GiB of R #### Compile and run -Compile from source in a golang environment (Go>1.22 required): +Compile from source in a golang environment (Go>1.23 required): ```bash git clone https://github.com/vocdoni/vocdoni-node.git -b release-lts-1 diff --git a/api/api.go b/api/api.go index 6dcacc5f6..5fa84931c 100644 --- a/api/api.go +++ b/api/api.go @@ -71,9 +71,14 @@ const ( ParamWithResults = "withResults" ParamFinalResults = "finalResults" ParamManuallyEnded = "manuallyEnded" + ParamChainId = "chainId" + ParamHash = "hash" + ParamProposerAddress = "proposerAddress" ParamHeight = "height" ParamReference = "reference" ParamType = "type" + ParamSubtype = "subtype" + ParamSigner = "signer" ParamAccountIdFrom = "accountIdFrom" ParamAccountIdTo = "accountIdTo" ParamStartDateAfter = "startDateAfter" diff --git a/api/api_types.go b/api/api_types.go index d948b7207..26b13508e 100644 --- a/api/api_types.go +++ b/api/api_types.go @@ -50,8 +50,19 @@ type AccountParams struct { // TransactionParams allows the client to filter transactions type TransactionParams struct { PaginationParams - Height uint64 `json:"height,omitempty"` - Type string `json:"type,omitempty"` + Hash string `json:"hash,omitempty"` + Height uint64 `json:"height,omitempty"` + Type string `json:"type,omitempty"` + Subtype string `json:"subtype,omitempty"` + Signer string `json:"signer,omitempty"` +} + +// BlockParams allows the client to filter blocks +type BlockParams struct { + PaginationParams + ChainID string `json:"chainId,omitempty"` + Hash string `json:"hash,omitempty"` + ProposerAddress string `json:"proposerAddress,omitempty"` } // FeesParams allows the client to filter fees @@ -267,8 +278,8 @@ type TransactionReference struct { // TransactionsList is used to return a paginated list to the client type TransactionsList struct { - Transactions []*indexertypes.Transaction `json:"transactions"` - Pagination *Pagination `json:"pagination"` + Transactions []*indexertypes.TransactionMetadata `json:"transactions"` + Pagination *Pagination `json:"pagination"` } // FeesList is used to return a paginated list to the client @@ -284,9 +295,9 @@ type TransfersList struct { } type GenericTransactionWithInfo struct { - TxContent json.RawMessage `json:"tx"` - TxInfo indexertypes.Transaction `json:"txInfo"` - Signature types.HexBytes `json:"signature"` + TxContent json.RawMessage `json:"tx"` + TxInfo *indexertypes.Transaction `json:"txInfo"` + Signature types.HexBytes `json:"signature"` } type ChainInfo struct { @@ -436,6 +447,13 @@ func CensusTypeToOrigin(ctype CensusTypeDescription) (models.CensusOrigin, []byt } type Block struct { - comettypes.Block `json:",inline"` - Hash types.HexBytes `json:"hash" ` + comettypes.Header `json:"header"` + Hash types.HexBytes `json:"hash" ` + TxCount int64 `json:"txCount"` +} + +// BlockList is used to return a paginated list to the client +type BlockList struct { + Blocks []*indexertypes.Block `json:"blocks"` + Pagination *Pagination `json:"pagination"` } diff --git a/api/censuses.go b/api/censuses.go index 31ec08c7c..9447d1654 100644 --- a/api/censuses.go +++ b/api/censuses.go @@ -36,7 +36,7 @@ const ( MaxCensusAddBatchSize = 8192 censusIDsize = 32 - censusRetrieveTimeout = 5 * time.Minute + censusRetrieveTimeout = 10 * time.Minute ) func (a *API) enableCensusHandlers() error { @@ -170,6 +170,14 @@ func (a *API) enableCensusHandlers() error { ); err != nil { return err } + if err := a.Endpoint.RegisterMethod( + "/censuses/export/ipfs/list", + "GET", + apirest.MethodAccessTypeAdmin, + a.censusExportIPFSListDBHandler, + ); err != nil { + return err + } if err := a.Endpoint.RegisterMethod( "/censuses/export", "GET", @@ -203,6 +211,9 @@ func (a *API) enableCensusHandlers() error { return err } + // Initialize the map to store the status of the async export to ipfs + censusIPFSExports = make(map[string]time.Time) + return nil } @@ -972,6 +983,9 @@ func (a *API) censusListHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) return ctx.Send(data, apirest.HTTPstatusOK) } +// censusIPFSExports is a map of ipfs uri to the time when the export was requested +var censusIPFSExports = map[string]time.Time{} + // censusExportDBHandler // // @Summary Export census database @@ -986,27 +1000,58 @@ func (a *API) censusListHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) func (a *API) censusExportDBHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error { isIPFSExport := strings.HasSuffix(ctx.Request.URL.Path, "ipfs") buf := bytes.Buffer{} - if err := a.censusdb.ExportCensusDB(&buf); err != nil { - return err - } var data []byte if isIPFSExport { - uri, err := a.storage.PublishReader(ctx.Request.Context(), &buf) - if err != nil { - return err - } + go func() { + log.Infow("exporting census database to ipfs async") + startTime := time.Now() + if err := a.censusdb.ExportCensusDB(&buf); err != nil { + log.Errorw(err, "could not export census database") + return + } + log.Infow("census database exported", "duration (s)", time.Since(startTime).Seconds()) + startTime = time.Now() + uri, err := a.storage.PublishReader(context.Background(), &buf) + if err != nil { + log.Errorw(err, "could not publish census database to ipfs") + return + } + log.Infow("census database published to ipfs", "uri", uri, "duration (s)", time.Since(startTime).Seconds()) + censusIPFSExports[uri] = time.Now() + }() + var err error data, err = json.Marshal(map[string]string{ - "uri": uri, + "message": "scheduled, check /censuses/export/ipfs/list", }) if err != nil { - return err + log.Errorw(err, "could not marshal response") } } else { + if err := a.censusdb.ExportCensusDB(&buf); err != nil { + return err + } data = buf.Bytes() } return ctx.Send(data, apirest.HTTPstatusOK) } +// censusExportIPFSListDBHandler +// +// @Summary List export census database to IPFS +// @Description List the IPFS URIs of the census database exports +// @Tags Censuses +// @Accept json +// @Produce json +// @Success 200 {object} object{valid=bool} +// @Router /censuses/export/ipfs/list [get] +func (a *API) censusExportIPFSListDBHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error { + data, err := json.Marshal(censusIPFSExports) + if err != nil { + return err + } + return ctx.Send(data, apirest.HTTPstatusOK) +} + // censusImportHandler // // @Summary Import census database diff --git a/api/chain.go b/api/chain.go index 13fd80127..931b4bf21 100644 --- a/api/chain.go +++ b/api/chain.go @@ -13,9 +13,7 @@ import ( "go.vocdoni.io/dvote/crypto/zk/circuit" "go.vocdoni.io/dvote/httprouter" "go.vocdoni.io/dvote/httprouter/apirest" - "go.vocdoni.io/dvote/types" "go.vocdoni.io/dvote/util" - "go.vocdoni.io/dvote/vochain" "go.vocdoni.io/dvote/vochain/genesis" "go.vocdoni.io/dvote/vochain/indexer" "go.vocdoni.io/dvote/vochain/state" @@ -106,14 +104,6 @@ func (a *API) enableChainHandlers() error { ); err != nil { return err } - if err := a.Endpoint.RegisterMethod( - "/chain/transactions/reference/index/{index}", - "GET", - apirest.MethodAccessTypePublic, - a.chainTxRefByIndexHandler, - ); err != nil { - return err - } if err := a.Endpoint.RegisterMethod( "/chain/blocks/{height}/transactions/page/{page}", "GET", @@ -126,7 +116,7 @@ func (a *API) enableChainHandlers() error { "/chain/transactions/{height}/{index}", "GET", apirest.MethodAccessTypePublic, - a.chainTxHandler, + a.chainTxByHeightAndIndexHandler, ); err != nil { return err } @@ -146,6 +136,14 @@ func (a *API) enableChainHandlers() error { ); err != nil { return err } + if err := a.Endpoint.RegisterMethod( + "/chain/transactions/{hash}", + "GET", + apirest.MethodAccessTypePublic, + a.chainTxByHashHandler, + ); err != nil { + return err + } if err := a.Endpoint.RegisterMethod( "/chain/transactions/page/{page}", "GET", @@ -166,7 +164,7 @@ func (a *API) enableChainHandlers() error { "/chain/blocks/{height}", "GET", apirest.MethodAccessTypePublic, - a.chainBlockHandler, + a.chainBlockByHeightHandler, ); err != nil { return err } @@ -178,6 +176,14 @@ func (a *API) enableChainHandlers() error { ); err != nil { return err } + if err := a.Endpoint.RegisterMethod( + "/chain/blocks", + "GET", + apirest.MethodAccessTypePublic, + a.chainBlockListHandler, + ); err != nil { + return err + } if err := a.Endpoint.RegisterMethod( "/chain/organizations/filter/page/{page}", "POST", @@ -641,11 +647,11 @@ func (a *API) chainTxCostHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext // @Success 204 "See [errors](vocdoni-api#errors) section" // @Router /chain/transactions/reference/{hash} [get] func (a *API) chainTxRefByHashHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error { - hash, err := hex.DecodeString(util.TrimHex(ctx.URLParam("hash"))) + hash, err := hex.DecodeString(util.TrimHex(ctx.URLParam(ParamHash))) if err != nil { return err } - ref, err := a.indexer.GetTxHashReference(hash) + ref, err := a.indexer.GetTxMetadataByHash(hash) if err != nil { if errors.Is(err, indexer.ErrTransactionNotFound) { return ErrTransactionNotFound @@ -660,10 +666,12 @@ func (a *API) chainTxRefByHashHandler(_ *apirest.APIdata, ctx *httprouter.HTTPCo return ctx.Send(data, apirest.HTTPstatusOK) } -// chainTxHandler +// chainTxByHeightAndIndexHandler // // @Summary Transaction by block height and index // @Description Get transaction full information by block height and index. It returns JSON transaction protobuf encoded. Depending of transaction type will return different types of objects. Current transaction types can be found calling `/chain/transactions/cost` +// @Deprecated +// @Description (deprecated, in favor of /chain/transactions/{hash}) // @Tags Chain // @Accept json // @Produce json @@ -672,7 +680,7 @@ func (a *API) chainTxRefByHashHandler(_ *apirest.APIdata, ctx *httprouter.HTTPCo // @Success 200 {object} GenericTransactionWithInfo // @Success 204 "See [errors](vocdoni-api#errors) section" // @Router /chain/transactions/{height}/{index} [get] -func (a *API) chainTxHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error { +func (a *API) chainTxByHeightAndIndexHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error { height, err := strconv.ParseInt(ctx.URLParam(ParamHeight), 10, 64) if err != nil { return err @@ -681,15 +689,7 @@ func (a *API) chainTxHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) er if err != nil { return err } - stx, err := a.vocapp.GetTx(uint32(height), int32(index)) - if err != nil { - if errors.Is(err, vochain.ErrTransactionNotFound) { - return ErrTransactionNotFound - } - return ErrVochainGetTxFailed.WithErr(err) - } - - ref, err := a.indexer.GetTxReferenceByBlockHeightAndBlockIndex(height, index) + itx, err := a.indexer.GetTransactionByHeightAndIndex(height, index) if err != nil { if errors.Is(err, indexer.ErrTransactionNotFound) { return ErrTransactionNotFound @@ -697,9 +697,9 @@ func (a *API) chainTxHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) er return ErrVochainGetTxFailed.WithErr(err) } tx := &GenericTransactionWithInfo{ - TxContent: []byte(protoFormat(stx.Tx)), - Signature: stx.Signature, - TxInfo: *ref, + TxContent: protoTxAsJSON(itx.RawTx), + Signature: itx.Signature, + TxInfo: itx, } data, err := json.Marshal(tx) if err != nil { @@ -708,30 +708,35 @@ func (a *API) chainTxHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) er return ctx.Send(data, apirest.HTTPstatusOK) } -// chainTxRefByIndexHandler +// chainTxByHashHandler // -// @Summary Transaction by index -// @Description Get transaction by its index. This is not transaction reference (hash), and neither the block height and block index. The transaction index is an incremental counter for each transaction. You could use the transaction `block` and `index` to retrieve full info using [transaction by block and index](transaction-by-block-index). +// @Summary Transaction by hash +// @Description Get transaction full information by hash. It returns JSON transaction protobuf encoded. Depending of transaction type will return different types of objects. Current transaction types can be found calling `/chain/transactions/cost` // @Tags Chain // @Accept json // @Produce json -// @Param index path int true "Index of the transaction" -// @Success 200 {object} indexertypes.Transaction +// @Param hash path string true "Transaction hash" +// @Success 200 {object} GenericTransactionWithInfo // @Success 204 "See [errors](vocdoni-api#errors) section" -// @Router /chain/transactions/reference/index/{index} [get] -func (a *API) chainTxRefByIndexHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error { - index, err := strconv.ParseUint(ctx.URLParam("index"), 10, 64) +// @Router /chain/transactions/{hash} [get] +func (a *API) chainTxByHashHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error { + hash, err := hex.DecodeString(util.TrimHex(ctx.URLParam(ParamHash))) if err != nil { - return err + return ErrCantParseHexString.WithErr(err) } - ref, err := a.indexer.GetTransaction(index) + itx, err := a.indexer.GetTransactionByHash(hash) if err != nil { if errors.Is(err, indexer.ErrTransactionNotFound) { return ErrTransactionNotFound } return ErrVochainGetTxFailed.WithErr(err) } - data, err := json.Marshal(ref) + tx := &GenericTransactionWithInfo{ + TxContent: protoTxAsJSON(itx.RawTx), + Signature: itx.Signature, + TxInfo: itx, + } + data, err := json.Marshal(tx) if err != nil { return err } @@ -741,22 +746,28 @@ func (a *API) chainTxRefByIndexHandler(_ *apirest.APIdata, ctx *httprouter.HTTPC // chainTxListHandler // // @Summary List transactions -// @Description To get full transaction information use [/chain/transaction/{blockHeight}/{txIndex}](transaction-by-block-index).\nWhere transactionIndex is the index of the transaction on the containing block. +// @Description To get full transaction information use [/chain/transaction/{hash}](transaction-by-hash). // @Tags Chain // @Accept json // @Produce json // @Param page query number false "Page" // @Param limit query number false "Items per page" +// @Param hash query string false "Tx hash" // @Param height query number false "Block height" // @Param type query string false "Tx type" -// @Success 200 {object} TransactionsList "List of transactions references" +// @Param subtype query string false "Tx subtype" +// @Param signer query string false "Tx signer" +// @Success 200 {object} TransactionsList "List of transactions (metadata only)" // @Router /chain/transactions [get] func (a *API) chainTxListHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error { params, err := parseTransactionParams( ctx.QueryParam(ParamPage), ctx.QueryParam(ParamLimit), + ctx.QueryParam(ParamHash), ctx.QueryParam(ParamHeight), ctx.QueryParam(ParamType), + ctx.QueryParam(ParamSubtype), + ctx.QueryParam(ParamSigner), ) if err != nil { return err @@ -772,7 +783,7 @@ func (a *API) chainTxListHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext // chainTxListByPageHandler // -// @Summary List transactions +// @Summary List transactions (legacy) // @Description To get full transaction information use [/chain/transaction/{blockHeight}/{txIndex}](transaction-by-block-index).\nWhere transactionIndex is the index of the transaction on the containing block. // @Deprecated // @Description (deprecated, in favor of /chain/transactions?page=xxx) @@ -780,7 +791,7 @@ func (a *API) chainTxListHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext // @Accept json // @Produce json // @Param page path number true "Page" -// @Success 200 {object} TransactionsList "List of transactions references" +// @Success 200 {object} TransactionsList "List of transactions (metadata only)" // @Router /chain/transactions/page/{page} [get] func (a *API) chainTxListByPageHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error { params, err := parseTransactionParams( @@ -788,6 +799,9 @@ func (a *API) chainTxListByPageHandler(_ *apirest.APIdata, ctx *httprouter.HTTPC "", "", "", + "", + "", + "", ) if err != nil { return err @@ -824,6 +838,9 @@ func (a *API) chainTxListByHeightAndPageHandler(_ *apirest.APIdata, ctx *httprou "", ctx.URLParam(ParamHeight), "", + "", + "", + "", ) if err != nil { return err @@ -849,7 +866,10 @@ func (a *API) transactionList(params *TransactionParams) (*TransactionsList, err params.Limit, params.Page*params.Limit, params.Height, + params.Hash, params.Type, + params.Subtype, + params.Signer, ) if err != nil { return nil, ErrIndexerQueryFailed.WithErr(err) @@ -902,7 +922,7 @@ func (a *API) chainValidatorsHandler(_ *apirest.APIdata, ctx *httprouter.HTTPCon return ctx.Send(data, apirest.HTTPstatusOK) } -// chainBlockHandler +// chainBlockByHeightHandler // // @Summary Get block (by height) // @Description Returns the full block information at the given height @@ -912,23 +932,34 @@ func (a *API) chainValidatorsHandler(_ *apirest.APIdata, ctx *httprouter.HTTPCon // @Param height path int true "Block height" // @Success 200 {object} api.Block // @Router /chain/blocks/{height} [get] -func (a *API) chainBlockHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error { +func (a *API) chainBlockByHeightHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error { height, err := strconv.ParseUint(ctx.URLParam(ParamHeight), 10, 64) if err != nil { return err } - tmblock := a.vocapp.GetBlockByHeight(int64(height)) - if tmblock == nil { - return ErrBlockNotFound + idxblock, err := a.indexer.BlockByHeight(int64(height)) + if err != nil { + if errors.Is(err, indexer.ErrBlockNotFound) { + return ErrBlockNotFound + } + return ErrBlockNotFound.WithErr(err) + } + txcount, err := a.indexer.CountTransactionsByHeight(int64(height)) + if err != nil { + return ErrIndexerQueryFailed.WithErr(err) } block := &Block{ - Block: comettypes.Block{ - Header: tmblock.Header, - Data: tmblock.Data, - Evidence: tmblock.Evidence, - LastCommit: tmblock.LastCommit, + Header: comettypes.Header{ + ChainID: idxblock.ChainID, + Height: idxblock.Height, + Time: idxblock.Time, + ProposerAddress: []byte(idxblock.ProposerAddress), + LastBlockID: comettypes.BlockID{ + Hash: []byte(idxblock.LastBlockHash), + }, }, - Hash: types.HexBytes(tmblock.Hash()), + Hash: idxblock.Hash, + TxCount: txcount, } data, err := json.Marshal(block) if err != nil { @@ -952,18 +983,29 @@ func (a *API) chainBlockByHashHandler(_ *apirest.APIdata, ctx *httprouter.HTTPCo if err != nil { return err } - tmblock := a.vocapp.GetBlockByHash(hash) - if tmblock == nil { - return ErrBlockNotFound + idxblock, err := a.indexer.BlockByHash(hash) + if err != nil { + if errors.Is(err, indexer.ErrBlockNotFound) { + return ErrBlockNotFound + } + return ErrBlockNotFound.WithErr(err) + } + txcount, err := a.indexer.CountTransactionsByHeight(idxblock.Height) + if err != nil { + return ErrIndexerQueryFailed.WithErr(err) } block := &Block{ - Block: comettypes.Block{ - Header: tmblock.Header, - Data: tmblock.Data, - Evidence: tmblock.Evidence, - LastCommit: tmblock.LastCommit, + Header: comettypes.Header{ + ChainID: idxblock.ChainID, + Height: idxblock.Height, + Time: idxblock.Time, + ProposerAddress: []byte(idxblock.ProposerAddress), + LastBlockID: comettypes.BlockID{ + Hash: []byte(idxblock.LastBlockHash), + }, }, - Hash: types.HexBytes(tmblock.Hash()), + Hash: idxblock.Hash, + TxCount: txcount, } data, err := json.Marshal(block) if err != nil { @@ -972,6 +1014,63 @@ func (a *API) chainBlockByHashHandler(_ *apirest.APIdata, ctx *httprouter.HTTPCo return ctx.Send(convertKeysToCamel(data), apirest.HTTPstatusOK) } +// chainBlockListHandler +// +// @Summary List all blocks +// @Description Returns the list of blocks, ordered by descending height. +// @Tags Chain +// @Accept json +// @Produce json +// @Param page query number false "Page" +// @Param limit query number false "Items per page" +// @Param chainId query string false "Filter by exact chainId" +// @Param hash query string false "Filter by partial hash" +// @Param proposerAddress query string false "Filter by exact proposerAddress" +// @Success 200 {object} BlockList +// @Router /chain/blocks [get] +func (a *API) chainBlockListHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContext) error { + params, err := parseBlockParams( + ctx.QueryParam(ParamPage), + ctx.QueryParam(ParamLimit), + ctx.QueryParam(ParamChainId), + ctx.QueryParam(ParamHash), + ctx.QueryParam(ParamProposerAddress), + ) + if err != nil { + return err + } + + return a.sendBlockList(ctx, params) +} + +// sendBlockList produces a filtered, paginated BlockList, +// and sends it marshalled over ctx.Send +// +// Errors returned are always of type APIerror. +func (a *API) sendBlockList(ctx *httprouter.HTTPContext, params *BlockParams) error { + blocks, total, err := a.indexer.BlockList( + params.Limit, + params.Page*params.Limit, + params.ChainID, + params.Hash, + params.ProposerAddress, + ) + if err != nil { + return ErrIndexerQueryFailed.WithErr(err) + } + + pagination, err := calculatePagination(params.Page, params.Limit, total) + if err != nil { + return err + } + + list := &BlockList{ + Blocks: blocks, + Pagination: pagination, + } + return marshalAndSend(ctx, list) +} + // chainTransactionCountHandler // // @Summary Transactions count @@ -1303,7 +1402,7 @@ func parseTransfersParams(paramPage, paramLimit, paramAccountId, paramAccountIdF } // parseTransactionParams returns an TransactionParams filled with the passed params -func parseTransactionParams(paramPage, paramLimit, paramHeight, paramType string) (*TransactionParams, error) { +func parseTransactionParams(paramPage, paramLimit, paramHash, paramHeight, paramType, paramSubtype, paramSigner string) (*TransactionParams, error) { pagination, err := parsePaginationParams(paramPage, paramLimit) if err != nil { return nil, err @@ -1316,7 +1415,25 @@ func parseTransactionParams(paramPage, paramLimit, paramHeight, paramType string return &TransactionParams{ PaginationParams: pagination, + Hash: util.TrimHex(paramHash), Height: uint64(height), Type: paramType, + Subtype: paramSubtype, + Signer: util.TrimHex(paramSigner), + }, nil +} + +// parseBlockParams returns an BlockParams filled with the passed params +func parseBlockParams(paramPage, paramLimit, paramChainId, paramHash, paramProposerAddress string) (*BlockParams, error) { + pagination, err := parsePaginationParams(paramPage, paramLimit) + if err != nil { + return nil, err + } + + return &BlockParams{ + PaginationParams: pagination, + ChainID: paramChainId, + Hash: util.TrimHex(paramHash), + ProposerAddress: util.TrimHex(paramProposerAddress), }, nil } diff --git a/api/docs/descriptions/api.md b/api/docs/descriptions/api.md index daf9d2989..426bb2e7a 100644 --- a/api/docs/descriptions/api.md +++ b/api/docs/descriptions/api.md @@ -1,5 +1,11 @@ -The Vocdoni API is a REST API that substitutes the previous RPCs in order to make it easier for developers/integrators to build on top of the voting protocol. This API facilitates the creation of voting processes with Vocdoni, without the hassle of integrating with a complex distributed stack with blockchain components. The API allows integrators to perform all the features enabled by the Vocdoni voting protocol, such as creating accounts, organizations, voting processes, and censuses, as well as casting votes. The API is designed to abstract away the complexity of the Vocdoni protocol as much as possible, offering a simple and straightforward way to performing these actions. +The Vocdoni API is a REST API that substitutes the previous RPCs in order to make it easier for developers/integrators to build on top of the voting protocol. This API facilitates the creation of voting processes with Vocdoni, without the hassle of integrating with a complex distributed stack with blockchain components. The API allows integrators to perform all the features enabled by the Vocdoni voting protocol, such as creating accounts, organizations, voting processes, and censuses, as well as casting votes. The API is designed to abstract away the complexity of the Vocdoni protocol as much as possible, offering a simple and straightforward way to performing these actions. + +Vocdoni API URLs: + +- **Production**: https://api.vocdoni.io/v2 +- **Staging**: https://api-stg.vocdoni.net/v2 +- **Development**: https://api-dev.vocdoni.net/v2 The API contains the following endpoints: diff --git a/api/elections.go b/api/elections.go index 9e921f616..5548a48b6 100644 --- a/api/elections.go +++ b/api/elections.go @@ -292,7 +292,7 @@ func (a *API) electionListHandler(_ *apirest.APIdata, ctx *httprouter.HTTPContex // // Errors returned are always of type APIerror. func (a *API) electionList(params *ElectionParams) (*ElectionsList, error) { - if params.OrganizationID != "" && !a.indexer.EntityExists(params.OrganizationID) { + if params.OrganizationID != "" && !a.indexer.AccountExists(params.OrganizationID) { return nil, ErrOrgNotFound } diff --git a/api/helpers.go b/api/helpers.go index 3c47b4ac2..a45c04aa6 100644 --- a/api/helpers.go +++ b/api/helpers.go @@ -1,12 +1,16 @@ package api import ( + "bytes" + "encoding/base64" "encoding/hex" "encoding/json" "errors" "fmt" "math" "math/big" + "reflect" + "slices" "strconv" "strings" "time" @@ -57,17 +61,66 @@ func (a *API) sendTx(tx []byte) (*cometcoretypes.ResultBroadcastTx, error) { return resp, nil } -func protoFormat(tx []byte) string { +func protoTxAsJSON(tx []byte) []byte { ptx := models.Tx{} if err := proto.Unmarshal(tx, &ptx); err != nil { - return "" + panic(err) } pj := protojson.MarshalOptions{ Multiline: false, Indent: "", EmitUnpopulated: true, } - return pj.Format(&ptx) + asJSON, err := pj.Marshal(&ptx) + if err != nil { + panic(err) + } + // protojson follows protobuf's json mapping behavior, + // which requires bytes to be encoded as base64: + // https://protobuf.dev/programming-guides/proto3/#json + // + // We want hex rather than base64 for consistency with our REST API + // protojson does not expose any option to configure its behavior, + // and as the Go types are code generated, we cannot use our HexBytes type. + // + // Do a bit of a hack: walk the protobuf value with reflection, + // find all []byte values, and search-and-replace their base64 encoding with hex + // in the protojson bytes. This can be slow if we have many byte slices, + // but in general the protobuf message will be small so there will be few. + bytesValues := collectBytesValues(nil, reflect.ValueOf(&ptx)) + for _, bv := range bytesValues { + asBase64 := base64.StdEncoding.AppendEncode(nil, bv) + asHex := hex.AppendEncode(nil, bv) + asJSON = bytes.Replace(asJSON, asBase64, asHex, 1) + } + return asJSON +} + +var typBytes = reflect.TypeFor[[]byte]() + +func collectBytesValues(result [][]byte, val reflect.Value) [][]byte { + typ := val.Type() + if typ == typBytes { + return append(result, val.Bytes()) + } + switch typ.Kind() { + case reflect.Pointer, reflect.Interface: + if !val.IsNil() { + result = collectBytesValues(result, val.Elem()) + } + case reflect.Struct: + for i := 0; i < val.NumField(); i++ { + if !typ.Field(i).IsExported() { + continue + } + result = collectBytesValues(result, val.Field(i)) + } + case reflect.Slice, reflect.Array: + for i := 0; i < val.Len(); i++ { + result = collectBytesValues(result, val.Index(i)) + } + } + return result } // isTransactionType checks if the given transaction is of the given type. @@ -154,13 +207,13 @@ func encodeEVMResultsArgs(electionId common.Hash, organizationId common.Address, // decryptVotePackage decrypts a vote package using the given private keys and indexes. func decryptVotePackage(vp []byte, privKeys []string, indexes []uint32) ([]byte, error) { - for i := len(indexes) - 1; i >= 0; i-- { - if indexes[i] >= uint32(len(privKeys)) { - return nil, fmt.Errorf("invalid key index %d", indexes[i]) + for _, index := range slices.Backward(indexes) { + if index >= uint32(len(privKeys)) { + return nil, fmt.Errorf("invalid key index %d", index) } - priv, err := nacl.DecodePrivate(privKeys[indexes[i]]) + priv, err := nacl.DecodePrivate(privKeys[index]) if err != nil { - return nil, fmt.Errorf("cannot decode encryption key with index %d: (%s)", indexes[i], err) + return nil, fmt.Errorf("cannot decode encryption key with index %d: (%s)", index, err) } vp, err = priv.Decrypt(vp) if err != nil { diff --git a/api/helpers_test.go b/api/helpers_test.go index 02038a659..0a19102a9 100644 --- a/api/helpers_test.go +++ b/api/helpers_test.go @@ -3,11 +3,16 @@ package api import ( "bytes" "encoding/json" + "strings" "testing" "github.com/ethereum/go-ethereum/common" + qt "github.com/frankban/quicktest" "github.com/google/go-cmp/cmp" "go.vocdoni.io/dvote/types" + "go.vocdoni.io/proto/build/go/models" + "google.golang.org/protobuf/encoding/protojson" + "google.golang.org/protobuf/proto" ) func TestAPIHelpers_encodeEVMResultsArgs(t *testing.T) { @@ -149,3 +154,43 @@ func TestConvertKeysToCamel(t *testing.T) { t.Fatal(diff) } } + +func TestProtoTxAsJSON(t *testing.T) { + inputJSON := strings.TrimSpace(` +{ + "setProcess": { + "txtype": "SET_PROCESS_CENSUS", + "nonce": 1, + "processId": "sx3/YYFNq5DWw6m2XWyQgwSA5Lda0y50eUICAAAAAAA=", + "censusRoot": "zUU9BcTLBCnuXuGu/tAW9VO4AmtM7VsMNSkFv6U8foE=", + "censusURI": "ipfs://bafybeicyfukarcryrvy5oe37ligmxwf55sbfiojori4t25wencma4ymxfa", + "censusSize": "1000" + } +} +`) + wantJSON := strings.TrimSpace(` +{ + "setProcess": { + "txtype": "SET_PROCESS_CENSUS", + "nonce": 1, + "processId": "b31dff61814dab90d6c3a9b65d6c90830480e4b75ad32e747942020000000000", + "censusRoot": "cd453d05c4cb0429ee5ee1aefed016f553b8026b4ced5b0c352905bfa53c7e81", + "censusURI": "ipfs://bafybeicyfukarcryrvy5oe37ligmxwf55sbfiojori4t25wencma4ymxfa", + "censusSize": "1000" + } +} +`) + var ptx models.Tx + err := protojson.Unmarshal([]byte(inputJSON), &ptx) + qt.Assert(t, err, qt.IsNil) + + asProto, err := proto.Marshal(&ptx) + qt.Assert(t, err, qt.IsNil) + + var dst bytes.Buffer + err = json.Indent(&dst, protoTxAsJSON(asProto), "", "\t") + qt.Assert(t, err, qt.IsNil) + gotJSON := dst.String() + + qt.Assert(t, gotJSON, qt.Equals, wantJSON) +} diff --git a/api/metadata_types.go b/api/metadata_types.go index 066d9849d..d41d75751 100644 --- a/api/metadata_types.go +++ b/api/metadata_types.go @@ -33,12 +33,14 @@ type Question struct { Choices []ChoiceMetadata `json:"choices"` Description LanguageString `json:"description"` Title LanguageString `json:"title"` + Meta any `json:"meta,omitempty"` } // ChoiceMetadata contains metadata for one choice of a question type ChoiceMetadata struct { Title LanguageString `json:"title"` Value uint32 `json:"value"` + Meta any `json:"meta,omitempty"` } // AccountMetadata is the metadata for an organization diff --git a/censustree/censustree.go b/censustree/censustree.go index 515648b73..7a5ce433f 100644 --- a/censustree/censustree.go +++ b/censustree/censustree.go @@ -125,12 +125,12 @@ func (t *Tree) Hash(data []byte) ([]byte, error) { // BytesToBigInt unmarshals a slice of bytes into a bigInt following the censusTree encoding rules func (*Tree) BytesToBigInt(data []byte) *big.Int { - return arbo.BytesToBigInt(data) + return arbo.BytesLEToBigInt(data) } // BigIntToBytes marshals a bigInt following the censusTree encoding rules func (t *Tree) BigIntToBytes(b *big.Int) []byte { - return arbo.BigIntToBytes(t.hashLen, b) + return arbo.BigIntToBytesLE(t.hashLen, b) } // FromRoot returns a new read-only Tree for the given root, that uses the same diff --git a/cmd/end2endtest/account.go b/cmd/end2endtest/account.go index af0ab6c86..08de5b7e1 100644 --- a/cmd/end2endtest/account.go +++ b/cmd/end2endtest/account.go @@ -122,10 +122,16 @@ func testCreateAndSetAccount(api *apiclient.HTTPclient, fp *models.FaucetPackage return err } + // get the create account transaction cost + txCost, err := api.TransactionCost(models.TxType_CREATE_ACCOUNT) + if err != nil { + return fmt.Errorf("error fetching transaction cost: %w", err) + } + // create account for bob with faucet package from alice afp, err := vochain.GenerateFaucetPackage(alice, bob.Address(), aliceAcc.Balance/2) if err != nil { - return fmt.Errorf("error in GenerateFaucetPackage %v", err) + return fmt.Errorf("error in GenerateFaucetPackage %w", err) } bobAcc, err := ensureAccountExists(api.Clone(hex.EncodeToString(bob.PrivateKey())), afp) @@ -134,9 +140,9 @@ func testCreateAndSetAccount(api *apiclient.HTTPclient, fp *models.FaucetPackage } // check balance added from payload - if bobAcc.Balance != aliceAcc.Balance/2 { + if bobAcc.Balance+txCost != aliceAcc.Balance/2 { return fmt.Errorf("expected balance for bob (%s) is %d but got %d", - bob.Address(), aliceAcc.Balance/2, bobAcc.Balance) + bob.Address(), (aliceAcc.Balance/2)-txCost, bobAcc.Balance) } log.Infow("account for bob successfully created with payload signed by alice", "alice", alice.Address(), "bob", bobAcc) diff --git a/cmd/tools/censusdump/main.go b/cmd/tools/censusdump/main.go index a7f9b09c0..7ae193aed 100644 --- a/cmd/tools/censusdump/main.go +++ b/cmd/tools/censusdump/main.go @@ -122,7 +122,7 @@ func main() { } if err := censusRef.Tree().IterateLeaves(func(key, value []byte) bool { - balance := arbo.BytesToBigInt(value) + balance := arbo.BytesLEToBigInt(value) census.Data = append(census.Data, struct { Address common.Address `json:"address"` Balance string `json:"balance"` diff --git a/crypto/ethereum/vocdoni_sik.go b/crypto/ethereum/vocdoni_sik.go index daa6144b4..ea2359f01 100644 --- a/crypto/ethereum/vocdoni_sik.go +++ b/crypto/ethereum/vocdoni_sik.go @@ -37,7 +37,7 @@ func (k *SignKeys) AccountSIK(secret []byte) ([]byte, error) { return nil, fmt.Errorf("error signing sik payload: %w", err) } seed := []*big.Int{ - arbo.BytesToBigInt(k.Address().Bytes()), + arbo.BytesLEToBigInt(k.Address().Bytes()), util.BigToFF(new(big.Int).SetBytes(secret)), util.BigToFF(new(big.Int).SetBytes(sign)), } @@ -45,7 +45,7 @@ func (k *SignKeys) AccountSIK(secret []byte) ([]byte, error) { if err != nil { return nil, err } - return arbo.BigIntToBytes(arbo.HashFunctionPoseidon.Len(), hash), nil + return arbo.BigIntToBytesLE(arbo.HashFunctionPoseidon.Len(), hash), nil } // AccountSIKnullifier method composes the nullifier of the current SignKeys diff --git a/crypto/zk/circuit/inputs.go b/crypto/zk/circuit/inputs.go index c019d9749..ac13cecb3 100644 --- a/crypto/zk/circuit/inputs.go +++ b/crypto/zk/circuit/inputs.go @@ -84,10 +84,10 @@ func GenerateCircuitInput(p CircuitInputsParameters) (*CircuitInputs, error) { Nullifier: new(big.Int).SetBytes(nullifier).String(), AvailableWeight: p.AvailableWeight.String(), VoteHash: util.BytesToArboSplitStr(p.VotePackage), - SIKRoot: arbo.BytesToBigInt(p.SIKRoot).String(), - CensusRoot: arbo.BytesToBigInt(p.CensusRoot).String(), + SIKRoot: arbo.BytesLEToBigInt(p.SIKRoot).String(), + CensusRoot: arbo.BytesLEToBigInt(p.CensusRoot).String(), - Address: arbo.BytesToBigInt(p.Account.Address().Bytes()).String(), + Address: arbo.BytesLEToBigInt(p.Account.Address().Bytes()).String(), Password: ffPassword.String(), Signature: util.BigToFF(new(big.Int).SetBytes(signature)).String(), diff --git a/crypto/zk/circuit/inputs_test.go b/crypto/zk/circuit/inputs_test.go index a063f0ba1..37e37a4bd 100644 --- a/crypto/zk/circuit/inputs_test.go +++ b/crypto/zk/circuit/inputs_test.go @@ -50,7 +50,7 @@ func TestGenerateCircuitInput(t *testing.T) { SIKRoot: "7714269703880573582519379213888374390024853519732158909852028066903886590497", CensusRoot: "7714269703880573582519379213888374390024853519732158909852028066903886590497", - Address: arbo.BytesToBigInt(acc.Address().Bytes()).String(), + Address: arbo.BytesLEToBigInt(acc.Address().Bytes()).String(), Password: "0", Signature: util.BigToFF(new(big.Int).SetBytes(signature)).String(), diff --git a/crypto/zk/prover/pubsignals.go b/crypto/zk/prover/pubsignals.go index 1aa769397..ca3e83692 100644 --- a/crypto/zk/prover/pubsignals.go +++ b/crypto/zk/prover/pubsignals.go @@ -68,7 +68,7 @@ func (p *Proof) CensusRoot() ([]byte, error) { if err != nil { return nil, err } - return arbo.BigIntToBytes(arbo.HashFunctionPoseidon.Len(), bi), nil + return arbo.BigIntToBytesLE(arbo.HashFunctionPoseidon.Len(), bi), nil } // VoteWeight returns the VoteWeight included into the current proof. @@ -108,5 +108,5 @@ func (p *Proof) SIKRoot() ([]byte, error) { if err != nil { return nil, err } - return arbo.BigIntToBytes(arbo.HashFunctionPoseidon.Len(), bi), nil + return arbo.BigIntToBytesLE(arbo.HashFunctionPoseidon.Len(), bi), nil } diff --git a/crypto/zk/utils.go b/crypto/zk/utils.go index ad52869ce..60a58f5f8 100644 --- a/crypto/zk/utils.go +++ b/crypto/zk/utils.go @@ -93,20 +93,20 @@ func ProverProofToProtobufZKProof(p *prover.Proof, electionId, sikRoot, func zkProofPublicInputs(electionId, sikRoot, censusRoot, nullifier types.HexBytes, voteWeight *big.Int) []string { pubInputs := []string{} // 0. electionId[0] - pubInputs = append(pubInputs, arbo.BytesToBigInt(electionId[:16]).String()) + pubInputs = append(pubInputs, arbo.BytesLEToBigInt(electionId[:16]).String()) // 1. electionId[1] - pubInputs = append(pubInputs, arbo.BytesToBigInt(electionId[16:]).String()) + pubInputs = append(pubInputs, arbo.BytesLEToBigInt(electionId[16:]).String()) // 2. nullifier - pubInputs = append(pubInputs, arbo.BytesToBigInt(nullifier).String()) + pubInputs = append(pubInputs, arbo.BytesLEToBigInt(nullifier).String()) voteHash := sha256.Sum256(voteWeight.Bytes()) // 3. voteHash[0] - pubInputs = append(pubInputs, arbo.BytesToBigInt(voteHash[:16]).String()) + pubInputs = append(pubInputs, arbo.BytesLEToBigInt(voteHash[:16]).String()) // 4. voteHash[1] - pubInputs = append(pubInputs, arbo.BytesToBigInt(voteHash[16:]).String()) + pubInputs = append(pubInputs, arbo.BytesLEToBigInt(voteHash[16:]).String()) // 5. sikRoot - pubInputs = append(pubInputs, arbo.BytesToBigInt(sikRoot).String()) + pubInputs = append(pubInputs, arbo.BytesLEToBigInt(sikRoot).String()) // 6. censusRoot - pubInputs = append(pubInputs, arbo.BytesToBigInt(censusRoot).String()) + pubInputs = append(pubInputs, arbo.BytesLEToBigInt(censusRoot).String()) // 7. availableWeight pubInputs = append(pubInputs, voteWeight.String()) @@ -133,7 +133,7 @@ func ProofToCircomSiblings(proof []byte) ([]string, error) { siblings := make([]string, censustree.DefaultMaxLevels+1) for i := 0; i < len(siblings); i++ { if i < len(rawSiblings) { - siblings[i] = arbo.BytesToBigInt(rawSiblings[i]).String() + siblings[i] = arbo.BytesLEToBigInt(rawSiblings[i]).String() } else { siblings[i] = "0" } diff --git a/data/ipfs/cid.go b/data/ipfs/cid.go index 8538266b8..d4c8a44a1 100644 --- a/data/ipfs/cid.go +++ b/data/ipfs/cid.go @@ -5,13 +5,13 @@ import ( "strings" "github.com/ipfs/boxo/blockservice" + "github.com/ipfs/boxo/blockstore" chunk "github.com/ipfs/boxo/chunker" "github.com/ipfs/boxo/ipld/unixfs/importer/balanced" ihelper "github.com/ipfs/boxo/ipld/unixfs/importer/helpers" ipfscid "github.com/ipfs/go-cid" ds "github.com/ipfs/go-datastore" dssync "github.com/ipfs/go-datastore/sync" - blockstore "github.com/ipfs/go-ipfs-blockstore" offline "github.com/ipfs/go-ipfs-exchange-offline" ipld "github.com/ipfs/go-ipld-format" diff --git a/data/ipfs/ipfs.go b/data/ipfs/ipfs.go index 8640793b9..e64f8ddfa 100644 --- a/data/ipfs/ipfs.go +++ b/data/ipfs/ipfs.go @@ -37,7 +37,7 @@ import ( const ( // MaxFileSizeBytes is the maximum size of a file to be published to IPFS - MaxFileSizeBytes = 1024 * 1024 * 100 // 100 MB + MaxFileSizeBytes = 1024 * 1024 * 1024 // 1 GB // RetrievedFileCacheSize is the maximum number of files to be cached in memory RetrievedFileCacheSize = 128 ) diff --git a/dockerfiles/testsuite/docker-compose.yml b/dockerfiles/testsuite/docker-compose.yml index a32a1f22a..38bae0780 100644 --- a/dockerfiles/testsuite/docker-compose.yml +++ b/dockerfiles/testsuite/docker-compose.yml @@ -101,7 +101,7 @@ services: command: "true" gocoverage: - image: golang:1.22 + image: golang:1.23 volumes: - gocoverage-seed:/app/run/gocoverage/seed - gocoverage-miner0:/app/run/gocoverage/miner0 diff --git a/go.mod b/go.mod index aa2aa5a14..a17aedb74 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module go.vocdoni.io/dvote -go 1.22.2 +go 1.23.0 // For testing purposes // replace go.vocdoni.io/proto => ../dvote-protobuf @@ -29,37 +29,35 @@ require ( github.com/iden3/go-rapidsnark/types v0.0.2 github.com/iden3/go-rapidsnark/verifier v0.0.3 github.com/iden3/go-rapidsnark/witness v0.0.3 - github.com/ipfs/boxo v0.19.0 + github.com/ipfs/boxo v0.24.3 github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-datastore v0.6.0 - github.com/ipfs/go-ipfs-blockstore v1.3.0 github.com/ipfs/go-ipfs-exchange-offline v0.3.0 github.com/ipfs/go-ipfs-keystore v0.1.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-log/v2 v2.5.1 - github.com/ipfs/kubo v0.28.0 - github.com/klauspost/compress v1.17.9 - github.com/libp2p/go-libp2p v0.33.2 - github.com/libp2p/go-libp2p-pubsub v0.10.0 + github.com/ipfs/kubo v0.32.1 + github.com/klauspost/compress v1.17.11 + github.com/libp2p/go-libp2p v0.37.2 + github.com/libp2p/go-libp2p-pubsub v0.12.0 github.com/libp2p/go-reuseport v0.4.0 github.com/manifoldco/promptui v0.9.0 - github.com/mattn/go-sqlite3 v1.14.22 - github.com/multiformats/go-multiaddr v0.12.3 + github.com/mattn/go-sqlite3 v1.14.24 + github.com/multiformats/go-multiaddr v0.13.0 github.com/multiformats/go-multicodec v0.9.0 github.com/multiformats/go-multihash v0.2.3 - github.com/pressly/goose/v3 v3.21.1 - github.com/prometheus/client_golang v1.19.1 + github.com/pressly/goose/v3 v3.23.0 + github.com/prometheus/client_golang v1.20.5 github.com/rs/zerolog v1.31.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.19.0 - github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a + github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d github.com/vocdoni/storage-proofs-eth-go v0.1.6 go.mongodb.org/mongo-driver v1.12.1 - go.vocdoni.io/proto v1.15.8 - golang.org/x/crypto v0.26.0 - golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa - golang.org/x/net v0.28.0 - google.golang.org/protobuf v1.34.2 + go.vocdoni.io/proto v1.15.10-0.20240903073233-86144b1e2165 + golang.org/x/crypto v0.29.0 + golang.org/x/net v0.31.0 + google.golang.org/protobuf v1.35.2 lukechampine.com/blake3 v1.3.0 ) @@ -70,7 +68,7 @@ require ( github.com/DataDog/zstd v1.5.2 // indirect github.com/Jorropo/jsync v1.0.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect + github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b // indirect github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/benbjohnson/clock v1.3.5 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -78,8 +76,10 @@ require ( github.com/blang/semver/v4 v4.0.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.3 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.0.2 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/ceramicnetwork/go-dag-jose v0.1.0 // indirect + github.com/caddyserver/certmagic v0.21.4 // indirect + github.com/caddyserver/zerossl v0.1.3 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/ceramicnetwork/go-dag-jose v0.1.1 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cheggaaa/pb v1.0.29 // indirect @@ -94,21 +94,21 @@ require ( github.com/containerd/cgroups v1.1.0 // indirect github.com/coreos/go-systemd/v22 v22.5.0 // indirect github.com/cosmos/gogoproto v1.5.0 // indirect - github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 // indirect + github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf // indirect github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect github.com/cskr/pubsub v1.0.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c // indirect github.com/deckarep/golang-set/v2 v2.6.0 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/dgraph-io/badger v1.6.2 // indirect github.com/dgraph-io/badger/v2 v2.2007.4 // indirect github.com/dgraph-io/ristretto v0.1.1 // indirect github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/elastic/gosigar v0.14.2 // indirect + github.com/elastic/gosigar v0.14.3 // indirect github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 // indirect github.com/ethereum/c-kzg-4844 v1.0.0 // indirect github.com/ethereum/go-verkle v0.1.1-0.20240306133620-7d920df305f0 // indirect @@ -117,35 +117,37 @@ require ( github.com/flynn/noise v1.1.0 // indirect github.com/francoispqt/gojay v1.2.13 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/gabriel-vasile/mimetype v1.4.3 // indirect + github.com/gabriel-vasile/mimetype v1.4.6 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-chi/chi v4.1.2+incompatible // indirect + github.com/go-jose/go-jose/v4 v4.0.4 // indirect github.com/go-kit/kit v0.13.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/godbus/dbus/v5 v5.1.0 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/gofrs/uuid v4.4.0+incompatible // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/glog v1.2.0 // indirect + github.com/golang/glog v1.2.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/btree v1.1.2 // indirect github.com/google/gopacket v1.1.19 // indirect github.com/google/orderedcode v0.0.1 // indirect - github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 // indirect + github.com/google/pprof v0.0.0-20241017200806-017d972448fc // indirect github.com/gopherjs/gopherjs v0.0.0-20190812055157-5d271430af9f // indirect github.com/gorilla/mux v1.8.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-bexpr v0.1.11 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect github.com/holiman/uint256 v1.3.1 // indirect @@ -155,54 +157,58 @@ require ( github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-bitfield v1.1.0 // indirect github.com/ipfs/go-block-format v0.2.0 // indirect - github.com/ipfs/go-blockservice v0.5.1 // indirect + github.com/ipfs/go-blockservice v0.5.2 // indirect github.com/ipfs/go-cidutil v0.1.0 // indirect github.com/ipfs/go-ds-badger v0.3.0 // indirect github.com/ipfs/go-ds-flatfs v0.5.1 // indirect github.com/ipfs/go-ds-leveldb v0.5.0 // indirect github.com/ipfs/go-ds-measure v0.2.0 // indirect + github.com/ipfs/go-ds-pebble v0.4.0 // indirect github.com/ipfs/go-fs-lock v0.0.7 // indirect - github.com/ipfs/go-ipfs-cmds v0.10.0 // indirect + github.com/ipfs/go-ipfs-blockstore v1.3.1 // indirect + github.com/ipfs/go-ipfs-cmds v0.14.0 // indirect github.com/ipfs/go-ipfs-delay v0.0.1 // indirect - github.com/ipfs/go-ipfs-ds-help v1.1.0 // indirect - github.com/ipfs/go-ipfs-exchange-interface v0.2.0 // indirect + github.com/ipfs/go-ipfs-ds-help v1.1.1 // indirect + github.com/ipfs/go-ipfs-exchange-interface v0.2.1 // indirect github.com/ipfs/go-ipfs-pq v0.0.3 // indirect - github.com/ipfs/go-ipfs-redirects-file v0.1.1 // indirect + github.com/ipfs/go-ipfs-redirects-file v0.1.2 // indirect github.com/ipfs/go-ipfs-util v0.0.3 // indirect - github.com/ipfs/go-ipld-cbor v0.1.0 // indirect + github.com/ipfs/go-ipld-cbor v0.2.0 // indirect github.com/ipfs/go-ipld-git v0.1.1 // indirect github.com/ipfs/go-ipld-legacy v0.2.1 // indirect github.com/ipfs/go-log v1.0.5 // indirect github.com/ipfs/go-merkledag v0.11.0 // indirect github.com/ipfs/go-metrics-interface v0.0.1 // indirect github.com/ipfs/go-peertaskqueue v0.8.1 // indirect - github.com/ipfs/go-unixfsnode v1.9.0 // indirect - github.com/ipfs/go-verifcid v0.0.2 // indirect - github.com/ipld/go-car v0.5.0 // indirect - github.com/ipld/go-car/v2 v2.13.1 // indirect + github.com/ipfs/go-unixfsnode v1.9.2 // indirect + github.com/ipfs/go-verifcid v0.0.3 // indirect + github.com/ipld/go-car v0.6.2 // indirect + github.com/ipld/go-car/v2 v2.14.2 // indirect github.com/ipld/go-codec-dagpb v1.6.0 // indirect github.com/ipld/go-ipld-prime v0.21.0 // indirect + github.com/ipshipyard/p2p-forge v0.0.2 // indirect github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jbenet/go-temp-err-catcher v0.1.0 // indirect github.com/jbenet/goprocess v0.1.4 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/koron/go-ssdp v0.0.4 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.10.9 // indirect + github.com/libdns/libdns v0.2.2 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/libp2p/go-cidranger v1.1.0 // indirect github.com/libp2p/go-doh-resolver v0.4.0 // indirect - github.com/libp2p/go-flow-metrics v0.1.0 // indirect + github.com/libp2p/go-flow-metrics v0.2.0 // indirect github.com/libp2p/go-libp2p-asn-util v0.4.1 // indirect github.com/libp2p/go-libp2p-gostream v0.6.0 // indirect github.com/libp2p/go-libp2p-http v0.5.0 // indirect - github.com/libp2p/go-libp2p-kad-dht v0.25.2 // indirect - github.com/libp2p/go-libp2p-kbucket v0.6.3 // indirect + github.com/libp2p/go-libp2p-kad-dht v0.28.1 // indirect + github.com/libp2p/go-libp2p-kbucket v0.6.4 // indirect github.com/libp2p/go-libp2p-pubsub-router v0.6.0 // indirect github.com/libp2p/go-libp2p-record v0.2.0 // indirect - github.com/libp2p/go-libp2p-routing-helpers v0.7.3 // indirect + github.com/libp2p/go-libp2p-routing-helpers v0.7.4 // indirect github.com/libp2p/go-libp2p-xor v0.1.0 // indirect github.com/libp2p/go-msgio v0.3.0 // indirect github.com/libp2p/go-nat v0.2.0 // indirect @@ -214,73 +220,73 @@ require ( github.com/marten-seemann/tcp v0.0.0-20210406111302-dfbc87cc63fd // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.14 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mfridman/interpolate v0.0.2 // indirect github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect - github.com/miekg/dns v1.1.58 // indirect + github.com/mholt/acmez/v2 v2.0.3 // indirect + github.com/miekg/dns v1.1.62 // indirect github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b // indirect github.com/mikioh/tcpopt v0.0.0-20190314235656-172688c1accc // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/minio/sha256-simd v1.0.1 // indirect - github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // 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.2.0 // indirect - github.com/multiformats/go-multiaddr-dns v0.3.1 // indirect + github.com/multiformats/go-multiaddr-dns v0.4.1 // indirect github.com/multiformats/go-multiaddr-fmt v0.1.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect - github.com/multiformats/go-multistream v0.5.0 // indirect + github.com/multiformats/go-multistream v0.6.0 // indirect github.com/multiformats/go-varint v0.0.7 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect - github.com/onsi/ginkgo/v2 v2.15.0 // indirect + github.com/onsi/ginkgo/v2 v2.20.2 // indirect github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/openzipkin/zipkin-go v0.4.2 // indirect + github.com/openzipkin/zipkin-go v0.4.3 // indirect github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/petermattis/goid v0.0.0-20221018141743-354ef7f2fd21 // indirect - github.com/pion/datachannel v1.5.5 // indirect - github.com/pion/dtls/v2 v2.2.8 // indirect - github.com/pion/ice/v2 v2.3.11 // indirect - github.com/pion/interceptor v0.1.25 // indirect + github.com/pion/datachannel v1.5.9 // indirect + github.com/pion/dtls/v2 v2.2.12 // indirect + github.com/pion/ice/v2 v2.3.36 // indirect + github.com/pion/interceptor v0.1.37 // indirect github.com/pion/logging v0.2.2 // indirect - github.com/pion/mdns v0.0.9 // indirect + github.com/pion/mdns v0.0.12 // indirect github.com/pion/randutil v0.1.0 // indirect - github.com/pion/rtcp v1.2.13 // indirect - github.com/pion/rtp v1.8.3 // indirect - github.com/pion/sctp v1.8.9 // indirect - github.com/pion/sdp/v3 v3.0.6 // indirect - github.com/pion/srtp/v2 v2.0.18 // indirect + github.com/pion/rtcp v1.2.14 // indirect + github.com/pion/rtp v1.8.9 // indirect + github.com/pion/sctp v1.8.33 // indirect + github.com/pion/sdp/v3 v3.0.9 // indirect + github.com/pion/srtp/v2 v2.0.20 // indirect github.com/pion/stun v0.6.1 // indirect - github.com/pion/transport/v2 v2.2.4 // indirect - github.com/pion/turn/v2 v2.1.4 // indirect - github.com/pion/webrtc/v3 v3.2.23 // indirect + github.com/pion/transport/v2 v2.2.10 // indirect + github.com/pion/turn/v2 v2.1.6 // indirect + github.com/pion/webrtc/v3 v3.3.4 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/polydawn/refmt v0.89.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/common v0.60.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/statsd_exporter v0.22.8 // indirect - github.com/quic-go/qpack v0.4.0 // indirect - github.com/quic-go/quic-go v0.42.0 // indirect - github.com/quic-go/webtransport-go v0.6.0 // indirect + github.com/quic-go/qpack v0.5.1 // indirect + github.com/quic-go/quic-go v0.48.2 // indirect + github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 // indirect github.com/raulk/go-watchdog v1.3.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/rivo/uniseg v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect - github.com/rs/cors v1.11.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect + github.com/rs/cors v1.11.1 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect - github.com/samber/lo v1.39.0 // indirect + github.com/samber/lo v1.47.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect - github.com/sethvargo/go-retry v0.2.4 // indirect + github.com/sethvargo/go-retry v0.3.0 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect @@ -297,49 +303,51 @@ require ( github.com/wasmerio/wasmer-go v1.0.4 // indirect github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - github.com/whyrusleeping/cbor-gen v0.1.0 // indirect + github.com/whyrusleeping/cbor-gen v0.1.2 // indirect github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f // indirect github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 // indirect github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1 // indirect github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 // indirect + github.com/wlynxg/anet v0.0.5 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect github.com/yusufpapurcu/wmi v1.2.2 // indirect + github.com/zeebo/blake3 v0.2.4 // indirect go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 // indirect go.opencensus.io v0.24.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 // indirect - go.opentelemetry.io/otel v1.24.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 // indirect - go.opentelemetry.io/otel/exporters/zipkin v1.21.0 // indirect - go.opentelemetry.io/otel/metric v1.24.0 // indirect - go.opentelemetry.io/otel/sdk v1.21.0 // indirect - go.opentelemetry.io/otel/trace v1.24.0 // indirect - go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect + go.opentelemetry.io/otel v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 // indirect + go.opentelemetry.io/otel/exporters/zipkin v1.31.0 // indirect + go.opentelemetry.io/otel/metric v1.31.0 // indirect + go.opentelemetry.io/otel/sdk v1.31.0 // indirect + go.opentelemetry.io/otel/trace v1.31.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect - go.uber.org/dig v1.17.1 // indirect - go.uber.org/fx v1.20.1 // indirect - go.uber.org/mock v0.4.0 // indirect + go.uber.org/dig v1.18.0 // indirect + go.uber.org/fx v1.23.0 // indirect + go.uber.org/mock v0.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect go4.org v0.0.0-20230225012048-214862532bf5 // indirect - golang.org/x/mod v0.20.0 // indirect - golang.org/x/oauth2 v0.22.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.23.0 // indirect - golang.org/x/text v0.17.0 // indirect - golang.org/x/tools v0.24.0 // indirect - golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/oauth2 v0.23.0 // indirect + golang.org/x/sync v0.9.0 // indirect + golang.org/x/sys v0.27.0 // indirect + golang.org/x/text v0.20.0 // indirect + golang.org/x/tools v0.26.0 // indirect + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect gonum.org/v1/gonum v0.15.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect - google.golang.org/grpc v1.64.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/grpc v1.67.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/square/go-jose.v2 v2.5.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect diff --git a/go.sum b/go.sum index 29c3e9e21..55f25df1b 100644 --- a/go.sum +++ b/go.sum @@ -106,8 +106,8 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs= -github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0= +github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 h1:iW0a5ljuFxkLGPNem5Ui+KBjFJzKg4Fv2fnxe4dvzpM= github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5/go.mod h1:Y2QMoi1vgtOIfc+6DhrMOGkLoGzqSV2rKp4Sm+opsyA= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= @@ -177,14 +177,18 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= github.com/c-bata/go-prompt v0.2.2/go.mod h1:VzqtzE2ksDBcdln8G7mk2RX9QyGjH+OVqOCSiVIqS34= +github.com/caddyserver/certmagic v0.21.4 h1:e7VobB8rffHv8ZZpSiZtEwnLDHUwLVYLWzWSa1FfKI0= +github.com/caddyserver/certmagic v0.21.4/go.mod h1:swUXjQ1T9ZtMv95qj7/InJvWLXURU85r+CfG0T+ZbDE= +github.com/caddyserver/zerossl v0.1.3 h1:onS+pxp3M8HnHpN5MMbOMyNjmTheJyWRaZYwn+YTAyA= +github.com/caddyserver/zerossl v0.1.3/go.mod h1:CxA0acn7oEGO6//4rtrRjYgEoa4MFw/XofZnrYwGqG4= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -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/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/ceramicnetwork/go-dag-jose v0.1.0 h1:yJ/HVlfKpnD3LdYP03AHyTvbm3BpPiz2oZiOeReJRdU= -github.com/ceramicnetwork/go-dag-jose v0.1.0/go.mod h1:qYA1nYt0X8u4XoMAVoOV3upUVKtrxy/I670Dg5F0wjI= +github.com/ceramicnetwork/go-dag-jose v0.1.1 h1:7pObs22egc14vSS3AfCFfS1VmaL4lQUsAK7OGC3PlKk= +github.com/ceramicnetwork/go-dag-jose v0.1.1/go.mod h1:8ptnYwY2Z2y/s5oJnNBn/UCxLg6CpramNJ2ZXF/5aNY= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= @@ -262,8 +266,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:ma github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668 h1:ZFUue+PNxmHlu7pYv+IYMtqlaO/0VwaGEqKepZf9JpA= -github.com/crackcomm/go-gitignore v0.0.0-20231225121904-e25f5bc08668/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= +github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf h1:dwGgBWn84wUS1pVikGiruW+x5XM4amhjaZO20vCjay4= +github.com/crackcomm/go-gitignore v0.0.0-20241020182519-7843d2ba8fdf/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLRPrZhHjHxufI8+2UG/i25QG92j0Er9p6I= github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= @@ -288,8 +292,8 @@ github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80N github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/deepmap/oapi-codegen v1.6.0/go.mod h1:ryDa9AgbELGeB+YEXE1dR53yAjHwFvE9iAUlWl9Al3M= github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= @@ -328,8 +332,8 @@ github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7j github.com/edsrzf/mmap-go v0.0.0-20160512033002-935e0e8a636c/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= -github.com/elastic/gosigar v0.14.2 h1:Dg80n8cr90OZ7x+bAax/QjoW/XqTI11RmA79ZwIm9/4= -github.com/elastic/gosigar v0.14.2/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= +github.com/elastic/gosigar v0.14.3 h1:xwkKwPia+hSfg9GqrCUKYdId102m9qTJIIr7egmK/uo= +github.com/elastic/gosigar v0.14.3/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302 h1:QV0ZrfBLpFc2KDk+a4LJefDczXnonRwrYrQJY/9L4dA= github.com/elgris/jsondiff v0.0.0-20160530203242-765b5c24c302/go.mod h1:qBlWZqWeVx9BjvqBsnC/8RUlAYpIFmPvgROcw0n1scE= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= @@ -370,7 +374,6 @@ github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVB github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/frankban/quicktest v1.13.0/go.mod h1:qLE0fzW0VuyUAJgPU19zByoIr0HtCHN/r/VLSOOIySU= -github.com/frankban/quicktest v1.14.0/go.mod h1:NeW+ay9A/U67EYXNFA1nPE8e/tnQv/09mUdL/ijj8og= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -378,8 +381,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0= -github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk= +github.com/gabriel-vasile/mimetype v1.4.6 h1:3+PzJTKLkvgjeTbts6msPJt4DixhT4YtFNf1gtGe3zc= +github.com/gabriel-vasile/mimetype v1.4.6/go.mod h1:JX1qVKqZd40hUPpAfiNTe0Sne7hdfKSbOqqmkq8GCXc= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= @@ -407,6 +410,8 @@ github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3Bop github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -423,8 +428,8 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= @@ -439,8 +444,8 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -459,13 +464,13 @@ github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= -github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.5.1 h1:JdqV9zKUdtaa9gdPlywC3aeoEsR681PlKC+4F5gQgeo= +github.com/golang-jwt/jwt/v4 v4.5.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= -github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= +github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -522,7 +527,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/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.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -547,8 +551,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5 h1:E/LAvt58di64hlYjx7AsNS6C/ysHWYo+2qPCZKTQhRo= -github.com/google/pprof v0.0.0-20240207164012-fb44976bdcd5/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik= +github.com/google/pprof v0.0.0-20241017200806-017d972448fc h1:NGyrhhFhwvRAZg02jnYVg3GBQy0qGBKmFQJwaPmpmxs= +github.com/google/pprof v0.0.0-20241017200806-017d972448fc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -583,8 +587,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.5.0/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0 h1:Wqo399gCIufwto+VfwCSvsnfGpF/w5E9CNxSwbpD6No= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.19.0/go.mod h1:qmOFXW2epJhM0qSnUUYpldc7gVz2KMQwJ/QYCDIa7XU= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= @@ -606,6 +610,8 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -671,8 +677,8 @@ github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c h1:7Uy github.com/ipfs-shipyard/nopfs/ipfs v0.13.2-0.20231027223058-cde3b5ba964c/go.mod h1:6EekK/jo+TynwSE/ZOiOJd4eEvRXoavEC3vquKtv4yI= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= -github.com/ipfs/boxo v0.19.0 h1:UbX9FBJQF19ACLqRZOgdEla6jR/sC4H1O+iGE0NToXA= -github.com/ipfs/boxo v0.19.0/go.mod h1:V5gJzbIMwKEXrg3IdvAxIdF7UPgU4RsXmNGS8MQ/0D4= +github.com/ipfs/boxo v0.24.3 h1:gldDPOWdM3Rz0v5LkVLtZu7A7gFNvAlWcmxhCqlHR3c= +github.com/ipfs/boxo v0.24.3/go.mod h1:h0DRzOY1IBFDHp6KNvrJLMFdSXTYID0Zf+q7X05JsNg= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -680,11 +686,10 @@ github.com/ipfs/go-bitswap v0.11.0/go.mod h1:05aE8H3XOU+LXpTedeAS0OZpcO1WFsj5niY github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= github.com/ipfs/go-block-format v0.2.0 h1:ZqrkxBA2ICbDRbK8KJs/u0O3dlp6gmAuuXUJNiW1Ycs= github.com/ipfs/go-block-format v0.2.0/go.mod h1:+jpL11nFx5A/SPpsoBn6Bzkra/zaArfSmsknbPMYgzM= -github.com/ipfs/go-blockservice v0.5.1 h1:9pAtkyKAz/skdHTh0kH8VulzWp+qmSDD0aI17TYP/s0= -github.com/ipfs/go-blockservice v0.5.1/go.mod h1:VpMblFEqG67A/H2sHKAemeH9vlURVavlysbdUI632yk= +github.com/ipfs/go-blockservice v0.5.2 h1:in9Bc+QcXwd1apOVM7Un9t8tixPKdaHQFdLSUM1Xgk8= +github.com/ipfs/go-blockservice v0.5.2/go.mod h1:VpMblFEqG67A/H2sHKAemeH9vlURVavlysbdUI632yk= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= -github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= @@ -707,39 +712,39 @@ github.com/ipfs/go-ds-leveldb v0.5.0 h1:s++MEBbD3ZKc9/8/njrn4flZLnCuY9I79v94gBUN github.com/ipfs/go-ds-leveldb v0.5.0/go.mod h1:d3XG9RUDzQ6V4SHi8+Xgj9j1XuEk1z82lquxrVbml/Q= github.com/ipfs/go-ds-measure v0.2.0 h1:sG4goQe0KDTccHMyT45CY1XyUbxe5VwTKpg2LjApYyQ= github.com/ipfs/go-ds-measure v0.2.0/go.mod h1:SEUD/rE2PwRa4IQEC5FuNAmjJCyYObZr9UvVh8V3JxE= +github.com/ipfs/go-ds-pebble v0.4.0 h1:88lgFAs2ck8jCQ8lMYRBtksEg18r9BlvTxIMnNJkZaQ= +github.com/ipfs/go-ds-pebble v0.4.0/go.mod h1:ZyYU+weIni+4NG/Yjva+cPkU3ghlsU1HA2R/VLHJ9sM= github.com/ipfs/go-fs-lock v0.0.7 h1:6BR3dajORFrFTkb5EpCUFIAypsoxpGpDSVUdFwzgL9U= github.com/ipfs/go-fs-lock v0.0.7/go.mod h1:Js8ka+FNYmgQRLrRXzU3CB/+Csr1BwrRilEcvYrHhhc= -github.com/ipfs/go-ipfs-blockstore v1.3.0 h1:m2EXaWgwTzAfsmt5UdJ7Is6l4gJcaM/A12XwJyvYvMM= -github.com/ipfs/go-ipfs-blockstore v1.3.0/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= +github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7PTTDQNsQ= +github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= -github.com/ipfs/go-ipfs-cmds v0.10.0 h1:ZB4+RgYaH4UARfJY0uLKl5UXgApqnRjKbuCiJVcErYk= -github.com/ipfs/go-ipfs-cmds v0.10.0/go.mod h1:sX5d7jkCft9XLPnkgEfXY0z2UBOB5g6fh/obBS0enJE= +github.com/ipfs/go-ipfs-cmds v0.14.0 h1:sxdurhAHSdQr5VrSNJjc+t92uJObSNq+gRVm/wLZGMM= +github.com/ipfs/go-ipfs-cmds v0.14.0/go.mod h1:zj2jN7bHJ4pDucRmqdq863AQYcsqdxXrfVkr9eqPfvo= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= -github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= -github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0 h1:8lMSJmKogZYNo2jjhUs0izT+dck05pqUw4mWNW9Pw6Y= -github.com/ipfs/go-ipfs-exchange-interface v0.2.0/go.mod h1:z6+RhJuDQbqKguVyslSOuVDhqF9JtTrO3eptSAiW2/Y= +github.com/ipfs/go-ipfs-ds-help v1.1.1 h1:B5UJOH52IbcfS56+Ul+sv8jnIV10lbjLF5eOO0C66Nw= +github.com/ipfs/go-ipfs-ds-help v1.1.1/go.mod h1:75vrVCkSdSFidJscs8n4W+77AtTpCIAdDGAwjitJMIo= +github.com/ipfs/go-ipfs-exchange-interface v0.2.1 h1:jMzo2VhLKSHbVe+mHNzYgs95n0+t0Q69GQ5WhRDZV/s= +github.com/ipfs/go-ipfs-exchange-interface v0.2.1/go.mod h1:MUsYn6rKbG6CTtsDp+lKJPmVt3ZrCViNyH3rfPGsZ2E= github.com/ipfs/go-ipfs-exchange-offline v0.3.0 h1:c/Dg8GDPzixGd0MC8Jh6mjOwU57uYokgWRFidfvEkuA= github.com/ipfs/go-ipfs-exchange-offline v0.3.0/go.mod h1:MOdJ9DChbb5u37M1IcbrRB02e++Z7521fMxqCNRrz9s= github.com/ipfs/go-ipfs-keystore v0.1.0 h1:gfuQUO/cyGZgZIHE6OrJas4OnwuxXCqJG7tI0lrB5Qc= github.com/ipfs/go-ipfs-keystore v0.1.0/go.mod h1:LvLw7Qhnb0RlMOfCzK6OmyWxICip6lQ06CCmdbee75U= github.com/ipfs/go-ipfs-pq v0.0.3 h1:YpoHVJB+jzK15mr/xsWC574tyDLkezVrDNeaalQBsTE= github.com/ipfs/go-ipfs-pq v0.0.3/go.mod h1:btNw5hsHBpRcSSgZtiNm/SLj5gYIZ18AKtv3kERkRb4= -github.com/ipfs/go-ipfs-redirects-file v0.1.1 h1:Io++k0Vf/wK+tfnhEh63Yte1oQK5VGT2hIEYpD0Rzx8= -github.com/ipfs/go-ipfs-redirects-file v0.1.1/go.mod h1:tAwRjCV0RjLTjH8DR/AU7VYvfQECg+lpUy2Mdzv7gyk= +github.com/ipfs/go-ipfs-redirects-file v0.1.2 h1:QCK7VtL91FH17KROVVy5KrzDx2hu68QvB2FTWk08ZQk= +github.com/ipfs/go-ipfs-redirects-file v0.1.2/go.mod h1:yIiTlLcDEM/8lS6T3FlCEXZktPPqSOyuY6dEzVqw7Fw= github.com/ipfs/go-ipfs-routing v0.3.0 h1:9W/W3N+g+y4ZDeffSgqhgo7BsBSJwPMcyssET9OWevc= github.com/ipfs/go-ipfs-routing v0.3.0/go.mod h1:dKqtTFIql7e1zYsEuWLyuOU+E0WJWW8JjbTPLParDWo= github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= github.com/ipfs/go-ipfs-util v0.0.3 h1:2RFdGez6bu2ZlZdI+rWfIdbQb1KudQp3VGwPtdNCmE0= github.com/ipfs/go-ipfs-util v0.0.3/go.mod h1:LHzG1a0Ig4G+iZ26UUOMjHd+lfM84LZCrn17xAKWBvs= -github.com/ipfs/go-ipld-cbor v0.1.0 h1:dx0nS0kILVivGhfWuB6dUpMa/LAwElHPw1yOGYopoYs= -github.com/ipfs/go-ipld-cbor v0.1.0/go.mod h1:U2aYlmVrJr2wsUBU67K4KgepApSZddGRDWBYR0H4sCk= +github.com/ipfs/go-ipld-cbor v0.2.0 h1:VHIW3HVIjcMd8m4ZLZbrYpwjzqlVUfjLM7oK4T5/YF0= +github.com/ipfs/go-ipld-cbor v0.2.0/go.mod h1:Cp8T7w1NKcu4AQJLqK0tWpd1nkgTxEVB5C6kVpLW6/0= github.com/ipfs/go-ipld-format v0.6.0 h1:VEJlA2kQ3LqFSIm5Vu6eIlSxD/Ze90xtc4Meten1F5U= github.com/ipfs/go-ipld-format v0.6.0/go.mod h1:g4QVMTn3marU3qXchwjpKPKgJv+zF+OlaKMyhJ4LHPg= github.com/ipfs/go-ipld-git v0.1.1 h1:TWGnZjS0htmEmlMFEkA3ogrNCqWjIxwr16x1OsdhG+Y= @@ -762,26 +767,27 @@ github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fG github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= -github.com/ipfs/go-unixfs v0.4.5 h1:wj8JhxvV1G6CD7swACwSKYa+NgtdWC1RUit+gFnymDU= -github.com/ipfs/go-unixfs v0.4.5/go.mod h1:BIznJNvt/gEx/ooRMI4Us9K8+qeGO7vx1ohnbk8gjFg= -github.com/ipfs/go-unixfsnode v1.9.0 h1:ubEhQhr22sPAKO2DNsyVBW7YB/zA8Zkif25aBvz8rc8= -github.com/ipfs/go-unixfsnode v1.9.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= -github.com/ipfs/go-verifcid v0.0.2 h1:XPnUv0XmdH+ZIhLGKg6U2vaPaRDXb9urMyNVCE7uvTs= -github.com/ipfs/go-verifcid v0.0.2/go.mod h1:40cD9x1y4OWnFXbLNJYRe7MpNvWlMn3LZAG5Wb4xnPU= -github.com/ipfs/kubo v0.28.0 h1:JmIunSz43G7BSrZZbSWVA5pJZNR1No3pFA8DiY2UOEA= -github.com/ipfs/kubo v0.28.0/go.mod h1:QQ0V6ENy2GQ6zbX9ISUhAayojtb36TTw5e7iT06WPDA= -github.com/ipld/go-car v0.5.0 h1:kcCEa3CvYMs0iE5BzD5sV7O2EwMiCIp3uF8tA6APQT8= -github.com/ipld/go-car v0.5.0/go.mod h1:ppiN5GWpjOZU9PgpAZ9HbZd9ZgSpwPMr48fGRJOWmvE= -github.com/ipld/go-car/v2 v2.13.1 h1:KnlrKvEPEzr5IZHKTXLAEub+tPrzeAFQVRlSQvuxBO4= -github.com/ipld/go-car/v2 v2.13.1/go.mod h1:QkdjjFNGit2GIkpQ953KBwowuoukoM75nP/JI1iDJdo= +github.com/ipfs/go-test v0.0.4 h1:DKT66T6GBB6PsDFLoO56QZPrOmzJkqU1FZH5C9ySkew= +github.com/ipfs/go-test v0.0.4/go.mod h1:qhIM1EluEfElKKM6fnWxGn822/z9knUGM1+I/OAQNKI= +github.com/ipfs/go-unixfsnode v1.9.2 h1:0A12BYs4XOtDPJTMlwmNPlllDfqcc4yie4e919hcUXk= +github.com/ipfs/go-unixfsnode v1.9.2/go.mod h1:v1nuMFHf4QTIhFUdPMvg1nQu7AqDLvIdwyvJ531Ot1U= +github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0zs= +github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= +github.com/ipfs/kubo v0.32.1 h1:nkx5qrkMeJ2f1ET7v3vx7U1ycurM0dC9R7AnsuSrNjk= +github.com/ipfs/kubo v0.32.1/go.mod h1:7fi1IMPgW5fupyMFUjJ4d4zbvkTEwq6tV3T+EQvtF28= +github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= +github.com/ipld/go-car v0.6.2/go.mod h1:oEGXdwp6bmxJCZ+rARSkDliTeYnVzv3++eXajZ+Bmr8= +github.com/ipld/go-car/v2 v2.14.2 h1:9ERr7KXpCC7If0rChZLhYDlyr6Bes6yRKPJnCO3hdHY= +github.com/ipld/go-car/v2 v2.14.2/go.mod h1:0iPB/825lTZLU2zPK5bVTk/R3V2612E1VI279OGSXWA= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.11.0/go.mod h1:+WIAkokurHmZ/KwzDOMUuoeJgaRQktHtEaLglS3ZeV8= -github.com/ipld/go-ipld-prime v0.14.1/go.mod h1:QcE4Y9n/ZZr8Ijg5bGPT0GqYWgZ1704nH0RDcQtgTP0= github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= github.com/ipld/go-ipld-prime v0.21.0/go.mod h1:3RLqy//ERg/y5oShXXdx5YIp50cFGOanyMctpPjsvxQ= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd h1:gMlw/MhNr2Wtp5RwGdsW23cs+yCuj9k2ON7i9MiJlRo= github.com/ipld/go-ipld-prime/storage/bsadapter v0.0.0-20230102063945-1a409dc236dd/go.mod h1:wZ8hH8UxeryOs4kJEJaiui/s00hDSbE37OKsL47g+Sw= +github.com/ipshipyard/p2p-forge v0.0.2 h1:86y9LxGB8sGxYQ/If5sNx+c8C/huSpBUg3UZ1uvtym8= +github.com/ipshipyard/p2p-forge v0.0.2/go.mod h1:taPeh3PDSO8Ual0/N2tIOAUXPV8gZoPF3uPXoUyiq14= github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= @@ -832,13 +838,12 @@ github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6 github.com/klauspost/compress v1.4.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -849,7 +854,6 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -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= @@ -866,6 +870,8 @@ github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2 github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s= +github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ= github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= @@ -876,10 +882,10 @@ github.com/libp2p/go-doh-resolver v0.4.0 h1:gUBa1f1XsPwtpE1du0O+nnZCUqtG7oYi7Bb+ github.com/libp2p/go-doh-resolver v0.4.0/go.mod h1:v1/jwsFusgsWIGX/c6vCRrnJ60x7bhTiq/fs2qt0cAg= github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= github.com/libp2p/go-flow-metrics v0.0.3/go.mod h1:HeoSNUrOJVK1jEpDqVEiUOIXqhbnS27omG0uWU5slZs= -github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= -github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= -github.com/libp2p/go-libp2p v0.33.2 h1:vCdwnFxoGOXMKmaGHlDSnL4bM3fQeW8pgIa9DECnb40= -github.com/libp2p/go-libp2p v0.33.2/go.mod h1:zTeppLuCvUIkT118pFVzA8xzP/p2dJYOMApCkFh0Yww= +github.com/libp2p/go-flow-metrics v0.2.0 h1:EIZzjmeOE6c8Dav0sNv35vhZxATIXWZg6j/C08XmmDw= +github.com/libp2p/go-flow-metrics v0.2.0/go.mod h1:st3qqfu8+pMfh+9Mzqb2GTiwrAGjIPszEjZmtksN8Jc= +github.com/libp2p/go-libp2p v0.37.2 h1:Irh+n9aDPTLt9wJYwtlHu6AhMUipbC1cGoJtOiBqI9c= +github.com/libp2p/go-libp2p v0.37.2/go.mod h1:M8CRRywYkqC6xKHdZ45hmqVckBj5z4mRLIMLWReypz8= github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-core v0.2.4/go.mod h1:STh4fdfa5vDYr0/SzYYeqnt+E6KfEV5VxfIrm0bcI0g= @@ -888,20 +894,20 @@ github.com/libp2p/go-libp2p-gostream v0.6.0 h1:QfAiWeQRce6pqnYfmIVWJFXNdDyfiR/qk github.com/libp2p/go-libp2p-gostream v0.6.0/go.mod h1:Nywu0gYZwfj7Jc91PQvbGU8dIpqbQQkjWgDuOrFaRdA= github.com/libp2p/go-libp2p-http v0.5.0 h1:+x0AbLaUuLBArHubbbNRTsgWz0RjNTy6DJLOxQ3/QBc= github.com/libp2p/go-libp2p-http v0.5.0/go.mod h1:glh87nZ35XCQyFsdzZps6+F4HYI6DctVFY5u1fehwSg= -github.com/libp2p/go-libp2p-kad-dht v0.25.2 h1:FOIk9gHoe4YRWXTu8SY9Z1d0RILol0TrtApsMDPjAVQ= -github.com/libp2p/go-libp2p-kad-dht v0.25.2/go.mod h1:6za56ncRHYXX4Nc2vn8z7CZK0P4QiMcrn77acKLM2Oo= +github.com/libp2p/go-libp2p-kad-dht v0.28.1 h1:DVTfzG8Ybn88g9RycIq47evWCRss5f0Wm8iWtpwyHso= +github.com/libp2p/go-libp2p-kad-dht v0.28.1/go.mod h1:0wHURlSFdAC42+wF7GEmpLoARw8JuS8do2guCtc/Y/w= github.com/libp2p/go-libp2p-kbucket v0.3.1/go.mod h1:oyjT5O7tS9CQurok++ERgc46YLwEpuGoFq9ubvoUOio= -github.com/libp2p/go-libp2p-kbucket v0.6.3 h1:p507271wWzpy2f1XxPzCQG9NiN6R6lHL9GiSErbQQo0= -github.com/libp2p/go-libp2p-kbucket v0.6.3/go.mod h1:RCseT7AH6eJWxxk2ol03xtP9pEHetYSPXOaJnOiD8i0= +github.com/libp2p/go-libp2p-kbucket v0.6.4 h1:OjfiYxU42TKQSB8t8WYd8MKhYhMJeO2If+NiuKfb6iQ= +github.com/libp2p/go-libp2p-kbucket v0.6.4/go.mod h1:jp6w82sczYaBsAypt5ayACcRJi0lgsba7o4TzJKEfWA= github.com/libp2p/go-libp2p-peerstore v0.1.4/go.mod h1:+4BDbDiiKf4PzpANZDAT+knVdLxvqh7hXOujessqdzs= -github.com/libp2p/go-libp2p-pubsub v0.10.0 h1:wS0S5FlISavMaAbxyQn3dxMOe2eegMfswM471RuHJwA= -github.com/libp2p/go-libp2p-pubsub v0.10.0/go.mod h1:1OxbaT/pFRO5h+Dpze8hdHQ63R0ke55XTs6b6NwLLkw= +github.com/libp2p/go-libp2p-pubsub v0.12.0 h1:PENNZjSfk8KYxANRlpipdS7+BfLmOl3L2E/6vSNjbdI= +github.com/libp2p/go-libp2p-pubsub v0.12.0/go.mod h1:Oi0zw9aw8/Y5GC99zt+Ef2gYAl+0nZlwdJonDyOz/sE= github.com/libp2p/go-libp2p-pubsub-router v0.6.0 h1:D30iKdlqDt5ZmLEYhHELCMRj8b4sFAqrUcshIUvVP/s= github.com/libp2p/go-libp2p-pubsub-router v0.6.0/go.mod h1:FY/q0/RBTKsLA7l4vqC2cbRbOvyDotg8PJQ7j8FDudE= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= -github.com/libp2p/go-libp2p-routing-helpers v0.7.3 h1:u1LGzAMVRK9Nqq5aYDVOiq/HaB93U9WWczBzGyAC5ZY= -github.com/libp2p/go-libp2p-routing-helpers v0.7.3/go.mod h1:cN4mJAD/7zfPKXBcs9ze31JGYAZgzdABEm+q/hkswb8= +github.com/libp2p/go-libp2p-routing-helpers v0.7.4 h1:6LqS1Bzn5CfDJ4tzvP9uwh42IB7TJLNFJA6dEeGBv84= +github.com/libp2p/go-libp2p-routing-helpers v0.7.4/go.mod h1:we5WDj9tbolBXOuF1hGOkR+r7Uh1408tQbAKaT5n1LE= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-libp2p-xor v0.1.0 h1:hhQwT4uGrBcuAkUGXADuPltalOdpf9aag9kaYNT2tLA= @@ -968,11 +974,11 @@ github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= -github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= -github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= -github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= +github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= @@ -980,12 +986,14 @@ github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGA github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI= github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= +github.com/mholt/acmez/v2 v2.0.3 h1:CgDBlEwg3QBp6s45tPQmFIBrkRIkBT4rW4orMM6p4sw= +github.com/mholt/acmez/v2 v2.0.3/go.mod h1:pQ1ysaDeGrIMvJ9dfJMk5kJNkn7L2sb3UhyrX6Q91cw= github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4= -github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4= -github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY= +github.com/miekg/dns v1.1.62 h1:cN8OuEF1/x5Rq6Np+h1epln8OiyPWV+lROx9LxcGgIQ= +github.com/miekg/dns v1.1.62/go.mod h1:mvDlcItzm+br7MToIKqkglaGhlFMHJ9DTNNWONWXbNQ= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c h1:bzE/A84HN25pxAuk9Eej1Kz9OUelF97nAc82bDquQI8= github.com/mikioh/tcp v0.0.0-20190314235350-803a9b46060c/go.mod h1:0SQS9kMwD2VsyFEB++InYyBJroV/FRmBgcydeSUcJms= github.com/mikioh/tcpinfo v0.0.0-20190314235526-30a79bb1804b h1:z78hV3sbSMAUoyUMM0I83AUIT6Hu17AWfgjzIbtrYFc= @@ -1003,7 +1011,6 @@ github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dz github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= @@ -1040,11 +1047,11 @@ github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a github.com/multiformats/go-multiaddr v0.1.0/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= github.com/multiformats/go-multiaddr v0.1.1/go.mod h1:aMKBKNEYmzmDmxfX88/vz+J5IU55txyt0p4aiWVohjo= github.com/multiformats/go-multiaddr v0.2.0/go.mod h1:0nO36NvPpyV4QzvTLi/lafl2y95ncPj0vFwVF6k6wJ4= -github.com/multiformats/go-multiaddr v0.12.3 h1:hVBXvPRcKG0w80VinQ23P5t7czWgg65BmIvQKjDydU8= -github.com/multiformats/go-multiaddr v0.12.3/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= +github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= +github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-dns v0.3.0/go.mod h1:mNzQ4eTGDg0ll1N9jKPOUogZPoJ30W8a7zk66FQPpdQ= -github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= -github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= +github.com/multiformats/go-multiaddr-dns v0.4.1 h1:whi/uCLbDS3mSEUMb1MsoT4uzUeZB0N32yzufqS0i5M= +github.com/multiformats/go-multiaddr-dns v0.4.1/go.mod h1:7hfthtB4E4pQwirrz+J0CcDUfbWzTqEzVyYKKIKpgkc= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multiaddr-net v0.1.1/go.mod h1:5JNbcfBOP4dnhoZOv10JJVkJO0pCCEf8mTnipAo2UZQ= @@ -1052,7 +1059,6 @@ github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/g github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= -github.com/multiformats/go-multicodec v0.3.0/go.mod h1:qGGaQmioCDh+TeFOnxrbU0DaIPw8yFgAZgFG0V7p1qQ= github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= @@ -1061,11 +1067,10 @@ github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpK github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= -github.com/multiformats/go-multihash v0.1.0/go.mod h1:RJlXsxt6vHGaia+S8We0ErjhojtKzPP2AH4+kYM7k84= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= -github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= +github.com/multiformats/go-multistream v0.6.0 h1:ZaHKbsL404720283o4c/IHQXiS6gb8qAN5EIJ4PN5EA= +github.com/multiformats/go-multistream v0.6.0/go.mod h1:MOyoG5otO24cHIg8kf9QW2/NozURlkP/rvi2FQJyCPg= github.com/multiformats/go-varint v0.0.1/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= @@ -1089,8 +1094,9 @@ github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJm github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20151028013722-8c68805598ab/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= +github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae h1:FatpGJD2jmJfhZiFDElaC0QhZUDQnxUeAwTGkfAHN3I= github.com/oasisprotocol/curve25519-voi v0.0.0-20220708102147-0a8a51822cae/go.mod h1:hVoHR2EVESiICEMbg137etN/Lx+lSrHPTD39Z/uE+2s= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= @@ -1109,16 +1115,16 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY= -github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM= +github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= +github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= 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.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8= -github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= @@ -1141,8 +1147,8 @@ github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.4.2 h1:zjqfqHjUpPmB3c1GlCvvgsM1G4LkvqQbBDueDOCg/jA= -github.com/openzipkin/zipkin-go v0.4.2/go.mod h1:ZeVkFjuuBiSy13y8vpSDCjMi9GoI3hPpCJSBx/EYFhY= +github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= +github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= github.com/ory/dockertest v3.3.5+incompatible h1:iLLK6SQwIhcbrG783Dghaaa3WPzGc+4Emza6EbVUUGA= github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= @@ -1168,53 +1174,48 @@ github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0 github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= -github.com/pion/datachannel v1.5.5 h1:10ef4kwdjije+M9d7Xm9im2Y3O6A6ccQb0zcqZcJew8= -github.com/pion/datachannel v1.5.5/go.mod h1:iMz+lECmfdCMqFRhXhcA/219B0SQlbpoR2V118yimL0= +github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA= +github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE= github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/dtls/v2 v2.2.8 h1:BUroldfiIbV9jSnC6cKOMnyiORRWrWWpV11JUyEu5OA= -github.com/pion/dtls/v2 v2.2.8/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= -github.com/pion/ice/v2 v2.3.11 h1:rZjVmUwyT55cmN8ySMpL7rsS8KYsJERsrxJLLxpKhdw= -github.com/pion/ice/v2 v2.3.11/go.mod h1:hPcLC3kxMa+JGRzMHqQzjoSj3xtE9F+eoncmXLlCL4E= -github.com/pion/interceptor v0.1.25 h1:pwY9r7P6ToQ3+IF0bajN0xmk/fNw/suTgaTdlwTDmhc= -github.com/pion/interceptor v0.1.25/go.mod h1:wkbPYAak5zKsfpVDYMtEfWEy8D4zL+rpxCxPImLOg3Y= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.36 h1:SopeXiVbbcooUg2EIR8sq4b13RQ8gzrkkldOVg+bBsc= +github.com/pion/ice/v2 v2.3.36/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= +github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI= +github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y= github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= -github.com/pion/mdns v0.0.8/go.mod h1:hYE72WX8WDveIhg7fmXgMKivD3Puklk0Ymzog0lSyaI= -github.com/pion/mdns v0.0.9 h1:7Ue5KZsqq8EuqStnpPWV33vYYEH0+skdDN5L7EiEsI4= -github.com/pion/mdns v0.0.9/go.mod h1:2JA5exfxwzXiCihmxpTKgFUpiQws2MnipoPK09vecIc= +github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= +github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk= github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= -github.com/pion/rtcp v1.2.10/go.mod h1:ztfEwXZNLGyF1oQDttz/ZKIBaeeg/oWbRYqzBM9TL1I= github.com/pion/rtcp v1.2.12/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= -github.com/pion/rtcp v1.2.13 h1:+EQijuisKwm/8VBs8nWllr0bIndR7Lf7cZG200mpbNo= -github.com/pion/rtcp v1.2.13/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= -github.com/pion/rtp v1.8.2/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/rtp v1.8.3 h1:VEHxqzSVQxCkKDSHro5/4IUUG1ea+MFdqR2R3xSpNU8= +github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= +github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= github.com/pion/rtp v1.8.3/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= -github.com/pion/sctp v1.8.5/go.mod h1:SUFFfDpViyKejTAdwD1d/HQsCu+V/40cCs2nZIvC3s0= -github.com/pion/sctp v1.8.8/go.mod h1:igF9nZBrjh5AtmKc7U30jXltsFHicFCXSmWA2GWRaWs= -github.com/pion/sctp v1.8.9 h1:TP5ZVxV5J7rz7uZmbyvnUvsn7EJ2x/5q9uhsTtXbI3g= -github.com/pion/sctp v1.8.9/go.mod h1:cMLT45jqw3+jiJCrtHVwfQLnfR0MGZ4rgOJwUOIqLkI= -github.com/pion/sdp/v3 v3.0.6 h1:WuDLhtuFUUVpTfus9ILC4HRyHsW6TdugjEX/QY9OiUw= -github.com/pion/sdp/v3 v3.0.6/go.mod h1:iiFWFpQO8Fy3S5ldclBkpXqmWy02ns78NOKoLLL0YQw= -github.com/pion/srtp/v2 v2.0.18 h1:vKpAXfawO9RtTRKZJbG4y0v1b11NZxQnxRl85kGuUlo= -github.com/pion/srtp/v2 v2.0.18/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk= +github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.33 h1:dSE4wX6uTJBcNm8+YlMg7lw1wqyKHggsP5uKbdj+NZw= +github.com/pion/sctp v1.8.33/go.mod h1:beTnqSzewI53KWoG3nqB282oDMGrhNxBdb+JZnkCwRM= +github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= +github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= +github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= +github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= -github.com/pion/transport v0.14.1 h1:XSM6olwW+o8J4SCmOBb/BpwZypkHeyM0PGFCxNQBr40= -github.com/pion/transport v0.14.1/go.mod h1:4tGmbk00NeYA3rUa9+n+dzCCoKkcy3YlYb99Jn2fNnI= github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= -github.com/pion/transport/v2 v2.2.2/go.mod h1:OJg3ojoBJopjEeECq2yJdXH9YVrUJ1uQ++NjXLOUorc= github.com/pion/transport/v2 v2.2.3/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v2 v2.2.4 h1:41JJK6DZQYSeVLxILA2+F4ZkKb4Xd/tFJZRFZQ9QAlo= github.com/pion/transport/v2 v2.2.4/go.mod h1:q2U/tf9FEfnSBGSW6w5Qp5PFWRLRj3NjLhCCgpRK4p0= -github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pion/transport/v3 v3.0.7 h1:iRbMH05BzSNwhILHoBoAPxoB9xQgOaJk+591KC9P1o0= +github.com/pion/transport/v3 v3.0.7/go.mod h1:YleKiTZ4vqNxVwh77Z0zytYi7rXHl7j6uPLGhhz9rwo= github.com/pion/turn/v2 v2.1.3/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/turn/v2 v2.1.4 h1:2xn8rduI5W6sCZQkEnIUDAkrBQNl2eYIBCHMZ3QMmP8= -github.com/pion/turn/v2 v2.1.4/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= -github.com/pion/webrtc/v3 v3.2.23 h1:GbqEuxBbVLFhXk0GwxKAoaIJYiEa9TyoZPEZC+2HZxM= -github.com/pion/webrtc/v3 v3.2.23/go.mod h1:1CaT2fcZzZ6VZA+O1i9yK2DU4EOcXVvSbWG9pr5jefs= +github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= +github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/webrtc/v3 v3.3.4 h1:v2heQVnXTSqNRXcaFQVOhIOYkLMxOu1iJG8uy1djvkk= +github.com/pion/webrtc/v3 v3.3.4/go.mod h1:liNa+E1iwyzyXqNUwvoMRNQ10x8h8FOeJKL8RkIbamE= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -1229,8 +1230,8 @@ github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXx github.com/polydawn/refmt v0.89.0 h1:ADJTApkvkeBZsN0tBTx8QjpD9JkmxbKp0cxfr9qszm4= github.com/polydawn/refmt v0.89.0/go.mod h1:/zvteZs/GwLtCgZ4BL6CBsk9IKIlexP43ObX9AxTqTw= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/pressly/goose/v3 v3.21.1 h1:5SSAKKWej8LVVzNLuT6KIvP1eFDuPvxa+B6H0w78buQ= -github.com/pressly/goose/v3 v3.21.1/go.mod h1:sqthmzV8PitchEkjecFJII//l43dLOCzfWh8pHEe+vE= +github.com/pressly/goose/v3 v3.23.0 h1:57hqKos8izGek4v6D5+OXBa+Y4Rq8MU//+MmnevdpVA= +github.com/pressly/goose/v3 v3.23.0/go.mod h1:rpx+D9GX/+stXmzKa+uh1DkjPnNVMdiOCV9iLdle4N8= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= @@ -1241,8 +1242,8 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= -github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -1262,8 +1263,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9 github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= -github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -1281,12 +1282,12 @@ github.com/prometheus/statsd_exporter v0.22.8/go.mod h1:/DzwbTEaFTE0Ojz5PqcSk6+P github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= -github.com/quic-go/qpack v0.4.0 h1:Cr9BXA1sQS2SmDUWjSofMPNKmvF6IiIfDRmgU0w1ZCo= -github.com/quic-go/qpack v0.4.0/go.mod h1:UZVnYIfi5GRk+zI9UMaCPsmZ2xKJP7XBUvVyT1Knj9A= -github.com/quic-go/quic-go v0.42.0 h1:uSfdap0eveIl8KXnipv9K7nlwZ5IqLlYOpJ58u5utpM= -github.com/quic-go/quic-go v0.42.0/go.mod h1:132kz4kL3F9vxhW3CtQJLDVwcFe5wdWeJXXijhsO57M= -github.com/quic-go/webtransport-go v0.6.0 h1:CvNsKqc4W2HljHJnoT+rMmbRJybShZ0YPFDD3NxaZLY= -github.com/quic-go/webtransport-go v0.6.0/go.mod h1:9KjU4AEBqEQidGHNDkZrb8CAa1abRaosM2yGOyiikEc= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.48.2 h1:wsKXZPeGWpMpCGSWqOcqpW2wZYic/8T3aqiOID0/KWE= +github.com/quic-go/quic-go v0.48.2/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= +github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg= +github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw= github.com/raulk/go-watchdog v1.3.0 h1:oUmdlHxdkXRJlwfG0O9omj8ukerm8MEQavSiDTEtBsk= github.com/raulk/go-watchdog v1.3.0/go.mod h1:fIvOnLbF0b0ZwkB9YU4mOW9Did//4vPZtDqv66NfsMU= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -1295,20 +1296,20 @@ github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqn github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= -github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= -github.com/rs/cors v1.11.0 h1:0B9GE/r9Bc2UxRMMtymBkHTenPkHDv0CW4Y98GBY+po= -github.com/rs/cors v1.11.0/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= @@ -1324,18 +1325,17 @@ github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6ke github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= -github.com/samber/lo v1.39.0 h1:4gTz1wUhNYLhFSKl6O+8peW0v2F4BCY034GRpU9WnuA= -github.com/samber/lo v1.39.0/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= +github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0= github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= -github.com/sethvargo/go-retry v0.2.4 h1:T+jHEQy/zKJf5s95UkguisicE0zuF9y7+/vgz08Ocec= -github.com/sethvargo/go-retry v0.2.4/go.mod h1:1afjQuvh7s4gflMObvjLPaWgluLLyhA1wmVZ6KLpICw= +github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE= +github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas= github.com/shirou/gopsutil v2.20.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= @@ -1441,12 +1441,10 @@ github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3 github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= -github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a h1:1ur3QoCqvE5fl+nylMaIr9PVV1w343YRDtsy+Rwu7XI= -github.com/syndtr/goleveldb v1.0.1-0.20220614013038-64ee5596c38a/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tj/assert v0.0.3 h1:Df/BlaZ20mq6kuai7f5z2TvPFiwC3xaWJSDQNiIS3Rk= -github.com/tj/assert v0.0.3/go.mod h1:Ne6X72Q+TB1AteidzQncjw9PabbMp4PBMZ1k+vd1Pvk= github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= @@ -1483,8 +1481,6 @@ github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMI github.com/vocdoni/storage-proofs-eth-go v0.1.6 h1:mF6VNGudgCjjgjxs5Z2GGMM2tS79+xFBWcr7BnPuhAY= github.com/vocdoni/storage-proofs-eth-go v0.1.6/go.mod h1:aoD9pKg8kDFQ5I6b3obGPTwjC+DsaW2h4wt2UQEjQrg= github.com/wangjia184/sortedset v0.0.0-20160527075905-f5d03557ba30/go.mod h1:YkocrP2K2tcw938x9gCOmT5G5eCD6jsTz0SZuyAqwIE= -github.com/warpfork/go-testmark v0.3.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= -github.com/warpfork/go-testmark v0.9.0/go.mod h1:jhEf8FVxd+F17juRubpmut64NEG6I2rgkUhlcqqXwE0= github.com/warpfork/go-testmark v0.12.1 h1:rMgCpJfwy1sJ50x0M0NgyphxYYPMOODIJHhsXyEHU0s= github.com/warpfork/go-testmark v0.12.1/go.mod h1:kHwy7wfvGSPh1rQJYKayD4AbtNaeyZdcGi9tNJTaa5Y= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= @@ -1496,8 +1492,8 @@ github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc h1:BCPnHtcboa github.com/whyrusleeping/base32 v0.0.0-20170828182744-c30ac30633cc/go.mod h1:r45hJU7yEoA81k6MWNhpMj/kms0n14dkzkxYHoB96UM= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 h1:5HZfQkwe0mIfyDmc1Em5GqlNRzcdtlv4HTNmdpt7XH0= github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11/go.mod h1:Wlo/SzPmxVp6vXpGt/zaXhHH0fn4IxgqZc82aKg6bpQ= -github.com/whyrusleeping/cbor-gen v0.1.0 h1:Jneeq3V5enErVcuL0NKEbD1Gi+iOvEeFhXOV1S1Fc6g= -github.com/whyrusleeping/cbor-gen v0.1.0/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= +github.com/whyrusleeping/cbor-gen v0.1.2 h1:WQFlrPhpcQl+M2/3dP5cvlTLWPVsL6LGBb9jJt6l/cA= +github.com/whyrusleeping/cbor-gen v0.1.2/go.mod h1:pM99HXyEbSQHcosHc0iW7YFmwnscr+t9Te4ibko05so= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP9WYv2nzyawpKMOCl+Z/jW7djv2/J50lj9E= github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1 h1:EKhdznlJHPMoKr0XTrX+IlJs1LH3lyx2nfr1dOlZ79k= @@ -1508,6 +1504,9 @@ github.com/whyrusleeping/go-sysinfo v0.0.0-20190219211824-4a357d4b90b1/go.mod h1 github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7 h1:E9S12nwJwEOXe2d6gT6qxdvqMnNq+VnSsKPgm2ZZNds= github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/wlynxg/anet v0.0.3/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= +github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= +github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= @@ -1531,6 +1530,12 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= github.com/yusufpapurcu/wmi v1.2.2/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY= +github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/blake3 v0.2.4 h1:KYQPkhpRtcqh0ssGYcKLG1JYvddkEA8QwCM/yBqhaZI= +github.com/zeebo/blake3 v0.2.4/go.mod h1:7eeQ6d2iXWRGF6npfaxl2CU+xy2Fjo2gxeyZGCRUjcE= +github.com/zeebo/pcg v1.0.1 h1:lyqfGeWiv4ahac6ttHs+I5hwtH/+1mrhlCtVNQM2kHo= +github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5 h1:qxen9oVGzDdIRP6ejyAJc760RwW4SnVDiTYTzwnXuxo= go.etcd.io/bbolt v1.4.0-alpha.0.0.20240404170359-43604f3112c5/go.mod h1:eW0HG9/oHQhvRCvb1/pIXW4cOvtDqeQK+XSi3TnwaXY= @@ -1549,28 +1554,28 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= -go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= -go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0 h1:tIqheXEFWAZ7O8A7m+J0aPTmpJN3YQ7qetUAdkkkKpk= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.21.0/go.mod h1:nUeKExfxAQVbiVFn32YXpXZZHZ61Cc3s3Rn1pDBGAb0= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0 h1:VhlEQAPp9R1ktYfrPk5SOryw1e9LDDTZCbIPFrho0ec= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.21.0/go.mod h1:kB3ufRbfU+CQ4MlUcqtW8Z7YEOBeK2DJ6CmR5rYYF3E= -go.opentelemetry.io/otel/exporters/zipkin v1.21.0 h1:D+Gv6lSfrFBWmQYyxKjDd0Zuld9SRXpIrEsKZvE4DO4= -go.opentelemetry.io/otel/exporters/zipkin v1.21.0/go.mod h1:83oMKR6DzmHisFOW3I+yIMGZUTjxiWaiBI8M8+TU5zE= -go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= -go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= -go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0 h1:FFeLy03iVTXP6ffeN2iXrxfGsZGCjVx0/4KlizjyBwU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.31.0/go.mod h1:TMu73/k1CP8nBUpDLc71Wj/Kf7ZS9FK5b53VapRsP9o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0 h1:UGZ1QwZWY67Z6BmckTU+9Rxn04m2bD3gD6Mk0OIOCPk= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.31.0/go.mod h1:fcwWuDuaObkkChiDlhEpSq9+X1C0omv+s5mBtToAQ64= +go.opentelemetry.io/otel/exporters/zipkin v1.31.0 h1:CgucL0tj3717DJnni7HVVB2wExzi8c2zJNEA2BhLMvI= +go.opentelemetry.io/otel/exporters/zipkin v1.31.0/go.mod h1:rfzOVNiSwIcWtEC2J8epwG26fiaXlYvLySJ7bwsrtAE= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1578,15 +1583,15 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= -go.uber.org/dig v1.17.1 h1:Tga8Lz8PcYNsWsyHMZ1Vm0OQOUaJNDyvPImgbAu9YSc= -go.uber.org/dig v1.17.1/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= -go.uber.org/fx v1.20.1 h1:zVwVQGS8zYvhh9Xxcu4w1M6ESyeMzebzj2NbSayZ4Mk= -go.uber.org/fx v1.20.1/go.mod h1:iSYNbHf2y55acNCwCXKx7LbWb5WG1Bnue5RDXz1OREg= +go.uber.org/dig v1.18.0 h1:imUL1UiY0Mg4bqbFfsRQO5G4CGRBec/ZujWTvSVp3pw= +go.uber.org/dig v1.18.0/go.mod h1:Us0rSJiThwCv2GteUN0Q7OKvU7n5J4dxZ9JKUXozFdE= +go.uber.org/fx v1.23.0 h1:lIr/gYWQGfTwGcSXWXu4vP5Ws6iqnNEIY+F/aFzCKTg= +go.uber.org/fx v1.23.0/go.mod h1:o/D9n+2mLP6v1EG+qsdT1O8wKopYAsqZasju97SDFCU= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= -go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= -go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= +go.uber.org/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -1602,8 +1607,8 @@ go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= -go.vocdoni.io/proto v1.15.8 h1:I5HVHffQwXyp0jootnCVj83+PoJ8L703RJ2CFSPTa2Q= -go.vocdoni.io/proto v1.15.8/go.mod h1:oi/WtiBFJ6QwNDv2aUQYwOnUKzYuS/fBqXF8xDNwcGo= +go.vocdoni.io/proto v1.15.10-0.20240903073233-86144b1e2165 h1:7r0RaKfYyGCVh1qeS2795jOk7WnpP9CI0IJOB/lxFVk= +go.vocdoni.io/proto v1.15.10-0.20240903073233-86144b1e2165/go.mod h1:oi/WtiBFJ6QwNDv2aUQYwOnUKzYuS/fBqXF8xDNwcGo= go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= go4.org v0.0.0-20200411211856-f5505b9728dd/go.mod h1:CIiUVy99QCPfoE13bO4EZaz5GZMZXMSBGhxRdsvzbkg= go4.org v0.0.0-20230225012048-214862532bf5 h1:nifaUDeh+rPaBCMPMQHZmvJf+QdpLFnuQPwx+LxVmtc= @@ -1635,12 +1640,10 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= -golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= -golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= +golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1655,8 +1658,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa h1:ELnwvuAXPNtPk1TJRuGkI9fDTwym6AYBu0qzT8AcHdI= -golang.org/x/exp v0.0.0-20240808152545-0cdaa3abc0fa/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -1684,8 +1687,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.20.0 h1:utOm6MM3R3dnawAiJgn0y+xvuYRsm1RKM/4giyfDgV0= -golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 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= @@ -1743,17 +1746,14 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= -golang.org/x/net v0.13.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= -golang.org/x/net v0.28.0 h1:a9JDOJc5GMUJ0+UDqmLT86WiEy7iWyIhz8gz8E4e5hE= -golang.org/x/net v0.28.0/go.mod h1:yqtgsTWOOnlGLG9GFRrK3++bGOUEkNBoHZc8MEDWPNg= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= +golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1763,8 +1763,8 @@ golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.22.0 h1:BzDx2FehcG7jJwgWLELCdmLuxk2i+x9UDpSiss2u0ZA= -golang.org/x/oauth2 v0.22.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.23.0 h1:PbgcYx2W7i4LvjJWEbf0ngHV6qJYr86PkAV3bXdLEbs= +golang.org/x/oauth2 v0.23.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= 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= @@ -1780,8 +1780,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= +golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1872,28 +1872,24 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/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.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= -golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= +golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= -golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1904,15 +1900,12 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= -golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= +golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -1981,15 +1974,15 @@ golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24= -golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 h1:LLhsEBxRTBLuKlQxFBYUOU8xyFgXv6cOTp2HASDlsDk= -golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.6.0/go.mod h1:9mxDZsDKxgMAuccQkewq682L+0eCu4dCN2yonUJTCLU= @@ -2062,10 +2055,10 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= -google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= +google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.16.0/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= @@ -2086,8 +2079,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= -google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= 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= @@ -2103,8 +2096,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ 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.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= +google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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= @@ -2123,8 +2116,6 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYs gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= -gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/src-d/go-cli.v0 v0.0.0-20181105080154-d492247bbc0d/go.mod h1:z+K8VcOYVYcSwSjGebuDL6176A1XskgbtNl64NSg+n8= gopkg.in/src-d/go-log.v1 v1.0.1/go.mod h1:GN34hKP0g305ysm2/hctJ0Y8nWP3zxXXJ8GFabTyABE= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= @@ -2156,25 +2147,24 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= -lukechampine.com/blake3 v1.1.6/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6 h1:5D53IMaUuA5InSeMu9eJtlQXS2NxAhyWQvkKEgXZhHI= modernc.org/gc/v3 v3.0.0-20240107210532-573471604cb6/go.mod h1:Qz0X07sNOR1jWYCrJMEnbW/X55x206Q7Vt4mz6/wHp4= -modernc.org/libc v1.41.0 h1:g9YAc6BkKlgORsUWj+JwqoB1wU3o4DE3bM3yvA3k+Gk= -modernc.org/libc v1.41.0/go.mod h1:w0eszPsiXoOnoMJgrXjglgLuDy/bt5RR4y3QzUUeodY= +modernc.org/libc v1.55.3 h1:AzcW1mhlPNrRtjS5sS+eW2ISCgSOLLNyFzRh/V3Qj/U= +modernc.org/libc v1.55.3/go.mod h1:qFXepLhz+JjFThQ4kzwzOjA/y/artDeg+pcYnY+Q83w= modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4= modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo= -modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E= -modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E= -modernc.org/sqlite v1.29.6 h1:0lOXGrycJPptfHDuohfYgNqoe4hu+gYuN/pKgY5XjS4= -modernc.org/sqlite v1.29.6/go.mod h1:S02dvcmm7TnTRvGhv8IGYyLnIt7AS2KPaB1F/71p75U= +modernc.org/memory v1.8.0 h1:IqGTL6eFMaDZZhEWwcREgeMXYwmW83LYW8cROZYkg+E= +modernc.org/memory v1.8.0/go.mod h1:XPZ936zp5OMKGWPqbD3JShgd/ZoQ7899TUuQqxY+peU= +modernc.org/sqlite v1.34.1 h1:u3Yi6M0N8t9yKRDwhXcyp1eS5/ErhPTBggxWFuR6Hfk= +modernc.org/sqlite v1.34.1/go.mod h1:pXV2xHxhzXZsgT/RtTFAPY6JJDEvOTcTdwADQCCWD4k= modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA= modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= -pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= -pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= +pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= +pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= diff --git a/test/api_test.go b/test/api_test.go index 80e4f3699..072e217d0 100644 --- a/test/api_test.go +++ b/test/api_test.go @@ -461,6 +461,41 @@ func TestAPIAccountTokentxs(t *testing.T) { qt.Assert(t, gotAcct1.Balance, qt.Equals, initBalance+amountAcc2toAcct1-amountAcc1toAcct2-uint64(txBasePrice)) } +func TestAPIBlocks(t *testing.T) { + server := testcommon.APIserver{} + server.Start(t, + api.ChainHandler, + api.CensusHandler, + api.VoteHandler, + api.AccountHandler, + api.ElectionHandler, + api.WalletHandler, + ) + token1 := uuid.New() + c := testutil.NewTestHTTPclient(t, server.ListenAddr, &token1) + + // Block 1 + server.VochainAPP.AdvanceTestBlock() + waitUntilHeight(t, c, 1) + + // create a new account + initBalance := uint64(80) + _ = createAccount(t, c, server, initBalance) + + // Block 2 + server.VochainAPP.AdvanceTestBlock() + waitUntilHeight(t, c, 2) + + // check the txCount + resp, code := c.Request("GET", nil, "chain", "blocks", "1") + qt.Assert(t, code, qt.Equals, 200, qt.Commentf("response: %s", resp)) + + block := api.Block{} + err := json.Unmarshal(resp, &block) + qt.Assert(t, err, qt.IsNil) + qt.Assert(t, block.TxCount, qt.Equals, int64(1)) +} + func runAPIElectionCostWithParams(t *testing.T, electionParams electionprice.ElectionParameters, startBlock uint32, initialBalance, @@ -667,7 +702,15 @@ func createAccount(t testing.TB, c *testutil.TestHTTPclient, metaData, err := json.Marshal(meta) qt.Assert(t, err, qt.IsNil) - fp, err := vochain.GenerateFaucetPackage(server.Account, signer.Address(), initialBalance) + // get the txCost for the create account transacction + data, statusCode := c.Request("GET", nil, "chain", "transactions", "cost") + qt.Assert(t, statusCode, qt.Equals, 200) + var txCosts api.Transaction + qt.Assert(t, json.Unmarshal(data, &txCosts), qt.IsNil) + txCost := txCosts.Costs[genesis.TxTypeToCostName(models.TxType_CREATE_ACCOUNT)] + + // add the tx cost to the initialBalance for the faucet package + fp, err := vochain.GenerateFaucetPackage(server.Account, signer.Address(), initialBalance+txCost) qt.Assert(t, err, qt.IsNil) // transaction diff --git a/test/testcommon/testutil/util.go b/test/testcommon/testutil/util.go index 629d74e11..83e2d4b68 100644 --- a/test/testcommon/testutil/util.go +++ b/test/testcommon/testutil/util.go @@ -82,7 +82,7 @@ func (r *Random) RandomInZKField() []byte { panic(err) } b[31] &= 0b00111111 - if iden3cryptoutils.CheckBigIntInField(arbo.BytesToBigInt(b)) { + if iden3cryptoutils.CheckBigIntInField(arbo.BytesLEToBigInt(b)) { return b } } diff --git a/tree/arbo/addbatch_test.go b/tree/arbo/addbatch_test.go index 0c4cab15f..33ba97dae 100644 --- a/tree/arbo/addbatch_test.go +++ b/tree/arbo/addbatch_test.go @@ -56,8 +56,8 @@ func testInit(c *qt.C, n int) (*Tree, *Tree) { // add the initial leafs to fill a bit the trees before calling the // AddBatch method for i := 0; i < n; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) if err := tree1.Add(k, v); err != nil { c.Fatal(err) } @@ -80,8 +80,8 @@ func TestAddBatchTreeEmpty(t *testing.T) { bLen := 32 var keys, values [][]byte for i := 0; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) keys = append(keys, k) values = append(values, v) } @@ -128,8 +128,8 @@ func TestAddBatchTreeEmptyNotPowerOf2(t *testing.T) { bLen := 32 for i := 0; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) if err := tree.Add(k, v); err != nil { t.Fatal(err) } @@ -144,8 +144,8 @@ func TestAddBatchTreeEmptyNotPowerOf2(t *testing.T) { var keys, values [][]byte for i := 0; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) keys = append(keys, k) values = append(values, v) } @@ -277,17 +277,17 @@ func TestAddBatchTestVector2(t *testing.T) { bLen := tree1.HashFunction().Len() var keys, values [][]byte // 1 - keys = append(keys, BigIntToBytes(bLen, big.NewInt(int64(1)))) - values = append(values, BigIntToBytes(bLen, big.NewInt(int64(1)))) + keys = append(keys, BigIntToBytesLE(bLen, big.NewInt(int64(1)))) + values = append(values, BigIntToBytesLE(bLen, big.NewInt(int64(1)))) // 2 - keys = append(keys, BigIntToBytes(bLen, big.NewInt(int64(2)))) - values = append(values, BigIntToBytes(bLen, big.NewInt(int64(2)))) + keys = append(keys, BigIntToBytesLE(bLen, big.NewInt(int64(2)))) + values = append(values, BigIntToBytesLE(bLen, big.NewInt(int64(2)))) // 3 - keys = append(keys, BigIntToBytes(bLen, big.NewInt(int64(3)))) - values = append(values, BigIntToBytes(bLen, big.NewInt(int64(3)))) + keys = append(keys, BigIntToBytesLE(bLen, big.NewInt(int64(3)))) + values = append(values, BigIntToBytesLE(bLen, big.NewInt(int64(3)))) // 5 - keys = append(keys, BigIntToBytes(bLen, big.NewInt(int64(5)))) - values = append(values, BigIntToBytes(bLen, big.NewInt(int64(5)))) + keys = append(keys, BigIntToBytesLE(bLen, big.NewInt(int64(5)))) + values = append(values, BigIntToBytesLE(bLen, big.NewInt(int64(5)))) for i := 0; i < len(keys); i++ { if err := tree1.Add(keys[i], values[i]); err != nil { @@ -324,17 +324,17 @@ func TestAddBatchTestVector3(t *testing.T) { bLen := tree1.HashFunction().Len() var keys, values [][]byte // 0 - keys = append(keys, BigIntToBytes(bLen, big.NewInt(int64(0)))) - values = append(values, BigIntToBytes(bLen, big.NewInt(int64(0)))) + keys = append(keys, BigIntToBytesLE(bLen, big.NewInt(int64(0)))) + values = append(values, BigIntToBytesLE(bLen, big.NewInt(int64(0)))) // 3 - keys = append(keys, BigIntToBytes(bLen, big.NewInt(int64(3)))) - values = append(values, BigIntToBytes(bLen, big.NewInt(int64(3)))) + keys = append(keys, BigIntToBytesLE(bLen, big.NewInt(int64(3)))) + values = append(values, BigIntToBytesLE(bLen, big.NewInt(int64(3)))) // 7 - keys = append(keys, BigIntToBytes(bLen, big.NewInt(int64(7)))) - values = append(values, BigIntToBytes(bLen, big.NewInt(int64(7)))) + keys = append(keys, BigIntToBytesLE(bLen, big.NewInt(int64(7)))) + values = append(values, BigIntToBytesLE(bLen, big.NewInt(int64(7)))) // 135 - keys = append(keys, BigIntToBytes(bLen, big.NewInt(int64(135)))) - values = append(values, BigIntToBytes(bLen, big.NewInt(int64(135)))) + keys = append(keys, BigIntToBytesLE(bLen, big.NewInt(int64(135)))) + values = append(values, BigIntToBytesLE(bLen, big.NewInt(int64(135)))) for i := 0; i < len(keys); i++ { if err := tree1.Add(keys[i], values[i]); err != nil { @@ -403,8 +403,8 @@ func TestAddBatchTreeNotEmptyFewLeafs(t *testing.T) { bLen := tree1.HashFunction().Len() start := time.Now() for i := initialNLeafs; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) if err := tree1.Add(k, v); err != nil { t.Fatal(err) } @@ -414,8 +414,8 @@ func TestAddBatchTreeNotEmptyFewLeafs(t *testing.T) { // prepare the key-values to be added var keys, values [][]byte for i := initialNLeafs; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) keys = append(keys, k) values = append(values, v) } @@ -446,8 +446,8 @@ func TestAddBatchTreeNotEmptyEnoughLeafs(t *testing.T) { bLen := tree1.HashFunction().Len() start := time.Now() for i := initialNLeafs; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) if err := tree1.Add(k, v); err != nil { t.Fatal(err) } @@ -457,8 +457,8 @@ func TestAddBatchTreeNotEmptyEnoughLeafs(t *testing.T) { // prepare the key-values to be added var keys, values [][]byte for i := initialNLeafs; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) keys = append(keys, k) values = append(values, v) } @@ -488,15 +488,15 @@ func TestAddBatchTreeEmptyRepeatedLeafs(t *testing.T) { // prepare the key-values to be added var keys, values [][]byte for i := 0; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) keys = append(keys, k) values = append(values, v) } // add repeated key-values for i := 0; i < nRepeatedKeys; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) keys = append(keys, k) values = append(values, v) } @@ -527,8 +527,8 @@ func TestAddBatchTreeNotEmptyFewLeafsRepeatedLeafs(t *testing.T) { // prepare the key-values to be added var keys, values [][]byte for i := 0; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) keys = append(keys, k) values = append(values, v) } @@ -554,8 +554,8 @@ func TestSplitInBuckets(t *testing.T) { nLeafs := 16 kvs := make([]kv, nLeafs) for i := 0; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) keyPath := make([]byte, 32) copy(keyPath, k) kvs[i].pos = i @@ -660,8 +660,8 @@ func TestAddBatchTreeNotEmpty(t *testing.T) { bLen := tree1.HashFunction().Len() start := time.Now() for i := initialNLeafs; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) if err := tree1.Add(k, v); err != nil { t.Fatal(err) } @@ -671,8 +671,8 @@ func TestAddBatchTreeNotEmpty(t *testing.T) { // prepare the key-values to be added var keys, values [][]byte for i := initialNLeafs; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) keys = append(keys, k) values = append(values, v) } @@ -702,8 +702,8 @@ func TestAddBatchNotEmptyUnbalanced(t *testing.T) { start := time.Now() for i := initialNLeafs; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) if err := tree1.Add(k, v); err != nil { t.Fatal(err) } @@ -722,8 +722,8 @@ func TestAddBatchNotEmptyUnbalanced(t *testing.T) { // add the initial leafs to fill a bit the tree before calling the // AddBatch method for i := 0; i < initialNLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) // use only the keys of one bucket, store the not used ones for // later if i%4 != 0 { @@ -737,8 +737,8 @@ func TestAddBatchNotEmptyUnbalanced(t *testing.T) { } for i := initialNLeafs; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) keys = append(keys, k) values = append(values, v) } @@ -950,7 +950,7 @@ func TestAddKeysWithEmptyValues(t *testing.T) { bLen := 32 var keys, values [][]byte for i := 0; i < nLeafs; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) v := []byte{} keys = append(keys, k) values = append(values, v) diff --git a/tree/arbo/circomproofs.go b/tree/arbo/circomproofs.go index e16419078..94a4aacbb 100644 --- a/tree/arbo/circomproofs.go +++ b/tree/arbo/circomproofs.go @@ -22,17 +22,17 @@ type CircomVerifierProof struct { func (cvp CircomVerifierProof) MarshalJSON() ([]byte, error) { m := make(map[string]any) - m["root"] = BytesToBigInt(cvp.Root).String() + m["root"] = BytesLEToBigInt(cvp.Root).String() m["siblings"] = siblingsToStringArray(cvp.Siblings) - m["oldKey"] = BytesToBigInt(cvp.OldKey).String() - m["oldValue"] = BytesToBigInt(cvp.OldValue).String() + m["oldKey"] = BytesLEToBigInt(cvp.OldKey).String() + m["oldValue"] = BytesLEToBigInt(cvp.OldValue).String() if cvp.IsOld0 { m["isOld0"] = "1" } else { m["isOld0"] = "0" } - m["key"] = BytesToBigInt(cvp.Key).String() - m["value"] = BytesToBigInt(cvp.Value).String() + m["key"] = BytesLEToBigInt(cvp.Key).String() + m["value"] = BytesLEToBigInt(cvp.Value).String() m["fnc"] = cvp.Fnc return json.Marshal(m) @@ -41,7 +41,7 @@ func (cvp CircomVerifierProof) MarshalJSON() ([]byte, error) { func siblingsToStringArray(s [][]byte) []string { var r []string for i := 0; i < len(s); i++ { - r = append(r, BytesToBigInt(s[i]).String()) + r = append(r, BytesLEToBigInt(s[i]).String()) } return r } diff --git a/tree/arbo/circomproofs_test.go b/tree/arbo/circomproofs_test.go index a75eba83f..47e69583e 100644 --- a/tree/arbo/circomproofs_test.go +++ b/tree/arbo/circomproofs_test.go @@ -26,15 +26,15 @@ func TestCircomVerifierProof(t *testing.T) { } bLen := 1 for i := 0; i < len(testVector); i++ { - k := BigIntToBytes(bLen, big.NewInt(testVector[i][0])) - v := BigIntToBytes(bLen, big.NewInt(testVector[i][1])) + k := BigIntToBytesLE(bLen, big.NewInt(testVector[i][0])) + v := BigIntToBytesLE(bLen, big.NewInt(testVector[i][1])) if err := tree.Add(k, v); err != nil { t.Fatal(err) } } // proof of existence - k := BigIntToBytes(bLen, big.NewInt(int64(2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(2))) cvp, err := tree.GenerateCircomVerifierProof(k) c.Assert(err, qt.IsNil) jCvp, err := json.Marshal(cvp) @@ -48,7 +48,7 @@ func TestCircomVerifierProof(t *testing.T) { `,"0"],"value":"22"}`) // proof of non-existence - k = BigIntToBytes(bLen, big.NewInt(int64(5))) + k = BigIntToBytesLE(bLen, big.NewInt(int64(5))) cvp, err = tree.GenerateCircomVerifierProof(k) c.Assert(err, qt.IsNil) jCvp, err = json.Marshal(cvp) diff --git a/tree/arbo/hash.go b/tree/arbo/hash.go index 4cfd0ed78..650f77f03 100644 --- a/tree/arbo/hash.go +++ b/tree/arbo/hash.go @@ -6,6 +6,7 @@ import ( "github.com/iden3/go-iden3-crypto/poseidon" "golang.org/x/crypto/blake2b" + "lukechampine.com/blake3" ) var ( @@ -16,6 +17,8 @@ var ( TypeHashPoseidon = []byte("poseidon") // TypeHashBlake2b represents the label for the HashFunction of Blake2b TypeHashBlake2b = []byte("blake2b") + // TypeHashBlake3 represents the label for the HashFunction of Blake3 + TypeHashBlake3 = []byte("blake3") // HashFunctionSha256 contains the HashSha256 struct which implements // the HashFunction interface @@ -26,6 +29,9 @@ var ( // HashFunctionBlake2b contains the HashBlake2b struct which implements // the HashFunction interface HashFunctionBlake2b HashBlake2b + // HashFunctionBlake3 contains the HashBlake3 struct which implements + // the HashFunction interface + HashFunctionBlake3 HashBlake3 ) // Once Generics are at Go, this will be updated (August 2021 @@ -83,14 +89,14 @@ func (HashPoseidon) Len() int { func (f HashPoseidon) Hash(b ...[]byte) ([]byte, error) { var toHash []*big.Int for i := 0; i < len(b); i++ { - bi := BytesToBigInt(b[i]) + bi := BytesLEToBigInt(b[i]) toHash = append(toHash, bi) } h, err := poseidon.Hash(toHash) if err != nil { return nil, err } - hB := BigIntToBytes(f.Len(), h) + hB := BigIntToBytesLE(f.Len(), h) return hB, nil } @@ -120,3 +126,27 @@ func (HashBlake2b) Hash(b ...[]byte) ([]byte, error) { } return hasher.Sum(nil), nil } + +// HashBlake3 implements the HashFunction interface for the Blake3 hash +type HashBlake3 struct{} + +// Type returns the type of HashFunction for the HashBlake3 +func (HashBlake3) Type() []byte { + return TypeHashBlake3 +} + +// Len returns the length of the Hash output +func (HashBlake3) Len() int { + return 32 +} + +// Hash implements the hash method for the HashFunction HashBlake3 +func (HashBlake3) Hash(b ...[]byte) ([]byte, error) { + hasher := blake3.New(32, nil) + for i := 0; i < len(b); i++ { + if _, err := hasher.Write(b[i]); err != nil { + return nil, err + } + } + return hasher.Sum(nil), nil +} diff --git a/tree/arbo/hash_test.go b/tree/arbo/hash_test.go index da0d6297b..7ddc6bdcf 100644 --- a/tree/arbo/hash_test.go +++ b/tree/arbo/hash_test.go @@ -27,12 +27,12 @@ func TestHashPoseidon(t *testing.T) { hashFunc := &HashPoseidon{} bLen := hashFunc.Len() h, err := hashFunc.Hash( - BigIntToBytes(bLen, big.NewInt(1)), - BigIntToBytes(bLen, big.NewInt(2))) + BigIntToBytesLE(bLen, big.NewInt(1)), + BigIntToBytesLE(bLen, big.NewInt(2))) if err != nil { t.Fatal(err) } - hBI := BytesToBigInt(h) + hBI := BytesLEToBigInt(h) // value checked with circomlib c := qt.New(t) c.Assert(hBI.String(), diff --git a/tree/arbo/proof.go b/tree/arbo/proof.go index dbf54bf06..ad19f671d 100644 --- a/tree/arbo/proof.go +++ b/tree/arbo/proof.go @@ -5,6 +5,7 @@ import ( "encoding/binary" "fmt" "math" + "slices" "go.vocdoni.io/dvote/db" ) @@ -173,21 +174,15 @@ func CheckProof(hashFunc HashFunction, k, v, root, packedSiblings []byte) (bool, } path := getPath(len(siblings), keyPath) - for i := len(siblings) - 1; i >= 0; i-- { + for i, sibling := range slices.Backward(siblings) { if path[i] { - key, _, err = newIntermediate(hashFunc, siblings[i], key) - if err != nil { - return false, err - } + key, _, err = newIntermediate(hashFunc, sibling, key) } else { - key, _, err = newIntermediate(hashFunc, key, siblings[i]) - if err != nil { - return false, err - } + key, _, err = newIntermediate(hashFunc, key, sibling) + } + if err != nil { + return false, err } } - if bytes.Equal(key, root) { - return true, nil - } - return false, nil + return bytes.Equal(key, root), nil } diff --git a/tree/arbo/testvectors/circom/go-data-generator/generator_test.go b/tree/arbo/testvectors/circom/go-data-generator/generator_test.go index 6b681d9e1..13562ed20 100644 --- a/tree/arbo/testvectors/circom/go-data-generator/generator_test.go +++ b/tree/arbo/testvectors/circom/go-data-generator/generator_test.go @@ -28,15 +28,15 @@ func TestGenerator(t *testing.T) { } bLen := 1 for i := 0; i < len(testVector); i++ { - k := arbo.BigIntToBytes(bLen, big.NewInt(testVector[i][0])) - v := arbo.BigIntToBytes(bLen, big.NewInt(testVector[i][1])) + k := arbo.BigIntToBytesLE(bLen, big.NewInt(testVector[i][0])) + v := arbo.BigIntToBytesLE(bLen, big.NewInt(testVector[i][1])) if err := tree.Add(k, v); err != nil { t.Fatal(err) } } // proof of existence - k := arbo.BigIntToBytes(bLen, big.NewInt(int64(2))) + k := arbo.BigIntToBytesLE(bLen, big.NewInt(int64(2))) cvp, err := tree.GenerateCircomVerifierProof(k) c.Assert(err, qt.IsNil) jCvp, err := json.Marshal(cvp) @@ -46,7 +46,7 @@ func TestGenerator(t *testing.T) { c.Assert(err, qt.IsNil) // proof of non-existence - k = arbo.BigIntToBytes(bLen, big.NewInt(int64(5))) + k = arbo.BigIntToBytesLE(bLen, big.NewInt(int64(5))) cvp, err = tree.GenerateCircomVerifierProof(k) c.Assert(err, qt.IsNil) jCvp, err = json.Marshal(cvp) diff --git a/tree/arbo/tree_test.go b/tree/arbo/tree_test.go index 9ff0e9679..7980e1a93 100644 --- a/tree/arbo/tree_test.go +++ b/tree/arbo/tree_test.go @@ -21,7 +21,7 @@ import ( func checkRootBIString(c *qt.C, tree *Tree, expected string) { root, err := tree.Root() c.Assert(err, qt.IsNil) - rootBI := BytesToBigInt(root) + rootBI := BytesLEToBigInt(root) c.Check(rootBI.String(), qt.Equals, expected) } @@ -86,20 +86,20 @@ func testAdd(c *qt.C, hashFunc HashFunction, testVectors []string) { bLen := 32 err = tree.Add( - BigIntToBytes(bLen, big.NewInt(1)), - BigIntToBytes(bLen, big.NewInt(2))) + BigIntToBytesLE(bLen, big.NewInt(1)), + BigIntToBytesLE(bLen, big.NewInt(2))) c.Assert(err, qt.IsNil) checkRootBIString(c, tree, testVectors[1]) err = tree.Add( - BigIntToBytes(bLen, big.NewInt(33)), - BigIntToBytes(bLen, big.NewInt(44))) + BigIntToBytesLE(bLen, big.NewInt(33)), + BigIntToBytesLE(bLen, big.NewInt(44))) c.Assert(err, qt.IsNil) checkRootBIString(c, tree, testVectors[2]) err = tree.Add( - BigIntToBytes(bLen, big.NewInt(1234)), - BigIntToBytes(bLen, big.NewInt(9876))) + BigIntToBytesLE(bLen, big.NewInt(1234)), + BigIntToBytesLE(bLen, big.NewInt(9876))) c.Assert(err, qt.IsNil) checkRootBIString(c, tree, testVectors[3]) } @@ -112,8 +112,8 @@ func TestAddBatch(t *testing.T) { bLen := 32 for i := 0; i < 1000; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(0)) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(0)) if err := tree.Add(k, v); err != nil { t.Fatal(err) } @@ -128,8 +128,8 @@ func TestAddBatch(t *testing.T) { var keys, values [][]byte for i := 0; i < 1000; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(0)) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(0)) keys = append(keys, k) values = append(values, v) } @@ -149,8 +149,8 @@ func TestAddDifferentOrder(t *testing.T) { bLen := 32 for i := 0; i < 16; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(0)) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(0)) if err := tree1.Add(k, v); err != nil { t.Fatal(err) } @@ -161,8 +161,8 @@ func TestAddDifferentOrder(t *testing.T) { c.Assert(err, qt.IsNil) for i := 16 - 1; i >= 0; i-- { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(0)) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(0)) if err := tree2.Add(k, v); err != nil { t.Fatal(err) } @@ -184,8 +184,8 @@ func TestAddRepeatedIndex(t *testing.T) { c.Assert(err, qt.IsNil) bLen := 32 - k := BigIntToBytes(bLen, big.NewInt(int64(3))) - v := BigIntToBytes(bLen, big.NewInt(int64(12))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(3))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(12))) err = tree.Add(k, v) c.Assert(err, qt.IsNil) @@ -200,13 +200,13 @@ func TestUpdate(t *testing.T) { c.Assert(err, qt.IsNil) bLen := 32 - k := BigIntToBytes(bLen, big.NewInt(int64(20))) - v := BigIntToBytes(bLen, big.NewInt(int64(12))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(20))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(12))) if err := tree.Add(k, v); err != nil { t.Fatal(err) } - v = BigIntToBytes(bLen, big.NewInt(int64(11))) + v = BigIntToBytesLE(bLen, big.NewInt(int64(11))) err = tree.Update(k, v) c.Assert(err, qt.IsNil) @@ -217,21 +217,21 @@ func TestUpdate(t *testing.T) { // add more leafs to the tree to do another test for i := 0; i < 16; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) if err := tree.Add(k, v); err != nil { t.Fatal(err) } } - k = BigIntToBytes(bLen, big.NewInt(int64(3))) - v = BigIntToBytes(bLen, big.NewInt(int64(11))) + k = BigIntToBytesLE(bLen, big.NewInt(int64(3))) + v = BigIntToBytesLE(bLen, big.NewInt(int64(11))) // check that before the Update, value for 3 is !=11 gettedKey, gettedValue, err = tree.Get(k) c.Assert(err, qt.IsNil) c.Check(gettedKey, qt.DeepEquals, k) c.Check(gettedValue, qt.Not(qt.DeepEquals), v) - c.Check(gettedValue, qt.DeepEquals, BigIntToBytes(bLen, big.NewInt(6))) + c.Check(gettedValue, qt.DeepEquals, BigIntToBytesLE(bLen, big.NewInt(6))) err = tree.Update(k, v) c.Assert(err, qt.IsNil) @@ -241,7 +241,7 @@ func TestUpdate(t *testing.T) { c.Assert(err, qt.IsNil) c.Check(gettedKey, qt.DeepEquals, k) c.Check(gettedValue, qt.DeepEquals, v) - c.Check(gettedValue, qt.DeepEquals, BigIntToBytes(bLen, big.NewInt(11))) + c.Check(gettedValue, qt.DeepEquals, BigIntToBytesLE(bLen, big.NewInt(11))) } func TestRootOnTx(t *testing.T) { @@ -251,8 +251,8 @@ func TestRootOnTx(t *testing.T) { c.Assert(err, qt.IsNil) bLen := 32 - k := BigIntToBytes(bLen, big.NewInt(int64(20))) - v := BigIntToBytes(bLen, big.NewInt(int64(12))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(20))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(12))) if err := tree.Add(k, v); err != nil { t.Fatal(err) } @@ -263,7 +263,7 @@ func TestRootOnTx(t *testing.T) { tx := database.WriteTx() // Update the value of the key - v = BigIntToBytes(bLen, big.NewInt(int64(11))) + v = BigIntToBytesLE(bLen, big.NewInt(int64(11))) err = tree.UpdateWithTx(tx, k, v) c.Assert(err, qt.IsNil) @@ -286,8 +286,8 @@ func TestRootOnTx(t *testing.T) { c.Assert(rootAfter, qt.DeepEquals, newRoot) // Add a new key-value pair - k2 := BigIntToBytes(bLen, big.NewInt(int64(30))) - v2 := BigIntToBytes(bLen, big.NewInt(int64(40))) + k2 := BigIntToBytesLE(bLen, big.NewInt(int64(30))) + v2 := BigIntToBytesLE(bLen, big.NewInt(int64(40))) if err := tree.AddWithTx(tx, k2, v2); err != nil { t.Fatal(err) } @@ -340,29 +340,29 @@ func TestAux(t *testing.T) { // TODO split in proper tests c.Assert(err, qt.IsNil) bLen := 32 - k := BigIntToBytes(bLen, big.NewInt(int64(1))) - v := BigIntToBytes(bLen, big.NewInt(int64(0))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(1))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(0))) err = tree.Add(k, v) c.Assert(err, qt.IsNil) - k = BigIntToBytes(bLen, big.NewInt(int64(256))) + k = BigIntToBytesLE(bLen, big.NewInt(int64(256))) err = tree.Add(k, v) c.Assert(err, qt.IsNil) - k = BigIntToBytes(bLen, big.NewInt(int64(257))) + k = BigIntToBytesLE(bLen, big.NewInt(int64(257))) err = tree.Add(k, v) c.Assert(err, qt.IsNil) - k = BigIntToBytes(bLen, big.NewInt(int64(515))) + k = BigIntToBytesLE(bLen, big.NewInt(int64(515))) err = tree.Add(k, v) c.Assert(err, qt.IsNil) - k = BigIntToBytes(bLen, big.NewInt(int64(770))) + k = BigIntToBytesLE(bLen, big.NewInt(int64(770))) err = tree.Add(k, v) c.Assert(err, qt.IsNil) - k = BigIntToBytes(bLen, big.NewInt(int64(388))) + k = BigIntToBytesLE(bLen, big.NewInt(int64(388))) err = tree.Add(k, v) c.Assert(err, qt.IsNil) - k = BigIntToBytes(bLen, big.NewInt(int64(900))) + k = BigIntToBytesLE(bLen, big.NewInt(int64(900))) err = tree.Add(k, v) c.Assert(err, qt.IsNil) // @@ -381,18 +381,18 @@ func TestGet(t *testing.T) { bLen := 32 for i := 0; i < 10; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) if err := tree.Add(k, v); err != nil { t.Fatal(err) } } - k := BigIntToBytes(bLen, big.NewInt(int64(7))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(7))) gettedKey, gettedValue, err := tree.Get(k) c.Assert(err, qt.IsNil) c.Check(gettedKey, qt.DeepEquals, k) - c.Check(gettedValue, qt.DeepEquals, BigIntToBytes(bLen, big.NewInt(int64(7*2)))) + c.Check(gettedValue, qt.DeepEquals, BigIntToBytesLE(bLen, big.NewInt(int64(7*2)))) } func TestBitmapBytes(t *testing.T) { @@ -522,15 +522,15 @@ func TestGenProofAndVerify(t *testing.T) { bLen := 32 for i := 0; i < 10; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) if err := tree.Add(k, v); err != nil { t.Fatal(err) } } - k := BigIntToBytes(bLen, big.NewInt(int64(7))) - v := BigIntToBytes(bLen, big.NewInt(int64(14))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(7))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(14))) kAux, proofV, siblings, existence, err := tree.GenProof(k) c.Assert(err, qt.IsNil) c.Assert(proofV, qt.DeepEquals, v) @@ -563,8 +563,8 @@ func testDumpAndImportDump(t *testing.T, inFile bool) { bLen := 32 for i := 0; i < 16; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i*2))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i*2))) if err := tree1.Add(k, v); err != nil { t.Fatal(err) } @@ -621,8 +621,8 @@ func TestRWMutex(t *testing.T) { bLen := 32 var keys, values [][]byte for i := 0; i < 1000; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(0)) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(0)) keys = append(keys, k) values = append(values, v) } @@ -634,8 +634,8 @@ func TestRWMutex(t *testing.T) { }() time.Sleep(500 * time.Millisecond) - k := BigIntToBytes(bLen, big.NewInt(int64(99999))) - v := BigIntToBytes(bLen, big.NewInt(int64(99999))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(99999))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(99999))) if err := tree.Add(k, v); err != nil { t.Fatal(err) } @@ -660,7 +660,7 @@ func TestAddBatchFullyUsed(t *testing.T) { var keys, values [][]byte for i := 0; i < 16; i++ { - k := BigIntToBytes(1, big.NewInt(int64(i))) + k := BigIntToBytesLE(1, big.NewInt(int64(i))) v := k keys = append(keys, k) @@ -683,10 +683,10 @@ func TestAddBatchFullyUsed(t *testing.T) { // get all key-values and check that are equal between both trees for i := 0; i < 16; i++ { - auxK1, auxV1, err := tree1.Get(BigIntToBytes(1, big.NewInt(int64(i)))) + auxK1, auxV1, err := tree1.Get(BigIntToBytesLE(1, big.NewInt(int64(i)))) c.Assert(err, qt.IsNil) - auxK2, auxV2, err := tree2.Get(BigIntToBytes(1, big.NewInt(int64(i)))) + auxK2, auxV2, err := tree2.Get(BigIntToBytesLE(1, big.NewInt(int64(i)))) c.Assert(err, qt.IsNil) c.Assert(auxK1, qt.DeepEquals, auxK2) @@ -695,7 +695,7 @@ func TestAddBatchFullyUsed(t *testing.T) { // try adding one more key to both trees (through Add & AddBatch) and // expect not being added due the tree is already full - k := BigIntToBytes(1, big.NewInt(int64(16))) + k := BigIntToBytesLE(1, big.NewInt(int64(16))) v := k err = tree1.Add(k, v) c.Assert(err, qt.Equals, ErrMaxVirtualLevel) @@ -720,8 +720,8 @@ func TestSetRoot(t *testing.T) { bLen := 32 var keys, values [][]byte for i := 0; i < 1000; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i))) keys = append(keys, k) values = append(values, v) } @@ -733,8 +733,8 @@ func TestSetRoot(t *testing.T) { expectedRoot) // add one more k-v - k := BigIntToBytes(bLen, big.NewInt(1000)) - v := BigIntToBytes(bLen, big.NewInt(1000)) + k := BigIntToBytesLE(bLen, big.NewInt(1000)) + v := BigIntToBytesLE(bLen, big.NewInt(1000)) err = tree.Add(k, v) c.Assert(err, qt.IsNil) checkRootBIString(c, tree, @@ -751,9 +751,9 @@ func TestSetRoot(t *testing.T) { c.Assert(string(root), qt.Equals, string(roots[0])) // check that the tree can be updated - err = tree.Add(BigIntToBytes(bLen, big.NewInt(int64(1024))), []byte("test")) + err = tree.Add(BigIntToBytesLE(bLen, big.NewInt(int64(1024))), []byte("test")) c.Assert(err, qt.IsNil) - err = tree.Update(BigIntToBytes(bLen, big.NewInt(int64(1024))), []byte("test2")) + err = tree.Update(BigIntToBytesLE(bLen, big.NewInt(int64(1024))), []byte("test2")) c.Assert(err, qt.IsNil) // check that the k-v '1000' does not exist in the new tree @@ -778,8 +778,8 @@ func TestSnapshot(t *testing.T) { bLen := 32 var keys, values [][]byte for i := 0; i < 1000; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i))) keys = append(keys, k) values = append(values, v) } @@ -827,7 +827,7 @@ func TestGetFromSnapshotExpectArboErrKeyNotFound(t *testing.T) { c.Assert(err, qt.IsNil) bLen := 32 - k := BigIntToBytes(bLen, big.NewInt(int64(3))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(3))) root, err := tree.Root() c.Assert(err, qt.IsNil) @@ -852,8 +852,8 @@ func TestKeyLen(t *testing.T) { // expect no errors when adding a key of only 4 bytes (when the // required length of keyPath for 100 levels would be 13 bytes) bLen := 4 - k := BigIntToBytes(bLen, big.NewInt(1)) - v := BigIntToBytes(bLen, big.NewInt(1)) + k := BigIntToBytesLE(bLen, big.NewInt(1)) + v := BigIntToBytesLE(bLen, big.NewInt(1)) err = tree.Add(k, v) c.Assert(err, qt.IsNil) @@ -867,8 +867,8 @@ func TestKeyLen(t *testing.T) { _, _, err = tree.Get(k) c.Assert(err, qt.IsNil) - k = BigIntToBytes(bLen, big.NewInt(2)) - v = BigIntToBytes(bLen, big.NewInt(2)) + k = BigIntToBytesLE(bLen, big.NewInt(2)) + v = BigIntToBytesLE(bLen, big.NewInt(2)) invalids, err := tree.AddBatch([][]byte{k}, [][]byte{v}) c.Assert(err, qt.IsNil) c.Assert(len(invalids), qt.Equals, 0) @@ -884,8 +884,8 @@ func TestKeyLen(t *testing.T) { c.Assert(err, qt.IsNil) maxKeyLen := int(math.Ceil(float64(maxLevels) / float64(8))) - k = BigIntToBytes(maxKeyLen+1, big.NewInt(1)) - v = BigIntToBytes(maxKeyLen+1, big.NewInt(1)) + k = BigIntToBytesLE(maxKeyLen+1, big.NewInt(1)) + v = BigIntToBytesLE(maxKeyLen+1, big.NewInt(1)) expectedErrMsg := "len(k) can not be bigger than ceil(maxLevels/8)," + " where len(k): 5, maxLevels: 32, max key len=ceil(maxLevels/8): 4." + @@ -914,15 +914,15 @@ func TestKeyLen(t *testing.T) { nKVs := nCPU + 1 var ks, vs [][]byte for i := 0; i < nKVs; i++ { - ks = append(ks, BigIntToBytes(maxKeyLen+1, big.NewInt(1))) - vs = append(vs, BigIntToBytes(maxKeyLen+1, big.NewInt(1))) + ks = append(ks, BigIntToBytesLE(maxKeyLen+1, big.NewInt(1))) + vs = append(vs, BigIntToBytesLE(maxKeyLen+1, big.NewInt(1))) } invalids, err = tree.AddBatch(ks, vs) c.Assert(err, qt.IsNil) c.Assert(len(invalids), qt.Equals, nKVs) // check that with maxKeyLen it can be added - k = BigIntToBytes(maxKeyLen, big.NewInt(1)) + k = BigIntToBytesLE(maxKeyLen, big.NewInt(1)) err = tree.Add(k, v) c.Assert(err, qt.IsNil) @@ -983,16 +983,16 @@ func TestDelete(t *testing.T) { bLen := 32 // Add multiple key/value pairs to the tree keys := [][]byte{ - BigIntToBytes(bLen, big.NewInt(int64(1))), - BigIntToBytes(bLen, big.NewInt(int64(2))), - BigIntToBytes(bLen, big.NewInt(int64(3))), - BigIntToBytes(bLen, big.NewInt(int64(4))), + BigIntToBytesLE(bLen, big.NewInt(int64(1))), + BigIntToBytesLE(bLen, big.NewInt(int64(2))), + BigIntToBytesLE(bLen, big.NewInt(int64(3))), + BigIntToBytesLE(bLen, big.NewInt(int64(4))), } values := [][]byte{ - BigIntToBytes(bLen, big.NewInt(int64(10))), - BigIntToBytes(bLen, big.NewInt(int64(20))), - BigIntToBytes(bLen, big.NewInt(int64(30))), - BigIntToBytes(bLen, big.NewInt(int64(40))), + BigIntToBytesLE(bLen, big.NewInt(int64(10))), + BigIntToBytesLE(bLen, big.NewInt(int64(20))), + BigIntToBytesLE(bLen, big.NewInt(int64(30))), + BigIntToBytesLE(bLen, big.NewInt(int64(40))), } for i, key := range keys { err := tree.Add(key, values[i]) @@ -1038,8 +1038,8 @@ func BenchmarkAdd(b *testing.B) { // prepare inputs var ks, vs [][]byte for i := 0; i < 1000; i++ { - k := BigIntToBytes(bLen, big.NewInt(int64(i))) - v := BigIntToBytes(bLen, big.NewInt(int64(i))) + k := BigIntToBytesLE(bLen, big.NewInt(int64(i))) + v := BigIntToBytesLE(bLen, big.NewInt(int64(i))) ks = append(ks, k) vs = append(vs, v) } @@ -1216,20 +1216,20 @@ func TestGetLeavesFromSubPath(t *testing.T) { // Add keys with shared prefix and some without shared prefix keys := [][]byte{ // Shared prefix keys - append([]byte{0xFF, 0xFF}, BigIntToBytes(bLen-2, big.NewInt(int64(1)))...), - append([]byte{0xFF, 0xFF}, BigIntToBytes(bLen-2, big.NewInt(int64(2)))...), - append([]byte{0xFF, 0xFF}, BigIntToBytes(bLen-2, big.NewInt(int64(3)))...), + append([]byte{0xFF, 0xFF}, BigIntToBytesLE(bLen-2, big.NewInt(int64(1)))...), + append([]byte{0xFF, 0xFF}, BigIntToBytesLE(bLen-2, big.NewInt(int64(2)))...), + append([]byte{0xFF, 0xFF}, BigIntToBytesLE(bLen-2, big.NewInt(int64(3)))...), // Non-shared prefix keys - BigIntToBytes(bLen, big.NewInt(int64(4))), - BigIntToBytes(bLen, big.NewInt(int64(5))), + BigIntToBytesLE(bLen, big.NewInt(int64(4))), + BigIntToBytesLE(bLen, big.NewInt(int64(5))), } - sharedPrefixKeyNotAdded := append([]byte{0xFF, 0xFF}, BigIntToBytes(bLen-2, big.NewInt(int64(4)))...) + sharedPrefixKeyNotAdded := append([]byte{0xFF, 0xFF}, BigIntToBytesLE(bLen-2, big.NewInt(int64(4)))...) values := [][]byte{ - BigIntToBytes(bLen, big.NewInt(int64(10))), - BigIntToBytes(bLen, big.NewInt(int64(20))), - BigIntToBytes(bLen, big.NewInt(int64(30))), - BigIntToBytes(bLen, big.NewInt(int64(40))), - BigIntToBytes(bLen, big.NewInt(int64(50))), + BigIntToBytesLE(bLen, big.NewInt(int64(10))), + BigIntToBytesLE(bLen, big.NewInt(int64(20))), + BigIntToBytesLE(bLen, big.NewInt(int64(30))), + BigIntToBytesLE(bLen, big.NewInt(int64(40))), + BigIntToBytesLE(bLen, big.NewInt(int64(50))), } for i, key := range keys { err := tree.Add(key, values[i]) @@ -1487,7 +1487,7 @@ func generateKV(bLen, count, offset int) ([][]byte, [][]byte) { for i := 0; i < count; i++ { // Convert integer i to a byte slice - key := BigIntToBytes(bLen, big.NewInt(int64(offset+i))) + key := BigIntToBytesLE(bLen, big.NewInt(int64(offset+i))) value := randomBytes(bLen) keys = append(keys, key) diff --git a/tree/arbo/utils.go b/tree/arbo/utils.go index c183ff315..7d6aed2a6 100644 --- a/tree/arbo/utils.go +++ b/tree/arbo/utils.go @@ -18,19 +18,48 @@ func SwapEndianness(b []byte) []byte { } // BigIntToBytes converts a *big.Int into a byte array in Little-Endian +// +// Deprecated: use BigIntToBytesLE or BigIntToBytesBE func BigIntToBytes(blen int, bi *big.Int) []byte { + return BigIntToBytesLE(blen, bi) +} + +// BigIntToBytesLE converts a *big.Int into a byte array in Little-Endian +func BigIntToBytesLE(blen int, bi *big.Int) []byte { // TODO make the length depending on the tree.hashFunction.Len() b := make([]byte, blen) copy(b, SwapEndianness(bi.Bytes())) return b } +// BigIntToBytesBE converts a *big.Int into a byte array in Big-Endian +func BigIntToBytesBE(blen int, bi *big.Int) []byte { + // TODO make the length depending on the tree.hashFunction.Len() + b := make([]byte, blen) + copy(b, bi.Bytes()) + return b +} + // BytesToBigInt converts a byte array in Little-Endian representation into // *big.Int +// +// Deprecated: use BytesLEToBigInt or BytesBEToBigInt func BytesToBigInt(b []byte) *big.Int { + return BytesLEToBigInt(b) +} + +// BytesLEToBigInt converts a byte array in Little-Endian representation into +// *big.Int +func BytesLEToBigInt(b []byte) *big.Int { return new(big.Int).SetBytes(SwapEndianness(b)) } +// BytesBEToBigInt converts a byte array in Big-Endian representation into +// *big.Int +func BytesBEToBigInt(b []byte) *big.Int { + return new(big.Int).SetBytes(b) +} + // newLeafValue takes a key & value from a leaf, and computes the leaf hash, // which is used as the leaf key. And the value is the concatenation of the // inputted key & value. The output of this function is used as key-value to diff --git a/tree/arbo/vt_test.go b/tree/arbo/vt_test.go index 705796b15..8ad4ee05c 100644 --- a/tree/arbo/vt_test.go +++ b/tree/arbo/vt_test.go @@ -51,16 +51,16 @@ func TestVirtualTreeTestVectors(t *testing.T) { maxLevels := 32 keyLen := int(math.Ceil(float64(maxLevels) / float64(8))) keys := [][]byte{ - BigIntToBytes(keyLen, big.NewInt(1)), - BigIntToBytes(keyLen, big.NewInt(33)), - BigIntToBytes(keyLen, big.NewInt(1234)), - BigIntToBytes(keyLen, big.NewInt(123456789)), + BigIntToBytesLE(keyLen, big.NewInt(1)), + BigIntToBytesLE(keyLen, big.NewInt(33)), + BigIntToBytesLE(keyLen, big.NewInt(1234)), + BigIntToBytesLE(keyLen, big.NewInt(123456789)), } values := [][]byte{ - BigIntToBytes(keyLen, big.NewInt(2)), - BigIntToBytes(keyLen, big.NewInt(44)), - BigIntToBytes(keyLen, big.NewInt(9876)), - BigIntToBytes(keyLen, big.NewInt(987654321)), + BigIntToBytesLE(keyLen, big.NewInt(2)), + BigIntToBytesLE(keyLen, big.NewInt(44)), + BigIntToBytesLE(keyLen, big.NewInt(9876)), + BigIntToBytesLE(keyLen, big.NewInt(987654321)), } // check the root for different batches of leafs @@ -159,7 +159,7 @@ func TestVirtualTreeAddBatchFullyUsed(t *testing.T) { var keys, values [][]byte for i := 0; i < 128; i++ { - k := BigIntToBytes(1, big.NewInt(int64(i))) + k := BigIntToBytesLE(1, big.NewInt(int64(i))) v := k keys = append(keys, k) diff --git a/vochain/account_test.go b/vochain/account_test.go index a491ea940..0943fa54b 100644 --- a/vochain/account_test.go +++ b/vochain/account_test.go @@ -3,7 +3,8 @@ package vochain import ( "context" "fmt" - "math/rand" + "math/rand/v2" + "regexp" "testing" cometabcitypes "github.com/cometbft/cometbft/abci/types" @@ -73,7 +74,7 @@ func setupTestBaseApplicationAndSigners(t *testing.T, } func TestSetAccountTx(t *testing.T) { - app, signers, err := setupTestBaseApplicationAndSigners(t, 10) + app, signers, err := setupTestBaseApplicationAndSigners(t, 11) qt.Assert(t, err, qt.IsNil) // set account 0 qt.Assert(t, @@ -84,6 +85,9 @@ func TestSetAccountTx(t *testing.T) { ) testCommitState(t, app) + // set create account tx cost to 200 + qt.Assert(t, app.State.SetTxBaseCost(models.TxType_CREATE_ACCOUNT, 200), qt.IsNil) + // CREATE ACCOUNT // should work is a valid faucet payload and tx.Account is provided and no infoURI is set @@ -97,13 +101,13 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err := app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(8900)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(9000)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer1Account, err := app.State.GetAccount(signers[1].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer1Account, qt.IsNotNil) - qt.Assert(t, signer1Account.Balance, qt.DeepEquals, uint64(1000)) + qt.Assert(t, signer1Account.Balance, qt.DeepEquals, uint64(800)) qt.Assert(t, signer1Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer1Account.InfoURI, qt.CmpEquals(), "") @@ -117,13 +121,13 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(7800)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(8000)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer2Account, err := app.State.GetAccount(signers[2].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer2Account, qt.IsNotNil) - qt.Assert(t, signer2Account.Balance, qt.DeepEquals, uint64(1000)) + qt.Assert(t, signer2Account.Balance, qt.DeepEquals, uint64(800)) qt.Assert(t, signer2Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer2Account.InfoURI, qt.CmpEquals(), "") @@ -137,13 +141,13 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(6700)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(7000)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer3Account, err := app.State.GetAccount(signers[3].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer3Account, qt.IsNotNil) - qt.Assert(t, signer3Account.Balance, qt.DeepEquals, uint64(1000)) + qt.Assert(t, signer3Account.Balance, qt.DeepEquals, uint64(800)) qt.Assert(t, signer3Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer3Account.InfoURI, qt.CmpEquals(), infoURI) @@ -158,13 +162,13 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5600)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(6000)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer4Account, err := app.State.GetAccount(signers[4].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer4Account, qt.IsNotNil) - qt.Assert(t, signer4Account.Balance, qt.DeepEquals, uint64(1000)) + qt.Assert(t, signer4Account.Balance, qt.DeepEquals, uint64(800)) qt.Assert(t, signer4Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer4Account.InfoURI, qt.CmpEquals(), infoURI) @@ -178,7 +182,7 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5600)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(6000)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer5Account, err := app.State.GetAccount(signers[5].Address(), false) @@ -193,7 +197,7 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5600)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(6000)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer5Account, err = app.State.GetAccount(signers[5].Address(), false) @@ -208,7 +212,7 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5600)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(6000)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer5Account, err = app.State.GetAccount(signers[5].Address(), false) @@ -223,7 +227,7 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5600)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(6000)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer5Account, err = app.State.GetAccount(signers[5].Address(), false) @@ -240,7 +244,7 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5600)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(6000)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer5Account, err = app.State.GetAccount(signers[5].Address(), false) @@ -271,7 +275,7 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5600)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(6000)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer5Account, err = app.State.GetAccount(signers[5].Address(), false) @@ -288,7 +292,7 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5600)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(6000)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer5Account, err = app.State.GetAccount(signers[5].Address(), false) @@ -296,7 +300,7 @@ func TestSetAccountTx(t *testing.T) { qt.Assert(t, signer5Account, qt.IsNil) // should work if random nonce provided - faucetPkg, err = GenerateFaucetPackage(signers[0], signers[5].Address(), 10) + faucetPkg, err = GenerateFaucetPackage(signers[0], signers[5].Address(), 200) qt.Assert(t, err, qt.IsNil) qt.Assert(t, testSetAccountTx(t, signers[5], common.Address{}, faucetPkg, app, infoURI, rand.Uint32(), true), @@ -305,19 +309,19 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5490)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5800)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer5Account, err = app.State.GetAccount(signers[5].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer5Account, qt.IsNotNil) - qt.Assert(t, signer5Account.Balance, qt.DeepEquals, uint64(10)) + qt.Assert(t, signer5Account.Balance, qt.DeepEquals, uint64(0)) qt.Assert(t, signer5Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer5Account.InfoURI, qt.CmpEquals(), infoURI) qt.Assert(t, signer5Account.DelegateAddrs, qt.DeepEquals, [][]byte(nil)) // should work if random account provided, the account created is the signer one - faucetPkg, err = GenerateFaucetPackage(signers[0], signers[6].Address(), 10) + faucetPkg, err = GenerateFaucetPackage(signers[0], signers[6].Address(), 200) qt.Assert(t, err, qt.IsNil) qt.Assert(t, testSetAccountTx(t, signers[6], signers[7].Address(), faucetPkg, app, infoURI, rand.Uint32(), true), @@ -326,13 +330,13 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5380)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5600)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer6Account, err = app.State.GetAccount(signers[6].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer6Account, qt.IsNotNil) - qt.Assert(t, signer6Account.Balance, qt.DeepEquals, uint64(10)) + qt.Assert(t, signer6Account.Balance, qt.DeepEquals, uint64(0)) qt.Assert(t, signer6Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer6Account.InfoURI, qt.CmpEquals(), infoURI) qt.Assert(t, signer6Account.DelegateAddrs, qt.DeepEquals, [][]byte(nil)) @@ -343,7 +347,7 @@ func TestSetAccountTx(t *testing.T) { // should ignore tx cost if tx cost is set to 0 qt.Assert(t, app.State.SetTxBaseCost(models.TxType_CREATE_ACCOUNT, 0), qt.IsNil) testCommitState(t, app) - faucetPkg, err = GenerateFaucetPackage(signers[0], signers[7].Address(), 10) + faucetPkg, err = GenerateFaucetPackage(signers[0], signers[7].Address(), 200) qt.Assert(t, err, qt.IsNil) qt.Assert(t, testSetAccountTx(t, signers[7], common.Address{}, faucetPkg, app, infoURI, 0, true), @@ -352,13 +356,13 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5370)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5400)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer7Account, err = app.State.GetAccount(signers[7].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer7Account, qt.IsNotNil) - qt.Assert(t, signer7Account.Balance, qt.DeepEquals, uint64(10)) + qt.Assert(t, signer7Account.Balance, qt.DeepEquals, uint64(200)) qt.Assert(t, signer7Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer7Account.InfoURI, qt.CmpEquals(), infoURI) qt.Assert(t, signer7Account.DelegateAddrs, qt.DeepEquals, [][]byte(nil)) @@ -371,7 +375,7 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5370)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5400)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer8Account, err := app.State.GetAccount(signers[8].Address(), false) @@ -383,7 +387,7 @@ func TestSetAccountTx(t *testing.T) { qt.Assert(t, signer8Account.DelegateAddrs, qt.DeepEquals, [][]byte(nil)) // should not work if tx cost is not 0 and no faucet package is provided - qt.Assert(t, app.State.SetTxBaseCost(models.TxType_CREATE_ACCOUNT, 1), qt.IsNil) + qt.Assert(t, app.State.SetTxBaseCost(models.TxType_CREATE_ACCOUNT, 200), qt.IsNil) testCommitState(t, app) qt.Assert(t, testSetAccountTx(t, signers[9], common.Address{}, nil, app, infoURI, 0, true), @@ -392,7 +396,7 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5370)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5400)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer9Account, err := app.State.GetAccount(signers[9].Address(), false) @@ -401,7 +405,8 @@ func TestSetAccountTx(t *testing.T) { // SET ACCOUNT INFO URI - // should not work for itself with faucet package (the faucet package is ignored) and invalid InfoURI + // should not work (the faucet package is ignored) and invalid InfoURI + qt.Assert(t, app.State.SetTxBaseCost(models.TxType_SET_ACCOUNT_INFO_URI, 200), qt.IsNil) faucetPkg, err = GenerateFaucetPackage(signers[0], signers[0].Address(), 1000) qt.Assert(t, err, qt.IsNil) qt.Assert(t, testSetAccountTx(t, @@ -411,7 +416,7 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5370)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5400)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) @@ -423,7 +428,7 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5370)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5400)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) @@ -433,7 +438,7 @@ func TestSetAccountTx(t *testing.T) { qt.IsNotNil, ) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5370)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5400)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) @@ -443,7 +448,7 @@ func TestSetAccountTx(t *testing.T) { qt.IsNotNil, ) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5370)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5400)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) @@ -455,7 +460,7 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5270)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5200)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(1)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI2) @@ -469,15 +474,16 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5270)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5200)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(1)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI2) signer1Account, err = app.State.GetAccount(signers[1].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer1Account, qt.IsNotNil) - qt.Assert(t, signer1Account.Balance, qt.DeepEquals, uint64(1000)) + qt.Assert(t, signer1Account.Balance, qt.DeepEquals, uint64(800)) qt.Assert(t, signer1Account.Nonce, qt.DeepEquals, uint32(0)) qt.Assert(t, signer1Account.InfoURI, qt.CmpEquals(), "") + // should work if delegate qt.Assert(t, app.State.SetAccountDelegate( signers[0].Address(), @@ -491,15 +497,125 @@ func TestSetAccountTx(t *testing.T) { signer0Account, err = app.State.GetAccount(signers[0].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer0Account, qt.IsNotNil) - qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5270)) + qt.Assert(t, signer0Account.Balance, qt.DeepEquals, uint64(5200)) qt.Assert(t, signer0Account.Nonce, qt.DeepEquals, uint32(1)) qt.Assert(t, signer0Account.InfoURI, qt.CmpEquals(), infoURI) signer1Account, err = app.State.GetAccount(signers[1].Address(), false) qt.Assert(t, err, qt.IsNil) qt.Assert(t, signer1Account, qt.IsNotNil) - qt.Assert(t, signer1Account.Balance, qt.DeepEquals, uint64(900)) + qt.Assert(t, signer1Account.Balance, qt.DeepEquals, uint64(600)) qt.Assert(t, signer1Account.Nonce, qt.DeepEquals, uint32(1)) qt.Assert(t, signer1Account.InfoURI, qt.CmpEquals(), "") + + // should work, try using a faucet package for a set account info tx + // first create the account (and check balance is 0, because tx cost 200) + faucetPkg, err = GenerateFaucetPackage(signers[0], signers[9].Address(), 200) + qt.Assert(t, err, qt.IsNil) + qt.Assert(t, testSetAccountTx(t, + signers[9], signers[9].Address(), faucetPkg, app, "", uint32(0), true), + qt.IsNil, + ) + + signer9Account, err = app.State.GetAccount(signers[9].Address(), false) + qt.Assert(t, err, qt.IsNil) + + qt.Assert(t, signer9Account, qt.IsNotNil) + qt.Assert(t, signer9Account.Balance, qt.DeepEquals, uint64(0)) + qt.Assert(t, signer9Account.Nonce, qt.DeepEquals, uint32(0)) + qt.Assert(t, signer9Account.InfoURI, qt.CmpEquals(), "") + + // second send the set account info uri tx, check the remaining balance is 34 + faucetPkg, err = GenerateFaucetPackage(signers[0], signers[9].Address(), 234) + qt.Assert(t, err, qt.IsNil) + infoURI3 := "ipfs://newInfoUri" + qt.Assert(t, testSetAccountTx(t, + signers[9], signers[9].Address(), faucetPkg, app, infoURI3, uint32(0), false), + qt.IsNil, + ) + + signer9Account, err = app.State.GetAccount(signers[9].Address(), false) + qt.Assert(t, err, qt.IsNil) + + qt.Assert(t, signer9Account, qt.IsNotNil) + qt.Assert(t, signer9Account.Balance, qt.DeepEquals, uint64(34)) + qt.Assert(t, signer9Account.Nonce, qt.DeepEquals, uint32(1)) + qt.Assert(t, signer9Account.InfoURI, qt.CmpEquals(), infoURI3) + + // third should not work: try using an insufficiente faucet package (150) for a set account info tx + // because tx cost 200 + faucetPkg, err = GenerateFaucetPackage(signers[0], signers[9].Address(), 150) + qt.Assert(t, err, qt.IsNil) + infoURI4 := "ipfs://newInfoUri4" + qt.Assert(t, testSetAccountTx(t, + signers[9], signers[9].Address(), faucetPkg, app, infoURI4, uint32(1), false), + qt.ErrorMatches, regexp.MustCompile(".*is not enough to pay the tx cost.*"), + ) + + signer9Account, err = app.State.GetAccount(signers[9].Address(), false) + qt.Assert(t, err, qt.IsNil) + + // the result should be the balance, nonce and infoURI remain unchanged. + qt.Assert(t, signer9Account, qt.IsNotNil) + qt.Assert(t, signer9Account.Balance, qt.DeepEquals, uint64(34)) + qt.Assert(t, signer9Account.Nonce, qt.DeepEquals, uint32(1)) + qt.Assert(t, signer9Account.InfoURI, qt.CmpEquals(), infoURI3) + + // now this should work: try again using a small faucet package (180) for a set account info tx + // but adding faucet (180) + balance (34) is enough to cover the tx cost of 200 + faucetPkg, err = GenerateFaucetPackage(signers[0], signers[9].Address(), 180) + qt.Assert(t, err, qt.IsNil) + qt.Assert(t, testSetAccountTx(t, + signers[9], signers[9].Address(), faucetPkg, app, infoURI4, uint32(1), false), + qt.IsNil, + ) + + signer9Account, err = app.State.GetAccount(signers[9].Address(), false) + qt.Assert(t, err, qt.IsNil) + + // the result should be updated infoURI and nonce, and a balance equal to + // the tokens from balance + faucet minus the consumed txcost, + qt.Assert(t, signer9Account, qt.IsNotNil) + qt.Assert(t, signer9Account.Balance, qt.DeepEquals, uint64(180+34-200)) + qt.Assert(t, signer9Account.Nonce, qt.DeepEquals, uint32(2)) + qt.Assert(t, signer9Account.InfoURI, qt.CmpEquals(), infoURI4) + + // now we init signers[10] with 1000 tokens from faucet (signers[0]) + // resulting balance should be 800 (because of the 200 txcost of createAccount) + // then "transfer" 700 of those to signers[9] via a faucet package issued by signers[10] + // used to setAccount + faucetPkg, err = GenerateFaucetPackage(signers[0], signers[10].Address(), 1000) + qt.Assert(t, err, qt.IsNil) + qt.Assert(t, testSetAccountTx(t, + signers[10], signers[10].Address(), faucetPkg, app, "", uint32(0), true), + qt.IsNil, + ) + signer10Account, err := app.State.GetAccount(signers[10].Address(), false) + qt.Assert(t, err, qt.IsNil) + qt.Assert(t, signer10Account.Balance, qt.DeepEquals, uint64(1000-200)) + + signer9Account, err = app.State.GetAccount(signers[9].Address(), false) + qt.Assert(t, err, qt.IsNil) + oldBalance := signer9Account.Balance + + faucetPkg, err = GenerateFaucetPackage(signers[10], signers[9].Address(), 1000-200+1) + qt.Assert(t, err, qt.IsNil) + qt.Assert(t, testSetAccountTx(t, + signers[9], signers[9].Address(), faucetPkg, app, "ipfs://test", uint32(2), false), + qt.ErrorMatches, regexp.MustCompile(".*issuer address does not have enough balance.*"), + ) + + faucetPkg, err = GenerateFaucetPackage(signers[10], signers[9].Address(), 1000-200-50) + qt.Assert(t, err, qt.IsNil) + qt.Assert(t, testSetAccountTx(t, + signers[9], signers[9].Address(), faucetPkg, app, "ipfs://test", uint32(2), false), + qt.IsNil, + ) + signer10Account, err = app.State.GetAccount(signers[10].Address(), false) + qt.Assert(t, err, qt.IsNil) + qt.Assert(t, signer10Account.Balance, qt.DeepEquals, uint64(50)) + signer9Account, err = app.State.GetAccount(signers[9].Address(), false) + qt.Assert(t, err, qt.IsNil) + qt.Assert(t, signer9Account.Balance, qt.DeepEquals, uint64(oldBalance+1000-200-50-200)) } func testSetAccountTx(t *testing.T, @@ -604,7 +720,7 @@ func TestSendTokensTxToTheSameAccount(t *testing.T) { err := signer.Generate() qt.Assert(t, err, qt.IsNil) - app.State.SetAccount(state.BurnAddress, &state.Account{}) + qt.Assert(t, app.State.SetAccount(state.BurnAddress, &state.Account{}), qt.IsNil) err = app.State.SetTxBaseCost(models.TxType_SEND_TOKENS, 10) qt.Assert(t, err, qt.IsNil) @@ -664,7 +780,7 @@ func TestSetAccountDelegateTx(t *testing.T) { err = signer2.Generate() qt.Assert(t, err, qt.IsNil) - app.State.SetAccount(state.BurnAddress, &state.Account{}) + qt.Assert(t, app.State.SetAccount(state.BurnAddress, &state.Account{}), qt.IsNil) err = app.State.SetTxBaseCost(models.TxType_ADD_DELEGATE_FOR_ACCOUNT, 10) qt.Assert(t, err, qt.IsNil) @@ -770,7 +886,7 @@ func TestCollectFaucetTx(t *testing.T) { err = toSigner.Generate() qt.Assert(t, err, qt.IsNil) - app.State.SetAccount(state.BurnAddress, &state.Account{}) + qt.Assert(t, app.State.SetAccount(state.BurnAddress, &state.Account{}), qt.IsNil) err = app.State.SetTxBaseCost(models.TxType_COLLECT_FAUCET, 10) qt.Assert(t, err, qt.IsNil) diff --git a/vochain/app.go b/vochain/app.go index 7e0107537..f6691be61 100644 --- a/vochain/app.go +++ b/vochain/app.go @@ -290,10 +290,6 @@ func (app *BaseApplication) beginBlock(t time.Time, height uint32) { app.State.SetHeight(height) go app.State.CachePurge(height) - app.State.OnBeginBlock(vstate.BeginBlock{ - Height: int64(height), - Time: t, - }) } // endBlock is called at the end of every block. diff --git a/vochain/appsetup.go b/vochain/appsetup.go index fb52f66ed..6726b8b21 100644 --- a/vochain/appsetup.go +++ b/vochain/appsetup.go @@ -25,9 +25,6 @@ func (app *BaseApplication) SetNode(vochaincfg *config.VochainCfg) error { if app.Node, err = newTendermint(app, vochaincfg); err != nil { return fmt.Errorf("could not set tendermint node service: %s", err) } - if vochaincfg.IsSeedNode { - return nil - } // Note that cometcli.New logs any error rather than returning it. app.NodeClient = cometcli.New(app.Node) return nil diff --git a/vochain/indexer/bench_test.go b/vochain/indexer/bench_test.go index 631e83205..a2c60cf1d 100644 --- a/vochain/indexer/bench_test.go +++ b/vochain/indexer/bench_test.go @@ -2,6 +2,7 @@ package indexer import ( "bytes" + "context" "fmt" "math/big" "sync" @@ -14,6 +15,7 @@ import ( "go.vocdoni.io/dvote/test/testcommon/testutil" "go.vocdoni.io/dvote/util" "go.vocdoni.io/dvote/vochain" + indexerdb "go.vocdoni.io/dvote/vochain/indexer/db" "go.vocdoni.io/dvote/vochain/state" "go.vocdoni.io/dvote/vochain/transaction/vochaintx" "go.vocdoni.io/proto/build/go/models" @@ -85,6 +87,7 @@ func BenchmarkIndexer(b *testing.B) { tx := &vochaintx.Tx{ TxID: rnd.Random32(), TxModelType: "vote", + Tx: &models.Tx{Payload: &models.Tx_Vote{}}, } idx.OnNewTx(tx, height, txBlockIndex) curTxs = append(curTxs, tx) @@ -112,7 +115,7 @@ func BenchmarkIndexer(b *testing.B) { qt.Check(b, bytes.Equal(voteRef.Meta.TxHash, tx.TxID[:]), qt.IsTrue) } - txRef, err := idx.GetTxHashReference(tx.TxID[:]) + txRef, err := idx.GetTxMetadataByHash(tx.TxID[:]) qt.Check(b, err, qt.IsNil) if err == nil { qt.Check(b, txRef.BlockHeight, qt.Equals, vote.Height) @@ -138,7 +141,11 @@ func BenchmarkFetchTx(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < numTxs; j++ { - idx.OnNewTx(&vochaintx.Tx{TxID: util.Random32()}, uint32(i), int32(j)) + idx.OnNewTx(&vochaintx.Tx{ + TxID: util.Random32(), + TxModelType: "vote", + Tx: &models.Tx{Payload: &models.Tx_Vote{}}, + }, uint32(i), int32(j)) } err := idx.Commit(uint32(i)) qt.Assert(b, err, qt.IsNil) @@ -147,14 +154,14 @@ func BenchmarkFetchTx(b *testing.B) { startTime := time.Now() for j := 0; j < numTxs; j++ { - _, err = idx.GetTransaction(uint64((i * numTxs) + j + 1)) + _, err = idx.GetTransactionByHeightAndIndex(int64(i), int64(j)) qt.Assert(b, err, qt.IsNil) } - log.Infof("fetched %d transactions (out of %d total) by index, took %s", + log.Infof("fetched %d transactions (out of %d total) by height+index, took %s", numTxs, (i+1)*numTxs, time.Since(startTime)) startTime = time.Now() for j := 0; j < numTxs; j++ { - _, err = idx.GetTxHashReference([]byte(fmt.Sprintf("hash%d%d", i, j))) + _, err = idx.GetTxMetadataByHash([]byte(fmt.Sprintf("hash%d%d", i, j))) qt.Assert(b, err, qt.IsNil) } log.Infof("fetched %d transactions (out of %d total) by hash, took %s", @@ -192,3 +199,84 @@ func BenchmarkNewProcess(b *testing.B) { log.Infof("indexed %d new processes, took %s", numProcesses, time.Since(startTime)) } + +func BenchmarkBlockList(b *testing.B) { + app := vochain.TestBaseApplication(b) + + idx, err := New(app, Options{DataDir: b.TempDir()}) + qt.Assert(b, err, qt.IsNil) + + count := 100000 + + createDummyBlocks(b, idx, count) + + b.ReportAllocs() + b.ResetTimer() + + benchmarkBlockList := func(b *testing.B, + limit int, offset int, chainID string, hash string, proposerAddress string, + ) { + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + blocks, total, err := idx.BlockList(limit, offset, chainID, hash, proposerAddress) + qt.Assert(b, err, qt.IsNil) + qt.Assert(b, blocks, qt.HasLen, limit, qt.Commentf("%+v", blocks)) + qt.Assert(b, blocks[0].TxCount, qt.Equals, int64(0)) + qt.Assert(b, total, qt.Equals, uint64(count)) + } + } + + // Run sub-benchmarks with different limits and filters + b.Run("BlockListLimit1", func(b *testing.B) { + benchmarkBlockList(b, 1, 0, "", "", "") + }) + + b.Run("BlockListLimit10", func(b *testing.B) { + benchmarkBlockList(b, 10, 0, "", "", "") + }) + + b.Run("BlockListLimit100", func(b *testing.B) { + benchmarkBlockList(b, 100, 0, "", "", "") + }) + + b.Run("BlockListOffset", func(b *testing.B) { + benchmarkBlockList(b, 10, count/2, "", "", "") + }) + + b.Run("BlockListWithChainID", func(b *testing.B) { + benchmarkBlockList(b, 10, 0, "test", "", "") + }) + + b.Run("BlockListWithHashSubstr", func(b *testing.B) { + benchmarkBlockList(b, 10, 0, "", "cafe", "") + }) + b.Run("BlockListWithHashExact", func(b *testing.B) { + benchmarkBlockList(b, 10, 0, "", "cafecafecafecafecafecafecafecafecafecafecafecafecafecafecafecafe", "") + }) +} + +func createDummyBlocks(b *testing.B, idx *Indexer, n int) { + idx.blockMu.Lock() + defer idx.blockMu.Unlock() + + queries := idx.blockTxQueries() + for h := 1; h <= n; h++ { + _, err := queries.CreateBlock(context.TODO(), indexerdb.CreateBlockParams{ + ChainID: "test", + Height: int64(h), + Time: time.Now(), + Hash: nonNullBytes([]byte{ + 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, + 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, 0xca, 0xfe, + }), + ProposerAddress: nonNullBytes([]byte{0xfe, 0xde}), + LastBlockHash: nonNullBytes([]byte{0xca, 0xfe}), + }, + ) + qt.Assert(b, err, qt.IsNil) + } + err := idx.blockTx.Commit() + qt.Assert(b, err, qt.IsNil) +} diff --git a/vochain/indexer/block.go b/vochain/indexer/block.go index e40a5fdfb..b6528e890 100644 --- a/vochain/indexer/block.go +++ b/vochain/indexer/block.go @@ -7,35 +7,94 @@ import ( "fmt" "time" - "go.vocdoni.io/dvote/log" indexerdb "go.vocdoni.io/dvote/vochain/indexer/db" - "go.vocdoni.io/dvote/vochain/state" + "go.vocdoni.io/dvote/vochain/indexer/indexertypes" ) // ErrBlockNotFound is returned if the block is not found in the indexer database. var ErrBlockNotFound = fmt.Errorf("block not found") -func (idx *Indexer) OnBeginBlock(bb state.BeginBlock) { - idx.blockMu.Lock() - defer idx.blockMu.Unlock() - queries := idx.blockTxQueries() - if _, err := queries.CreateBlock(context.TODO(), indexerdb.CreateBlockParams{ - Height: bb.Height, - Time: bb.Time, - DataHash: nonNullBytes(bb.DataHash), - }); err != nil { - log.Errorw(err, "cannot index new block") +// BlockTimestamp returns the timestamp of the block at the given height +func (idx *Indexer) BlockTimestamp(height int64) (time.Time, error) { + block, err := idx.BlockByHeight(height) + if err != nil { + return time.Time{}, err } + return block.Time, nil } -// BlockTimestamp returns the timestamp of the block at the given height -func (idx *Indexer) BlockTimestamp(height int64) (time.Time, error) { - block, err := idx.readOnlyQuery.GetBlock(context.TODO(), height) +// BlockByHeight returns the available information of the block at the given height +func (idx *Indexer) BlockByHeight(height int64) (*indexertypes.Block, error) { + block, err := idx.readOnlyQuery.GetBlockByHeight(context.TODO(), height) if err != nil { if errors.Is(err, sql.ErrNoRows) { - return time.Time{}, ErrBlockNotFound + return nil, ErrBlockNotFound } - return time.Time{}, err + return nil, err } - return block.Time, nil + return indexertypes.BlockFromDB(&block), nil +} + +// BlockByHash returns the available information of the block with the given hash +func (idx *Indexer) BlockByHash(hash []byte) (*indexertypes.Block, error) { + block, err := idx.readOnlyQuery.GetBlockByHash(context.TODO(), hash) + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return nil, ErrBlockNotFound + } + return nil, err + } + return indexertypes.BlockFromDB(&block), nil +} + +// BlockList returns the list of blocks indexed. +// chainID, hash, proposerAddress are optional, if declared as zero-value will be ignored. +// The first one returned is the newest, so they are in descending order. +func (idx *Indexer) BlockList(limit, offset int, chainID, hash, proposerAddress string) ([]*indexertypes.Block, uint64, error) { + if offset < 0 { + return nil, 0, fmt.Errorf("invalid value: offset cannot be %d", offset) + } + if limit <= 0 { + return nil, 0, fmt.Errorf("invalid value: limit cannot be %d", limit) + } + results, err := idx.readOnlyQuery.SearchBlocks(context.TODO(), indexerdb.SearchBlocksParams{ + Limit: int64(limit), + Offset: int64(offset), + ChainID: chainID, + HashSubstr: hash, + ProposerAddress: proposerAddress, + }) + if err != nil { + return nil, 0, err + } + list := []*indexertypes.Block{} + for _, row := range results { + list = append(list, indexertypes.BlockFromDBRow(&row)) + } + count, err := idx.CountBlocks(chainID, hash, proposerAddress) + if err != nil { + return nil, 0, err + } + return list, count, nil +} + +// CountBlocks returns how many blocks are indexed. +// If all args passed are empty ("") it will return the last block height, as an optimization. +func (idx *Indexer) CountBlocks(chainID, hash, proposerAddress string) (uint64, error) { + if chainID == "" && hash == "" && proposerAddress == "" { + count, err := idx.readOnlyQuery.LastBlockHeight(context.TODO()) + if err != nil { + return 0, err + } + return uint64(count), nil + } + count, err := idx.readOnlyQuery.CountBlocks(context.TODO(), indexerdb.CountBlocksParams{ + ChainID: chainID, + HashSubstr: hash, + ProposerAddress: proposerAddress, + }) + if err != nil { + return 0, err + } + return uint64(count), nil } diff --git a/vochain/indexer/db/account.sql.go b/vochain/indexer/db/account.sql.go index 9280ea315..75ceffc85 100644 --- a/vochain/indexer/db/account.sql.go +++ b/vochain/indexer/db/account.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.25.0 +// sqlc v1.27.0 // source: account.sql package indexerdb diff --git a/vochain/indexer/db/blocks.sql.go b/vochain/indexer/db/blocks.sql.go index ffa3fa896..a78f722ea 100644 --- a/vochain/indexer/db/blocks.sql.go +++ b/vochain/indexer/db/blocks.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.25.0 +// sqlc v1.27.0 // source: blocks.sql package indexerdb @@ -11,33 +11,197 @@ import ( "time" ) +const countBlocks = `-- name: CountBlocks :one +SELECT COUNT(*) +FROM blocks AS b +WHERE ( + (?1 = '' OR b.chain_id = ?1) + AND LENGTH(?2) <= 64 -- if passed arg is longer, then just abort the query + AND ( + ?2 = '' + OR (LENGTH(?2) = 64 AND LOWER(HEX(b.hash)) = LOWER(?2)) + OR (LENGTH(?2) < 64 AND INSTR(LOWER(HEX(b.hash)), LOWER(?2)) > 0) + -- TODO: consider keeping an hash_hex column for faster searches + ) + AND (?3 = '' OR LOWER(HEX(b.proposer_address)) = LOWER(?3)) +) +` + +type CountBlocksParams struct { + ChainID interface{} + HashSubstr interface{} + ProposerAddress interface{} +} + +func (q *Queries) CountBlocks(ctx context.Context, arg CountBlocksParams) (int64, error) { + row := q.queryRow(ctx, q.countBlocksStmt, countBlocks, arg.ChainID, arg.HashSubstr, arg.ProposerAddress) + var count int64 + err := row.Scan(&count) + return count, err +} + const createBlock = `-- name: CreateBlock :execresult INSERT INTO blocks( - height, time, data_hash + chain_id, height, time, hash, proposer_address, last_block_hash ) VALUES ( - ?, ?, ? + ?, ?, ?, ?, ?, ? ) +ON CONFLICT(height) DO UPDATE +SET chain_id = excluded.chain_id, + time = excluded.time, + hash = excluded.hash, + proposer_address = excluded.proposer_address, + last_block_hash = excluded.last_block_hash ` type CreateBlockParams struct { - Height int64 - Time time.Time - DataHash []byte + ChainID string + Height int64 + Time time.Time + Hash []byte + ProposerAddress []byte + LastBlockHash []byte } func (q *Queries) CreateBlock(ctx context.Context, arg CreateBlockParams) (sql.Result, error) { - return q.exec(ctx, q.createBlockStmt, createBlock, arg.Height, arg.Time, arg.DataHash) + return q.exec(ctx, q.createBlockStmt, createBlock, + arg.ChainID, + arg.Height, + arg.Time, + arg.Hash, + arg.ProposerAddress, + arg.LastBlockHash, + ) +} + +const getBlockByHash = `-- name: GetBlockByHash :one +SELECT height, time, chain_id, hash, proposer_address, last_block_hash FROM blocks +WHERE hash = ? +LIMIT 1 +` + +func (q *Queries) GetBlockByHash(ctx context.Context, hash []byte) (Block, error) { + row := q.queryRow(ctx, q.getBlockByHashStmt, getBlockByHash, hash) + var i Block + err := row.Scan( + &i.Height, + &i.Time, + &i.ChainID, + &i.Hash, + &i.ProposerAddress, + &i.LastBlockHash, + ) + return i, err } -const getBlock = `-- name: GetBlock :one -SELECT height, time, data_hash FROM blocks +const getBlockByHeight = `-- name: GetBlockByHeight :one +SELECT height, time, chain_id, hash, proposer_address, last_block_hash FROM blocks WHERE height = ? LIMIT 1 ` -func (q *Queries) GetBlock(ctx context.Context, height int64) (Block, error) { - row := q.queryRow(ctx, q.getBlockStmt, getBlock, height) +func (q *Queries) GetBlockByHeight(ctx context.Context, height int64) (Block, error) { + row := q.queryRow(ctx, q.getBlockByHeightStmt, getBlockByHeight, height) var i Block - err := row.Scan(&i.Height, &i.Time, &i.DataHash) + err := row.Scan( + &i.Height, + &i.Time, + &i.ChainID, + &i.Hash, + &i.ProposerAddress, + &i.LastBlockHash, + ) return i, err } + +const lastBlockHeight = `-- name: LastBlockHeight :one +SELECT height FROM blocks +ORDER BY height DESC +LIMIT 1 +` + +func (q *Queries) LastBlockHeight(ctx context.Context) (int64, error) { + row := q.queryRow(ctx, q.lastBlockHeightStmt, lastBlockHeight) + var height int64 + err := row.Scan(&height) + return height, err +} + +const searchBlocks = `-- name: SearchBlocks :many +SELECT + b.height, b.time, b.chain_id, b.hash, b.proposer_address, b.last_block_hash, + COUNT(t.block_index) AS tx_count +FROM blocks AS b +LEFT JOIN transactions AS t + ON b.height = t.block_height +WHERE ( + (?1 = '' OR b.chain_id = ?1) + AND LENGTH(?2) <= 64 -- if passed arg is longer, then just abort the query + AND ( + ?2 = '' + OR (LENGTH(?2) = 64 AND LOWER(HEX(b.hash)) = LOWER(?2)) + OR (LENGTH(?2) < 64 AND INSTR(LOWER(HEX(b.hash)), LOWER(?2)) > 0) + -- TODO: consider keeping an hash_hex column for faster searches + ) + AND (?3 = '' OR LOWER(HEX(b.proposer_address)) = LOWER(?3)) +) +GROUP BY b.height +ORDER BY b.height DESC +LIMIT ?5 +OFFSET ?4 +` + +type SearchBlocksParams struct { + ChainID interface{} + HashSubstr interface{} + ProposerAddress interface{} + Offset int64 + Limit int64 +} + +type SearchBlocksRow struct { + Height int64 + Time time.Time + ChainID string + Hash []byte + ProposerAddress []byte + LastBlockHash []byte + TxCount int64 +} + +func (q *Queries) SearchBlocks(ctx context.Context, arg SearchBlocksParams) ([]SearchBlocksRow, error) { + rows, err := q.query(ctx, q.searchBlocksStmt, searchBlocks, + arg.ChainID, + arg.HashSubstr, + arg.ProposerAddress, + arg.Offset, + arg.Limit, + ) + if err != nil { + return nil, err + } + defer rows.Close() + var items []SearchBlocksRow + for rows.Next() { + var i SearchBlocksRow + if err := rows.Scan( + &i.Height, + &i.Time, + &i.ChainID, + &i.Hash, + &i.ProposerAddress, + &i.LastBlockHash, + &i.TxCount, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} diff --git a/vochain/indexer/db/db.go b/vochain/indexer/db/db.go index 3695e8b73..bcbb12f84 100644 --- a/vochain/indexer/db/db.go +++ b/vochain/indexer/db/db.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.25.0 +// sqlc v1.27.0 package indexerdb @@ -30,12 +30,18 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) { if q.countAccountsStmt, err = db.PrepareContext(ctx, countAccounts); err != nil { return nil, fmt.Errorf("error preparing query CountAccounts: %w", err) } + if q.countBlocksStmt, err = db.PrepareContext(ctx, countBlocks); err != nil { + return nil, fmt.Errorf("error preparing query CountBlocks: %w", err) + } if q.countTokenTransfersByAccountStmt, err = db.PrepareContext(ctx, countTokenTransfersByAccount); err != nil { return nil, fmt.Errorf("error preparing query CountTokenTransfersByAccount: %w", err) } if q.countTransactionsStmt, err = db.PrepareContext(ctx, countTransactions); err != nil { return nil, fmt.Errorf("error preparing query CountTransactions: %w", err) } + if q.countTransactionsByHeightStmt, err = db.PrepareContext(ctx, countTransactionsByHeight); err != nil { + return nil, fmt.Errorf("error preparing query CountTransactionsByHeight: %w", err) + } if q.countVotesStmt, err = db.PrepareContext(ctx, countVotes); err != nil { return nil, fmt.Errorf("error preparing query CountVotes: %w", err) } @@ -60,8 +66,11 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) { if q.createVoteStmt, err = db.PrepareContext(ctx, createVote); err != nil { return nil, fmt.Errorf("error preparing query CreateVote: %w", err) } - if q.getBlockStmt, err = db.PrepareContext(ctx, getBlock); err != nil { - return nil, fmt.Errorf("error preparing query GetBlock: %w", err) + if q.getBlockByHashStmt, err = db.PrepareContext(ctx, getBlockByHash); err != nil { + return nil, fmt.Errorf("error preparing query GetBlockByHash: %w", err) + } + if q.getBlockByHeightStmt, err = db.PrepareContext(ctx, getBlockByHeight); err != nil { + return nil, fmt.Errorf("error preparing query GetBlockByHeight: %w", err) } if q.getEntityCountStmt, err = db.PrepareContext(ctx, getEntityCount); err != nil { return nil, fmt.Errorf("error preparing query GetEntityCount: %w", err) @@ -81,21 +90,24 @@ func Prepare(ctx context.Context, db DBTX) (*Queries, error) { if q.getTokenTransferStmt, err = db.PrepareContext(ctx, getTokenTransfer); err != nil { return nil, fmt.Errorf("error preparing query GetTokenTransfer: %w", err) } - if q.getTransactionStmt, err = db.PrepareContext(ctx, getTransaction); err != nil { - return nil, fmt.Errorf("error preparing query GetTransaction: %w", err) - } if q.getTransactionByHashStmt, err = db.PrepareContext(ctx, getTransactionByHash); err != nil { return nil, fmt.Errorf("error preparing query GetTransactionByHash: %w", err) } - if q.getTxReferenceByBlockHeightAndBlockIndexStmt, err = db.PrepareContext(ctx, getTxReferenceByBlockHeightAndBlockIndex); err != nil { - return nil, fmt.Errorf("error preparing query GetTxReferenceByBlockHeightAndBlockIndex: %w", err) + if q.getTransactionByHeightAndIndexStmt, err = db.PrepareContext(ctx, getTransactionByHeightAndIndex); err != nil { + return nil, fmt.Errorf("error preparing query GetTransactionByHeightAndIndex: %w", err) } if q.getVoteStmt, err = db.PrepareContext(ctx, getVote); err != nil { return nil, fmt.Errorf("error preparing query GetVote: %w", err) } + if q.lastBlockHeightStmt, err = db.PrepareContext(ctx, lastBlockHeight); err != nil { + return nil, fmt.Errorf("error preparing query LastBlockHeight: %w", err) + } if q.searchAccountsStmt, err = db.PrepareContext(ctx, searchAccounts); err != nil { return nil, fmt.Errorf("error preparing query SearchAccounts: %w", err) } + if q.searchBlocksStmt, err = db.PrepareContext(ctx, searchBlocks); err != nil { + return nil, fmt.Errorf("error preparing query SearchBlocks: %w", err) + } if q.searchEntitiesStmt, err = db.PrepareContext(ctx, searchEntities); err != nil { return nil, fmt.Errorf("error preparing query SearchEntities: %w", err) } @@ -147,6 +159,11 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing countAccountsStmt: %w", cerr) } } + if q.countBlocksStmt != nil { + if cerr := q.countBlocksStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing countBlocksStmt: %w", cerr) + } + } if q.countTokenTransfersByAccountStmt != nil { if cerr := q.countTokenTransfersByAccountStmt.Close(); cerr != nil { err = fmt.Errorf("error closing countTokenTransfersByAccountStmt: %w", cerr) @@ -157,6 +174,11 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing countTransactionsStmt: %w", cerr) } } + if q.countTransactionsByHeightStmt != nil { + if cerr := q.countTransactionsByHeightStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing countTransactionsByHeightStmt: %w", cerr) + } + } if q.countVotesStmt != nil { if cerr := q.countVotesStmt.Close(); cerr != nil { err = fmt.Errorf("error closing countVotesStmt: %w", cerr) @@ -197,9 +219,14 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing createVoteStmt: %w", cerr) } } - if q.getBlockStmt != nil { - if cerr := q.getBlockStmt.Close(); cerr != nil { - err = fmt.Errorf("error closing getBlockStmt: %w", cerr) + if q.getBlockByHashStmt != nil { + if cerr := q.getBlockByHashStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing getBlockByHashStmt: %w", cerr) + } + } + if q.getBlockByHeightStmt != nil { + if cerr := q.getBlockByHeightStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing getBlockByHeightStmt: %w", cerr) } } if q.getEntityCountStmt != nil { @@ -232,19 +259,14 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing getTokenTransferStmt: %w", cerr) } } - if q.getTransactionStmt != nil { - if cerr := q.getTransactionStmt.Close(); cerr != nil { - err = fmt.Errorf("error closing getTransactionStmt: %w", cerr) - } - } if q.getTransactionByHashStmt != nil { if cerr := q.getTransactionByHashStmt.Close(); cerr != nil { err = fmt.Errorf("error closing getTransactionByHashStmt: %w", cerr) } } - if q.getTxReferenceByBlockHeightAndBlockIndexStmt != nil { - if cerr := q.getTxReferenceByBlockHeightAndBlockIndexStmt.Close(); cerr != nil { - err = fmt.Errorf("error closing getTxReferenceByBlockHeightAndBlockIndexStmt: %w", cerr) + if q.getTransactionByHeightAndIndexStmt != nil { + if cerr := q.getTransactionByHeightAndIndexStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing getTransactionByHeightAndIndexStmt: %w", cerr) } } if q.getVoteStmt != nil { @@ -252,11 +274,21 @@ func (q *Queries) Close() error { err = fmt.Errorf("error closing getVoteStmt: %w", cerr) } } + if q.lastBlockHeightStmt != nil { + if cerr := q.lastBlockHeightStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing lastBlockHeightStmt: %w", cerr) + } + } if q.searchAccountsStmt != nil { if cerr := q.searchAccountsStmt.Close(); cerr != nil { err = fmt.Errorf("error closing searchAccountsStmt: %w", cerr) } } + if q.searchBlocksStmt != nil { + if cerr := q.searchBlocksStmt.Close(); cerr != nil { + err = fmt.Errorf("error closing searchBlocksStmt: %w", cerr) + } + } if q.searchEntitiesStmt != nil { if cerr := q.searchEntitiesStmt.Close(); cerr != nil { err = fmt.Errorf("error closing searchEntitiesStmt: %w", cerr) @@ -354,85 +386,93 @@ func (q *Queries) queryRow(ctx context.Context, stmt *sql.Stmt, query string, ar } type Queries struct { - db DBTX - tx *sql.Tx - computeProcessVoteCountStmt *sql.Stmt - countAccountsStmt *sql.Stmt - countTokenTransfersByAccountStmt *sql.Stmt - countTransactionsStmt *sql.Stmt - countVotesStmt *sql.Stmt - createAccountStmt *sql.Stmt - createBlockStmt *sql.Stmt - createProcessStmt *sql.Stmt - createTokenFeeStmt *sql.Stmt - createTokenTransferStmt *sql.Stmt - createTransactionStmt *sql.Stmt - createVoteStmt *sql.Stmt - getBlockStmt *sql.Stmt - getEntityCountStmt *sql.Stmt - getProcessStmt *sql.Stmt - getProcessCountStmt *sql.Stmt - getProcessIDsByFinalResultsStmt *sql.Stmt - getProcessStatusStmt *sql.Stmt - getTokenTransferStmt *sql.Stmt - getTransactionStmt *sql.Stmt - getTransactionByHashStmt *sql.Stmt - getTxReferenceByBlockHeightAndBlockIndexStmt *sql.Stmt - getVoteStmt *sql.Stmt - searchAccountsStmt *sql.Stmt - searchEntitiesStmt *sql.Stmt - searchProcessesStmt *sql.Stmt - searchTokenFeesStmt *sql.Stmt - searchTokenTransfersStmt *sql.Stmt - searchTransactionsStmt *sql.Stmt - searchVotesStmt *sql.Stmt - setProcessResultsCancelledStmt *sql.Stmt - setProcessResultsReadyStmt *sql.Stmt - updateProcessEndDateStmt *sql.Stmt - updateProcessFromStateStmt *sql.Stmt - updateProcessResultByIDStmt *sql.Stmt - updateProcessResultsStmt *sql.Stmt + db DBTX + tx *sql.Tx + computeProcessVoteCountStmt *sql.Stmt + countAccountsStmt *sql.Stmt + countBlocksStmt *sql.Stmt + countTokenTransfersByAccountStmt *sql.Stmt + countTransactionsStmt *sql.Stmt + countTransactionsByHeightStmt *sql.Stmt + countVotesStmt *sql.Stmt + createAccountStmt *sql.Stmt + createBlockStmt *sql.Stmt + createProcessStmt *sql.Stmt + createTokenFeeStmt *sql.Stmt + createTokenTransferStmt *sql.Stmt + createTransactionStmt *sql.Stmt + createVoteStmt *sql.Stmt + getBlockByHashStmt *sql.Stmt + getBlockByHeightStmt *sql.Stmt + getEntityCountStmt *sql.Stmt + getProcessStmt *sql.Stmt + getProcessCountStmt *sql.Stmt + getProcessIDsByFinalResultsStmt *sql.Stmt + getProcessStatusStmt *sql.Stmt + getTokenTransferStmt *sql.Stmt + getTransactionByHashStmt *sql.Stmt + getTransactionByHeightAndIndexStmt *sql.Stmt + getVoteStmt *sql.Stmt + lastBlockHeightStmt *sql.Stmt + searchAccountsStmt *sql.Stmt + searchBlocksStmt *sql.Stmt + searchEntitiesStmt *sql.Stmt + searchProcessesStmt *sql.Stmt + searchTokenFeesStmt *sql.Stmt + searchTokenTransfersStmt *sql.Stmt + searchTransactionsStmt *sql.Stmt + searchVotesStmt *sql.Stmt + setProcessResultsCancelledStmt *sql.Stmt + setProcessResultsReadyStmt *sql.Stmt + updateProcessEndDateStmt *sql.Stmt + updateProcessFromStateStmt *sql.Stmt + updateProcessResultByIDStmt *sql.Stmt + updateProcessResultsStmt *sql.Stmt } func (q *Queries) WithTx(tx *sql.Tx) *Queries { return &Queries{ - db: tx, - tx: tx, - computeProcessVoteCountStmt: q.computeProcessVoteCountStmt, - countAccountsStmt: q.countAccountsStmt, - countTokenTransfersByAccountStmt: q.countTokenTransfersByAccountStmt, - countTransactionsStmt: q.countTransactionsStmt, - countVotesStmt: q.countVotesStmt, - createAccountStmt: q.createAccountStmt, - createBlockStmt: q.createBlockStmt, - createProcessStmt: q.createProcessStmt, - createTokenFeeStmt: q.createTokenFeeStmt, - createTokenTransferStmt: q.createTokenTransferStmt, - createTransactionStmt: q.createTransactionStmt, - createVoteStmt: q.createVoteStmt, - getBlockStmt: q.getBlockStmt, - getEntityCountStmt: q.getEntityCountStmt, - getProcessStmt: q.getProcessStmt, - getProcessCountStmt: q.getProcessCountStmt, - getProcessIDsByFinalResultsStmt: q.getProcessIDsByFinalResultsStmt, - getProcessStatusStmt: q.getProcessStatusStmt, - getTokenTransferStmt: q.getTokenTransferStmt, - getTransactionStmt: q.getTransactionStmt, - getTransactionByHashStmt: q.getTransactionByHashStmt, - getTxReferenceByBlockHeightAndBlockIndexStmt: q.getTxReferenceByBlockHeightAndBlockIndexStmt, - getVoteStmt: q.getVoteStmt, - searchAccountsStmt: q.searchAccountsStmt, - searchEntitiesStmt: q.searchEntitiesStmt, - searchProcessesStmt: q.searchProcessesStmt, - searchTokenFeesStmt: q.searchTokenFeesStmt, - searchTokenTransfersStmt: q.searchTokenTransfersStmt, - searchTransactionsStmt: q.searchTransactionsStmt, - searchVotesStmt: q.searchVotesStmt, - setProcessResultsCancelledStmt: q.setProcessResultsCancelledStmt, - setProcessResultsReadyStmt: q.setProcessResultsReadyStmt, - updateProcessEndDateStmt: q.updateProcessEndDateStmt, - updateProcessFromStateStmt: q.updateProcessFromStateStmt, - updateProcessResultByIDStmt: q.updateProcessResultByIDStmt, - updateProcessResultsStmt: q.updateProcessResultsStmt, + db: tx, + tx: tx, + computeProcessVoteCountStmt: q.computeProcessVoteCountStmt, + countAccountsStmt: q.countAccountsStmt, + countBlocksStmt: q.countBlocksStmt, + countTokenTransfersByAccountStmt: q.countTokenTransfersByAccountStmt, + countTransactionsStmt: q.countTransactionsStmt, + countTransactionsByHeightStmt: q.countTransactionsByHeightStmt, + countVotesStmt: q.countVotesStmt, + createAccountStmt: q.createAccountStmt, + createBlockStmt: q.createBlockStmt, + createProcessStmt: q.createProcessStmt, + createTokenFeeStmt: q.createTokenFeeStmt, + createTokenTransferStmt: q.createTokenTransferStmt, + createTransactionStmt: q.createTransactionStmt, + createVoteStmt: q.createVoteStmt, + getBlockByHashStmt: q.getBlockByHashStmt, + getBlockByHeightStmt: q.getBlockByHeightStmt, + getEntityCountStmt: q.getEntityCountStmt, + getProcessStmt: q.getProcessStmt, + getProcessCountStmt: q.getProcessCountStmt, + getProcessIDsByFinalResultsStmt: q.getProcessIDsByFinalResultsStmt, + getProcessStatusStmt: q.getProcessStatusStmt, + getTokenTransferStmt: q.getTokenTransferStmt, + getTransactionByHashStmt: q.getTransactionByHashStmt, + getTransactionByHeightAndIndexStmt: q.getTransactionByHeightAndIndexStmt, + getVoteStmt: q.getVoteStmt, + lastBlockHeightStmt: q.lastBlockHeightStmt, + searchAccountsStmt: q.searchAccountsStmt, + searchBlocksStmt: q.searchBlocksStmt, + searchEntitiesStmt: q.searchEntitiesStmt, + searchProcessesStmt: q.searchProcessesStmt, + searchTokenFeesStmt: q.searchTokenFeesStmt, + searchTokenTransfersStmt: q.searchTokenTransfersStmt, + searchTransactionsStmt: q.searchTransactionsStmt, + searchVotesStmt: q.searchVotesStmt, + setProcessResultsCancelledStmt: q.setProcessResultsCancelledStmt, + setProcessResultsReadyStmt: q.setProcessResultsReadyStmt, + updateProcessEndDateStmt: q.updateProcessEndDateStmt, + updateProcessFromStateStmt: q.updateProcessFromStateStmt, + updateProcessResultByIDStmt: q.updateProcessResultByIDStmt, + updateProcessResultsStmt: q.updateProcessResultsStmt, } } diff --git a/vochain/indexer/db/models.go b/vochain/indexer/db/models.go index 08a6e0e2b..2f25a2817 100644 --- a/vochain/indexer/db/models.go +++ b/vochain/indexer/db/models.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.25.0 +// sqlc v1.27.0 package indexerdb @@ -11,9 +11,12 @@ import ( ) type Block struct { - Height int64 - Time time.Time - DataHash []byte + Height int64 + Time time.Time + ChainID string + Hash []byte + ProposerAddress []byte + LastBlockHash []byte } type Process struct { @@ -57,9 +60,12 @@ type TokenTransfer struct { } type Transaction struct { - ID int64 Hash types.Hash BlockHeight int64 BlockIndex int64 Type string + Subtype string + RawTx []byte + Signature []byte + Signer []byte } diff --git a/vochain/indexer/db/processes.sql.go b/vochain/indexer/db/processes.sql.go index b274c802c..66ed2861b 100644 --- a/vochain/indexer/db/processes.sql.go +++ b/vochain/indexer/db/processes.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.25.0 +// sqlc v1.27.0 // source: processes.sql package indexerdb diff --git a/vochain/indexer/db/token_fees.sql.go b/vochain/indexer/db/token_fees.sql.go index 0bbe20281..ef44efbe4 100644 --- a/vochain/indexer/db/token_fees.sql.go +++ b/vochain/indexer/db/token_fees.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.25.0 +// sqlc v1.27.0 // source: token_fees.sql package indexerdb diff --git a/vochain/indexer/db/token_transfers.sql.go b/vochain/indexer/db/token_transfers.sql.go index 7e46f74da..2d8a1d129 100644 --- a/vochain/indexer/db/token_transfers.sql.go +++ b/vochain/indexer/db/token_transfers.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.25.0 +// sqlc v1.27.0 // source: token_transfers.sql package indexerdb diff --git a/vochain/indexer/db/transactions.sql.go b/vochain/indexer/db/transactions.sql.go index 2d06f135a..909053e1c 100644 --- a/vochain/indexer/db/transactions.sql.go +++ b/vochain/indexer/db/transactions.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.25.0 +// sqlc v1.27.0 // source: transactions.sql package indexerdb @@ -23,12 +23,32 @@ func (q *Queries) CountTransactions(ctx context.Context) (int64, error) { return count, err } +const countTransactionsByHeight = `-- name: CountTransactionsByHeight :one +SELECT COUNT(*) FROM transactions +WHERE block_height = ? +` + +func (q *Queries) CountTransactionsByHeight(ctx context.Context, blockHeight int64) (int64, error) { + row := q.queryRow(ctx, q.countTransactionsByHeightStmt, countTransactionsByHeight, blockHeight) + var count int64 + err := row.Scan(&count) + return count, err +} + const createTransaction = `-- name: CreateTransaction :execresult INSERT INTO transactions ( - hash, block_height, block_index, type + hash, block_height, block_index, type, subtype, raw_tx, signature, signer ) VALUES ( - ?, ?, ?, ? + ?, ?, ?, ?, ?, ?, ?, ? ) +ON CONFLICT(hash) DO UPDATE +SET block_height = excluded.block_height, + block_index = excluded.block_index, + type = excluded.type, + subtype = excluded.subtype, + raw_tx = excluded.raw_tx, + signature = excluded.signature, + signer = excluded.signer ` type CreateTransactionParams struct { @@ -36,6 +56,10 @@ type CreateTransactionParams struct { BlockHeight int64 BlockIndex int64 Type string + Subtype string + RawTx []byte + Signature []byte + Signer []byte } func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionParams) (sql.Result, error) { @@ -44,30 +68,15 @@ func (q *Queries) CreateTransaction(ctx context.Context, arg CreateTransactionPa arg.BlockHeight, arg.BlockIndex, arg.Type, + arg.Subtype, + arg.RawTx, + arg.Signature, + arg.Signer, ) } -const getTransaction = `-- name: GetTransaction :one -SELECT id, hash, block_height, block_index, type FROM transactions -WHERE id = ? -LIMIT 1 -` - -func (q *Queries) GetTransaction(ctx context.Context, id int64) (Transaction, error) { - row := q.queryRow(ctx, q.getTransactionStmt, getTransaction, id) - var i Transaction - err := row.Scan( - &i.ID, - &i.Hash, - &i.BlockHeight, - &i.BlockIndex, - &i.Type, - ) - return i, err -} - const getTransactionByHash = `-- name: GetTransactionByHash :one -SELECT id, hash, block_height, block_index, type FROM transactions +SELECT hash, block_height, block_index, type, subtype, raw_tx, signature, signer FROM transactions WHERE hash = ? LIMIT 1 ` @@ -76,77 +85,95 @@ func (q *Queries) GetTransactionByHash(ctx context.Context, hash types.Hash) (Tr row := q.queryRow(ctx, q.getTransactionByHashStmt, getTransactionByHash, hash) var i Transaction err := row.Scan( - &i.ID, &i.Hash, &i.BlockHeight, &i.BlockIndex, &i.Type, + &i.Subtype, + &i.RawTx, + &i.Signature, + &i.Signer, ) return i, err } -const getTxReferenceByBlockHeightAndBlockIndex = `-- name: GetTxReferenceByBlockHeightAndBlockIndex :one -SELECT id, hash, block_height, block_index, type FROM transactions +const getTransactionByHeightAndIndex = `-- name: GetTransactionByHeightAndIndex :one +SELECT hash, block_height, block_index, type, subtype, raw_tx, signature, signer FROM transactions WHERE block_height = ? AND block_index = ? LIMIT 1 ` -type GetTxReferenceByBlockHeightAndBlockIndexParams struct { +type GetTransactionByHeightAndIndexParams struct { BlockHeight int64 BlockIndex int64 } -func (q *Queries) GetTxReferenceByBlockHeightAndBlockIndex(ctx context.Context, arg GetTxReferenceByBlockHeightAndBlockIndexParams) (Transaction, error) { - row := q.queryRow(ctx, q.getTxReferenceByBlockHeightAndBlockIndexStmt, getTxReferenceByBlockHeightAndBlockIndex, arg.BlockHeight, arg.BlockIndex) +func (q *Queries) GetTransactionByHeightAndIndex(ctx context.Context, arg GetTransactionByHeightAndIndexParams) (Transaction, error) { + row := q.queryRow(ctx, q.getTransactionByHeightAndIndexStmt, getTransactionByHeightAndIndex, arg.BlockHeight, arg.BlockIndex) var i Transaction err := row.Scan( - &i.ID, &i.Hash, &i.BlockHeight, &i.BlockIndex, &i.Type, + &i.Subtype, + &i.RawTx, + &i.Signature, + &i.Signer, ) return i, err } const searchTransactions = `-- name: SearchTransactions :many -WITH results AS ( - SELECT id, hash, block_height, block_index, type - FROM transactions - WHERE ( - (?3 = 0 OR block_height = ?3) - AND (?4 = '' OR LOWER(type) = LOWER(?4)) +SELECT hash, block_height, block_index, type, subtype, raw_tx, signature, signer, COUNT(*) OVER() AS total_count +FROM transactions +WHERE + (?1 = 0 OR block_height = ?1) + AND (?2 = '' OR LOWER(type) = LOWER(?2)) + AND (?3 = '' OR LOWER(subtype) = LOWER(?3)) + AND (?4 = '' OR LOWER(HEX(signer)) = LOWER(?4)) + AND ( + ?5 = '' + OR (LENGTH(?5) = 64 AND LOWER(HEX(hash)) = LOWER(?5)) + OR (LENGTH(?5) < 64 AND INSTR(LOWER(HEX(hash)), LOWER(?5)) > 0) + -- TODO: consider keeping an hash_hex column for faster searches ) -) -SELECT id, hash, block_height, block_index, type, COUNT(*) OVER() AS total_count -FROM results -ORDER BY id DESC -LIMIT ?2 -OFFSET ?1 +ORDER BY block_height DESC, block_index DESC +LIMIT ?7 +OFFSET ?6 ` type SearchTransactionsParams struct { - Offset int64 - Limit int64 BlockHeight interface{} TxType interface{} + TxSubtype interface{} + TxSigner interface{} + HashSubstr interface{} + Offset int64 + Limit int64 } type SearchTransactionsRow struct { - ID int64 - Hash []byte + Hash types.Hash BlockHeight int64 BlockIndex int64 Type string + Subtype string + RawTx []byte + Signature []byte + Signer []byte TotalCount int64 } func (q *Queries) SearchTransactions(ctx context.Context, arg SearchTransactionsParams) ([]SearchTransactionsRow, error) { rows, err := q.query(ctx, q.searchTransactionsStmt, searchTransactions, - arg.Offset, - arg.Limit, arg.BlockHeight, arg.TxType, + arg.TxSubtype, + arg.TxSigner, + arg.HashSubstr, + arg.Offset, + arg.Limit, ) if err != nil { return nil, err @@ -156,11 +183,14 @@ func (q *Queries) SearchTransactions(ctx context.Context, arg SearchTransactions for rows.Next() { var i SearchTransactionsRow if err := rows.Scan( - &i.ID, &i.Hash, &i.BlockHeight, &i.BlockIndex, &i.Type, + &i.Subtype, + &i.RawTx, + &i.Signature, + &i.Signer, &i.TotalCount, ); err != nil { return nil, err diff --git a/vochain/indexer/db/votes.sql.go b/vochain/indexer/db/votes.sql.go index 3c94ae672..48392a768 100644 --- a/vochain/indexer/db/votes.sql.go +++ b/vochain/indexer/db/votes.sql.go @@ -1,6 +1,6 @@ // Code generated by sqlc. DO NOT EDIT. // versions: -// sqlc v1.25.0 +// sqlc v1.27.0 // source: votes.sql package indexerdb diff --git a/vochain/indexer/indexer.go b/vochain/indexer/indexer.go index 43b59323e..37fea31a2 100644 --- a/vochain/indexer/indexer.go +++ b/vochain/indexer/indexer.go @@ -1,6 +1,7 @@ package indexer import ( + "bytes" "context" "database/sql" "embed" @@ -8,6 +9,7 @@ import ( "errors" "fmt" "io" + "maps" "math/big" "os" "path/filepath" @@ -28,7 +30,6 @@ import ( "go.vocdoni.io/proto/build/go/models" "github.com/pressly/goose/v3" - "golang.org/x/exp/maps" // modernc is a pure-Go version, but its errors have less useful info. // We use mattn while developing and testing, and we can swap them later. @@ -36,7 +37,7 @@ import ( _ "github.com/mattn/go-sqlite3" ) -//go:generate go run github.com/sqlc-dev/sqlc/cmd/sqlc@v1.25.0 generate +//go:generate go run github.com/sqlc-dev/sqlc/cmd/sqlc@v1.27.0 generate //go:embed migrations/*.sql var embedMigrations embed.FS @@ -172,6 +173,12 @@ func (idx *Indexer) startDB() error { } goose.SetLogger(log.GooseLogger()) goose.SetBaseFS(embedMigrations) + + if gooseMigrationsPending(idx.readWriteDB, "migrations") { + log.Info("indexer db needs migration, scheduling a reindex after sync") + defer func() { go idx.ReindexBlocks(false) }() + } + if err := goose.Up(idx.readWriteDB, "migrations"); err != nil { return fmt.Errorf("goose up: %w", err) } @@ -249,6 +256,27 @@ func (idx *Indexer) RestoreBackup(path string) error { return nil } +func gooseMigrationsPending(db *sql.DB, dir string) bool { + // Get the latest applied migration version + currentVersion, err := goose.GetDBVersion(db) + if err != nil { + log.Errorf("failed to get current database version: %v", err) + return false + } + + // Collect migrations after the current version + migrations, err := goose.CollectMigrations(dir, currentVersion, goose.MaxVersion) + if err != nil { + if errors.Is(err, goose.ErrNoMigrationFiles) { + return false + } + log.Errorf("failed to collect migrations: %v", err) + return false + } + + return len(migrations) > 0 +} + // SaveBackup backs up the database to a file on disk. // Note that writes to the database may be blocked until the backup finishes, // and an error may occur if a file at path already exists. @@ -402,18 +430,119 @@ func (idx *Indexer) AfterSyncBootstrap(inTest bool) { log.Infof("live results recovery computation finished, took %s", time.Since(startTime)) } +// ReindexBlocks reindexes all blocks found in blockstore +func (idx *Indexer) ReindexBlocks(inTest bool) { + if !inTest { + <-idx.App.WaitUntilSynced() + } + + // Note that holding blockMu means new votes aren't added until the reindex finishes. + idx.blockMu.Lock() + defer idx.blockMu.Unlock() + + if idx.App.Node == nil || idx.App.Node.BlockStore() == nil { + return + } + + idxBlockCount, err := idx.CountBlocks("", "", "") + if err != nil { + log.Warnf("indexer CountBlocks returned error: %s", err) + } + log.Infow("start reindexing", + "blockStoreBase", idx.App.Node.BlockStore().Base(), + "blockStoreHeight", idx.App.Node.BlockStore().Height(), + "indexerBlockCount", idxBlockCount, + ) + queries := idx.blockTxQueries() + for height := idx.App.Node.BlockStore().Base(); height <= idx.App.Node.BlockStore().Height(); height++ { + if b := idx.App.GetBlockByHeight(int64(height)); b != nil { + // Blocks + func() { + idxBlock, err := idx.readOnlyQuery.GetBlockByHeight(context.TODO(), b.Height) + if height%10000 == 1 { + log.Infof("reindexing height %d, updating values (%s, %x, %x, %x) on current row %+v", + height, b.ChainID, b.Hash(), b.ProposerAddress, b.LastBlockID.Hash, idxBlock) + if err := idx.blockTx.Commit(); err != nil { + log.Errorw(err, "could not commit tx") + } + idx.blockTx = nil + queries = idx.blockTxQueries() + } + if err == nil && idxBlock.Time != b.Time { + log.Errorf("while reindexing blocks, block %d timestamp in db (%s) differs from blockstore (%s), leaving untouched", height, idxBlock.Time, b.Time) + return + } + if _, err := queries.CreateBlock(context.TODO(), indexerdb.CreateBlockParams{ + ChainID: b.ChainID, + Height: b.Height, + Time: b.Time, + Hash: nonNullBytes(b.Hash()), + ProposerAddress: nonNullBytes(b.ProposerAddress), + LastBlockHash: nonNullBytes(b.LastBlockID.Hash), + }); err != nil { + log.Errorw(err, "cannot index new block") + } + }() + + // Transactions + func() { + for index, tx := range b.Data.Txs { + idxTx, err := idx.readOnlyQuery.GetTransactionByHeightAndIndex(context.TODO(), indexerdb.GetTransactionByHeightAndIndexParams{ + BlockHeight: b.Height, + BlockIndex: int64(index), + }) + if err == nil && !bytes.Equal(idxTx.Hash, tx.Hash()) { + log.Errorf("while reindexing txs, tx %d/%d hash in db (%x) differs from blockstore (%x), leaving untouched", b.Height, index, idxTx.Hash, tx.Hash()) + return + } + vtx := new(vochaintx.Tx) + if err := vtx.Unmarshal(tx, b.ChainID); err != nil { + log.Errorw(err, fmt.Sprintf("cannot unmarshal tx %d/%d", b.Height, index)) + continue + } + idx.indexTx(vtx, uint32(b.Height), int32(index)) + } + }() + } + } + + if err := idx.blockTx.Commit(); err != nil { + log.Errorw(err, "could not commit tx") + } + idx.blockTx = nil + + log.Infow("finished reindexing", + "blockStoreBase", idx.App.Node.BlockStore().Base(), + "blockStoreHeight", idx.App.Node.BlockStore().Height(), + "indexerBlockCount", idxBlockCount, + ) +} + // Commit is called by the APP when a block is confirmed and included into the chain func (idx *Indexer) Commit(height uint32) error { idx.blockMu.Lock() defer idx.blockMu.Unlock() // Update existing processes - updateProcs := maps.Keys(idx.blockUpdateProcs) - slices.Sort(updateProcs) + updateProcs := slices.Sorted(maps.Keys(idx.blockUpdateProcs)) queries := idx.blockTxQueries() ctx := context.TODO() + // index the new block + if b := idx.App.GetBlockByHeight(int64(height)); b != nil { + if _, err := queries.CreateBlock(context.TODO(), indexerdb.CreateBlockParams{ + ChainID: b.ChainID, + Height: b.Height, + Time: b.Time, + Hash: nonNullBytes(b.Hash()), + ProposerAddress: nonNullBytes(b.ProposerAddress), + LastBlockHash: nonNullBytes(b.LastBlockID.Hash), + }); err != nil { + log.Errorw(err, "cannot index new block") + } + } + for _, pidStr := range updateProcs { pid := types.ProcessID(pidStr) if err := idx.updateProcess(ctx, queries, pid); err != nil { diff --git a/vochain/indexer/indexer_test.go b/vochain/indexer/indexer_test.go index fad19d248..f3dc00ed3 100644 --- a/vochain/indexer/indexer_test.go +++ b/vochain/indexer/indexer_test.go @@ -1392,6 +1392,7 @@ func TestTxIndexer(t *testing.T) { idx.OnNewTx(&vochaintx.Tx{ TxID: getTxID(i, j), TxModelType: "setAccount", + Tx: &models.Tx{Payload: &models.Tx_SetAccount{}}, }, uint32(i), int32(j)) } } @@ -1404,7 +1405,7 @@ func TestTxIndexer(t *testing.T) { for i := 0; i < totalBlocks; i++ { for j := 0; j < txsPerBlock; j++ { - ref, err := idx.GetTransaction(uint64(i*txsPerBlock + j + 1)) + ref, err := idx.GetTransactionByHeightAndIndex(int64(i), int64(j)) qt.Assert(t, err, qt.IsNil) qt.Assert(t, ref.BlockHeight, qt.Equals, uint32(i)) qt.Assert(t, ref.TxBlockIndex, qt.Equals, int32(j)) @@ -1412,28 +1413,25 @@ func TestTxIndexer(t *testing.T) { h := make([]byte, 32) id := getTxID(i, j) copy(h, id[:]) - hashRef, err := idx.GetTxHashReference(h) + hashRef, err := idx.GetTxMetadataByHash(h) qt.Assert(t, err, qt.IsNil) qt.Assert(t, hashRef.BlockHeight, qt.Equals, uint32(i)) qt.Assert(t, hashRef.TxBlockIndex, qt.Equals, int32(j)) } } - txs, _, err := idx.SearchTransactions(15, 0, 0, "") + txs, _, err := idx.SearchTransactions(15, 0, 0, "", "", "", "") qt.Assert(t, err, qt.IsNil) for i, tx := range txs { - // Index is between 1 and totalCount. - qt.Assert(t, tx.Index, qt.Equals, uint64(totalTxs-i)) // BlockIndex and TxBlockIndex start at 0, so subtract 1. qt.Assert(t, tx.BlockHeight, qt.Equals, uint32(totalTxs-i-1)/txsPerBlock) qt.Assert(t, tx.TxBlockIndex, qt.Equals, int32(totalTxs-i-1)%txsPerBlock) qt.Assert(t, tx.TxType, qt.Equals, "setAccount") } - txs, _, err = idx.SearchTransactions(1, 5, 0, "") + txs, _, err = idx.SearchTransactions(1, 5, 0, "", "", "", "") qt.Assert(t, err, qt.IsNil) qt.Assert(t, txs, qt.HasLen, 1) - qt.Assert(t, txs[0].Index, qt.Equals, uint64(95)) } func TestCensusUpdate(t *testing.T) { diff --git a/vochain/indexer/indexertypes/block.go b/vochain/indexer/indexertypes/block.go new file mode 100644 index 000000000..4b711bdbc --- /dev/null +++ b/vochain/indexer/indexertypes/block.go @@ -0,0 +1,46 @@ +package indexertypes + +import ( + "time" + + "go.vocdoni.io/dvote/types" + indexerdb "go.vocdoni.io/dvote/vochain/indexer/db" +) + +// Block represents a block handled by the Vochain. +// The indexer Block data type is different from the vochain state data type +// since it is optimized for querying purposes and not for keeping a shared consensus state. +type Block struct { + ChainID string `json:"chainId"` + Height int64 `json:"height"` + Time time.Time `json:"time"` + Hash types.HexBytes `json:"hash"` + ProposerAddress types.HexBytes `json:"proposer"` + LastBlockHash types.HexBytes `json:"lastBlockHash"` + TxCount int64 `json:"txCount"` +} + +// BlockFromDB converts the indexerdb.Block into a Block +func BlockFromDB(dbblock *indexerdb.Block) *Block { + return &Block{ + ChainID: dbblock.ChainID, + Height: dbblock.Height, + Time: dbblock.Time, + Hash: nonEmptyBytes(dbblock.Hash), + ProposerAddress: nonEmptyBytes(dbblock.ProposerAddress), + LastBlockHash: nonEmptyBytes(dbblock.LastBlockHash), + } +} + +// BlockFromDBRow converts the indexerdb.SearchBlocksRow into a Block +func BlockFromDBRow(row *indexerdb.SearchBlocksRow) *Block { + return &Block{ + ChainID: row.ChainID, + Height: row.Height, + Time: row.Time, + Hash: nonEmptyBytes(row.Hash), + ProposerAddress: nonEmptyBytes(row.ProposerAddress), + LastBlockHash: nonEmptyBytes(row.LastBlockHash), + TxCount: row.TxCount, + } +} diff --git a/vochain/indexer/indexertypes/types.go b/vochain/indexer/indexertypes/types.go index d0d2b29aa..ad5b29748 100644 --- a/vochain/indexer/indexertypes/types.go +++ b/vochain/indexer/indexertypes/types.go @@ -176,30 +176,51 @@ type TxPackage struct { Signature types.HexBytes `json:"signature"` } -// TxMetadata contains tx information for the TransactionList api -type TxMetadata struct { - Type string `json:"type"` - BlockHeight uint32 `json:"blockHeight,omitempty"` - Index int32 `json:"index"` - Hash types.HexBytes `json:"hash"` +// TransactionMetadata contains tx information for the TransactionList api +type TransactionMetadata struct { + Hash types.HexBytes `json:"hash" swaggertype:"string" example:"75e8f822f5dd13973ac5158d600f0a2a5fea4bfefce9712ab5195bf17884cfad"` + BlockHeight uint32 `json:"height" format:"int32" example:"64924"` + TxBlockIndex int32 `json:"index" format:"int32" example:"0"` + TxType string `json:"type" enums:"vote,newProcess,admin,setProcess,registerKey,mintTokens,sendTokens,setTransactionCosts,setAccount,collectFaucet,setKeykeeper" example:"Vote"` + TxSubtype string `json:"subtype" example:"set_process_census"` + Signer types.HexBytes `json:"signer" swaggertype:"string" example:"0e45513942cf95330fc5e9020851b8bdd9b9c9df"` } -// Transaction holds the db reference for a single transaction -type Transaction struct { - Index uint64 `json:"transactionNumber" format:"int64" example:"944"` - Hash types.HexBytes `json:"transactionHash" swaggertype:"string" example:"75e8f822f5dd13973ac5158d600f0a2a5fea4bfefce9712ab5195bf17884cfad"` - BlockHeight uint32 `json:"blockHeight" format:"int32" example:"64924"` - TxBlockIndex int32 `json:"transactionIndex" format:"int32" example:"0"` - TxType string `json:"transactionType" enums:"vote,newProcess,admin,setProcess,registerKey,mintTokens,sendTokens,setTransactionCosts,setAccount,collectFaucet,setKeykeeper" example:"Vote"` +func TransactionMetadataFromDB(dbtx *indexerdb.Transaction) *TransactionMetadata { + return &TransactionMetadata{ + Hash: dbtx.Hash, + BlockHeight: uint32(dbtx.BlockHeight), + TxBlockIndex: int32(dbtx.BlockIndex), + TxType: dbtx.Type, + TxSubtype: dbtx.Subtype, + Signer: dbtx.Signer, + } } -func TransactionFromDB(dbtx *indexerdb.Transaction) *Transaction { - return &Transaction{ - Index: uint64(dbtx.ID), +func TransactionMetadataFromDBRow(dbtx *indexerdb.SearchTransactionsRow) *TransactionMetadata { + return &TransactionMetadata{ Hash: dbtx.Hash, BlockHeight: uint32(dbtx.BlockHeight), TxBlockIndex: int32(dbtx.BlockIndex), TxType: dbtx.Type, + TxSubtype: dbtx.Subtype, + Signer: dbtx.Signer, + } +} + +// Transaction holds a single transaction +type Transaction struct { + *TransactionMetadata + RawTx types.HexBytes `json:"-"` + Signature types.HexBytes `json:"-"` +} + +// TransactionFromDB converts an indexerdb.Transaction into a Transaction +func TransactionFromDB(dbtx *indexerdb.Transaction) *Transaction { + return &Transaction{ + TransactionMetadata: TransactionMetadataFromDB(dbtx), + RawTx: dbtx.RawTx, + Signature: dbtx.Signature, } } diff --git a/vochain/indexer/migrations/0013_recreate_table_transactions.sql b/vochain/indexer/migrations/0013_recreate_table_transactions.sql new file mode 100644 index 000000000..636f0e2bc --- /dev/null +++ b/vochain/indexer/migrations/0013_recreate_table_transactions.sql @@ -0,0 +1,56 @@ +-- +goose Up +PRAGMA foreign_keys = OFF; + +-- Create a new table with hash as primary key +CREATE TABLE transactions_new ( + hash BLOB NOT NULL PRIMARY KEY, + block_height INTEGER NOT NULL, + block_index INTEGER NOT NULL, + type TEXT NOT NULL +); + +-- Copy data from the old table to the new table +INSERT OR REPLACE INTO transactions_new (hash, block_height, block_index, type) +SELECT hash, block_height, block_index, type +FROM transactions; + +-- Drop the old table +DROP TABLE transactions; + +-- Rename the new table to the old table name +ALTER TABLE transactions_new RENAME TO transactions; + +-- Recreate necessary indexes +CREATE INDEX transactions_block_height_index +ON transactions(block_height, block_index); + +PRAGMA foreign_keys = ON; + +-- +goose Down +PRAGMA foreign_keys = OFF; + +-- Recreate the old table structure +CREATE TABLE transactions ( + id INTEGER NOT NULL PRIMARY KEY, + hash BLOB NOT NULL, + block_height INTEGER NOT NULL, + block_index INTEGER NOT NULL, + type TEXT NOT NULL +); + +-- Copy data back from the new table to the old table +INSERT INTO transactions (hash, block_height, block_index, type) +SELECT hash, block_height, block_index, type +FROM transactions_new; + +-- Drop the new table +DROP TABLE transactions_new; + +-- Recreate the old indexes +CREATE INDEX transactions_hash +ON transactions(hash); + +CREATE INDEX transactions_block_height_index +ON transactions(block_height, block_index); + +PRAGMA foreign_keys = ON; diff --git a/vochain/indexer/migrations/0014_alter_columns_table_blocks.sql b/vochain/indexer/migrations/0014_alter_columns_table_blocks.sql new file mode 100644 index 000000000..c83c32c06 --- /dev/null +++ b/vochain/indexer/migrations/0014_alter_columns_table_blocks.sql @@ -0,0 +1,13 @@ +-- +goose Up +ALTER TABLE blocks DROP COLUMN data_hash; +ALTER TABLE blocks ADD COLUMN chain_id TEXT NOT NULL DEFAULT ''; +ALTER TABLE blocks ADD COLUMN hash BLOB NOT NULL DEFAULT x''; +ALTER TABLE blocks ADD COLUMN proposer_address BLOB NOT NULL DEFAULT x''; +ALTER TABLE blocks ADD COLUMN last_block_hash BLOB NOT NULL DEFAULT x''; + +-- +goose Down +ALTER TABLE blocks ADD COLUMN data_hash BLOB NOT NULL; +ALTER TABLE blocks DROP COLUMN chain_id; +ALTER TABLE blocks DROP COLUMN hash; +ALTER TABLE blocks DROP COLUMN proposer_address; +ALTER TABLE blocks DROP COLUMN last_block_hash; diff --git a/vochain/indexer/migrations/0015_alter_columns_table_transactions.sql b/vochain/indexer/migrations/0015_alter_columns_table_transactions.sql new file mode 100644 index 000000000..81dcb9dec --- /dev/null +++ b/vochain/indexer/migrations/0015_alter_columns_table_transactions.sql @@ -0,0 +1,11 @@ +-- +goose Up +ALTER TABLE transactions ADD COLUMN subtype TEXT NOT NULL DEFAULT ''; +ALTER TABLE transactions ADD COLUMN raw_tx BLOB NOT NULL DEFAULT x''; +ALTER TABLE transactions ADD COLUMN signature BLOB NOT NULL DEFAULT x''; +ALTER TABLE transactions ADD COLUMN signer BLOB NOT NULL DEFAULT x''; + +-- +goose Down +ALTER TABLE transactions DROP COLUMN signer; +ALTER TABLE transactions DROP COLUMN signature; +ALTER TABLE transactions DROP COLUMN raw_tx; +ALTER TABLE transactions DROP COLUMN subtype; diff --git a/vochain/indexer/queries/blocks.sql b/vochain/indexer/queries/blocks.sql index 577e875b5..98533e60c 100644 --- a/vochain/indexer/queries/blocks.sql +++ b/vochain/indexer/queries/blocks.sql @@ -1,11 +1,65 @@ -- name: CreateBlock :execresult INSERT INTO blocks( - height, time, data_hash + chain_id, height, time, hash, proposer_address, last_block_hash ) VALUES ( - ?, ?, ? -); + ?, ?, ?, ?, ?, ? +) +ON CONFLICT(height) DO UPDATE +SET chain_id = excluded.chain_id, + time = excluded.time, + hash = excluded.hash, + proposer_address = excluded.proposer_address, + last_block_hash = excluded.last_block_hash; --- name: GetBlock :one +-- name: GetBlockByHeight :one SELECT * FROM blocks WHERE height = ? LIMIT 1; + +-- name: GetBlockByHash :one +SELECT * FROM blocks +WHERE hash = ? +LIMIT 1; + +-- name: LastBlockHeight :one +SELECT height FROM blocks +ORDER BY height DESC +LIMIT 1; + +-- name: SearchBlocks :many +SELECT + b.*, + COUNT(t.block_index) AS tx_count +FROM blocks AS b +LEFT JOIN transactions AS t + ON b.height = t.block_height +WHERE ( + (sqlc.arg(chain_id) = '' OR b.chain_id = sqlc.arg(chain_id)) + AND LENGTH(sqlc.arg(hash_substr)) <= 64 -- if passed arg is longer, then just abort the query + AND ( + sqlc.arg(hash_substr) = '' + OR (LENGTH(sqlc.arg(hash_substr)) = 64 AND LOWER(HEX(b.hash)) = LOWER(sqlc.arg(hash_substr))) + OR (LENGTH(sqlc.arg(hash_substr)) < 64 AND INSTR(LOWER(HEX(b.hash)), LOWER(sqlc.arg(hash_substr))) > 0) + -- TODO: consider keeping an hash_hex column for faster searches + ) + AND (sqlc.arg(proposer_address) = '' OR LOWER(HEX(b.proposer_address)) = LOWER(sqlc.arg(proposer_address))) +) +GROUP BY b.height +ORDER BY b.height DESC +LIMIT sqlc.arg(limit) +OFFSET sqlc.arg(offset); + +-- name: CountBlocks :one +SELECT COUNT(*) +FROM blocks AS b +WHERE ( + (sqlc.arg(chain_id) = '' OR b.chain_id = sqlc.arg(chain_id)) + AND LENGTH(sqlc.arg(hash_substr)) <= 64 -- if passed arg is longer, then just abort the query + AND ( + sqlc.arg(hash_substr) = '' + OR (LENGTH(sqlc.arg(hash_substr)) = 64 AND LOWER(HEX(b.hash)) = LOWER(sqlc.arg(hash_substr))) + OR (LENGTH(sqlc.arg(hash_substr)) < 64 AND INSTR(LOWER(HEX(b.hash)), LOWER(sqlc.arg(hash_substr))) > 0) + -- TODO: consider keeping an hash_hex column for faster searches + ) + AND (sqlc.arg(proposer_address) = '' OR LOWER(HEX(b.proposer_address)) = LOWER(sqlc.arg(proposer_address))) +); diff --git a/vochain/indexer/queries/transactions.sql b/vochain/indexer/queries/transactions.sql index 0e625a197..c9c152482 100644 --- a/vochain/indexer/queries/transactions.sql +++ b/vochain/indexer/queries/transactions.sql @@ -1,14 +1,18 @@ -- name: CreateTransaction :execresult INSERT INTO transactions ( - hash, block_height, block_index, type + hash, block_height, block_index, type, subtype, raw_tx, signature, signer ) VALUES ( - ?, ?, ?, ? -); + ?, ?, ?, ?, ?, ?, ?, ? +) +ON CONFLICT(hash) DO UPDATE +SET block_height = excluded.block_height, + block_index = excluded.block_index, + type = excluded.type, + subtype = excluded.subtype, + raw_tx = excluded.raw_tx, + signature = excluded.signature, + signer = excluded.signer; --- name: GetTransaction :one -SELECT * FROM transactions -WHERE id = ? -LIMIT 1; -- name: GetTransactionByHash :one SELECT * FROM transactions @@ -18,22 +22,29 @@ LIMIT 1; -- name: CountTransactions :one SELECT COUNT(*) FROM transactions; --- name: GetTxReferenceByBlockHeightAndBlockIndex :one +-- name: CountTransactionsByHeight :one +SELECT COUNT(*) FROM transactions +WHERE block_height = ?; + +-- name: GetTransactionByHeightAndIndex :one SELECT * FROM transactions WHERE block_height = ? AND block_index = ? LIMIT 1; -- name: SearchTransactions :many -WITH results AS ( - SELECT * - FROM transactions - WHERE ( - (sqlc.arg(block_height) = 0 OR block_height = sqlc.arg(block_height)) - AND (sqlc.arg(tx_type) = '' OR LOWER(type) = LOWER(sqlc.arg(tx_type))) - ) -) SELECT *, COUNT(*) OVER() AS total_count -FROM results -ORDER BY id DESC +FROM transactions +WHERE + (sqlc.arg(block_height) = 0 OR block_height = sqlc.arg(block_height)) + AND (sqlc.arg(tx_type) = '' OR LOWER(type) = LOWER(sqlc.arg(tx_type))) + AND (sqlc.arg(tx_subtype) = '' OR LOWER(subtype) = LOWER(sqlc.arg(tx_subtype))) + AND (sqlc.arg(tx_signer) = '' OR LOWER(HEX(signer)) = LOWER(sqlc.arg(tx_signer))) + AND ( + sqlc.arg(hash_substr) = '' + OR (LENGTH(sqlc.arg(hash_substr)) = 64 AND LOWER(HEX(hash)) = LOWER(sqlc.arg(hash_substr))) + OR (LENGTH(sqlc.arg(hash_substr)) < 64 AND INSTR(LOWER(HEX(hash)), LOWER(sqlc.arg(hash_substr))) > 0) + -- TODO: consider keeping an hash_hex column for faster searches + ) +ORDER BY block_height DESC, block_index DESC LIMIT sqlc.arg(limit) OFFSET sqlc.arg(offset); diff --git a/vochain/indexer/transaction.go b/vochain/indexer/transaction.go index 4b8c9fe21..41a6a1818 100644 --- a/vochain/indexer/transaction.go +++ b/vochain/indexer/transaction.go @@ -5,12 +5,15 @@ import ( "database/sql" "errors" "fmt" + "strings" + "go.vocdoni.io/dvote/crypto/ethereum" "go.vocdoni.io/dvote/log" "go.vocdoni.io/dvote/types" indexerdb "go.vocdoni.io/dvote/vochain/indexer/db" "go.vocdoni.io/dvote/vochain/indexer/indexertypes" "go.vocdoni.io/dvote/vochain/transaction/vochaintx" + "google.golang.org/protobuf/proto" ) // ErrTransactionNotFound is returned if the transaction is not found. @@ -22,49 +25,55 @@ func (idx *Indexer) CountTotalTransactions() (uint64, error) { return uint64(count), err } -// GetTransaction fetches the txReference for the given tx height -func (idx *Indexer) GetTransaction(id uint64) (*indexertypes.Transaction, error) { - sqlTxRef, err := idx.readOnlyQuery.GetTransaction(context.TODO(), int64(id)) +// CountTransactionsByHeight returns the number of transactions indexed for a given height +func (idx *Indexer) CountTransactionsByHeight(height int64) (int64, error) { + return idx.readOnlyQuery.CountTransactionsByHeight(context.TODO(), height) +} + +// GetTxMetadataByHash fetches the tx metadata for the given tx hash +func (idx *Indexer) GetTxMetadataByHash(hash types.HexBytes) (*indexertypes.TransactionMetadata, error) { + sqlTxRef, err := idx.readOnlyQuery.GetTransactionByHash(context.TODO(), hash) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, ErrTransactionNotFound } - return nil, fmt.Errorf("tx with id %d not found: %v", id, err) + return nil, fmt.Errorf("tx hash %x not found: %v", hash, err) } - return indexertypes.TransactionFromDB(&sqlTxRef), nil + return indexertypes.TransactionMetadataFromDB(&sqlTxRef), nil } -// GetTxReferenceByBlockHeightAndBlockIndex fetches the txReference for the given tx height and block tx index -func (idx *Indexer) GetTxReferenceByBlockHeightAndBlockIndex(blockHeight, blockIndex int64) (*indexertypes.Transaction, error) { - sqlTxRef, err := idx.readOnlyQuery.GetTxReferenceByBlockHeightAndBlockIndex(context.TODO(), indexerdb.GetTxReferenceByBlockHeightAndBlockIndexParams{ - BlockHeight: blockHeight, - BlockIndex: blockIndex, - }) +// GetTransactionByHash fetches the full tx for the given tx hash +func (idx *Indexer) GetTransactionByHash(hash types.HexBytes) (*indexertypes.Transaction, error) { + sqlTxRef, err := idx.readOnlyQuery.GetTransactionByHash(context.TODO(), hash) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, ErrTransactionNotFound } - return nil, fmt.Errorf("tx at block %d and index %d not found: %v", blockHeight, blockIndex, err) + return nil, fmt.Errorf("tx hash %x not found: %v", hash, err) } return indexertypes.TransactionFromDB(&sqlTxRef), nil } -// GetTxHashReference fetches the txReference for the given tx hash -func (idx *Indexer) GetTxHashReference(hash types.HexBytes) (*indexertypes.Transaction, error) { - sqlTxRef, err := idx.readOnlyQuery.GetTransactionByHash(context.TODO(), hash) +// GetTransactionByHeightAndIndex fetches the full tx for the given tx height and block tx index +func (idx *Indexer) GetTransactionByHeightAndIndex(blockHeight, blockIndex int64) (*indexertypes.Transaction, error) { + sqlTxRef, err := idx.readOnlyQuery.GetTransactionByHeightAndIndex(context.TODO(), indexerdb.GetTransactionByHeightAndIndexParams{ + BlockHeight: blockHeight, + BlockIndex: blockIndex, + }) if err != nil { if errors.Is(err, sql.ErrNoRows) { return nil, ErrTransactionNotFound } - return nil, fmt.Errorf("tx hash %x not found: %v", hash, err) + return nil, fmt.Errorf("tx at block %d and index %d not found: %v", blockHeight, blockIndex, err) } return indexertypes.TransactionFromDB(&sqlTxRef), nil } // SearchTransactions returns the list of transactions indexed. -// height and txType are optional, if declared as zero-value will be ignored. +// blockHeight, hash, txType, txSubtype and txSigner are optional, if declared as zero-value will be ignored. +// hash matches substrings. // The first one returned is the newest, so they are in descending order. -func (idx *Indexer) SearchTransactions(limit, offset int, blockHeight uint64, txType string) ([]*indexertypes.Transaction, uint64, error) { +func (idx *Indexer) SearchTransactions(limit, offset int, blockHeight uint64, txHash, txType, txSubtype, txSigner string) ([]*indexertypes.TransactionMetadata, uint64, error) { if offset < 0 { return nil, 0, fmt.Errorf("invalid value: offset cannot be %d", offset) } @@ -74,21 +83,18 @@ func (idx *Indexer) SearchTransactions(limit, offset int, blockHeight uint64, tx results, err := idx.readOnlyQuery.SearchTransactions(context.TODO(), indexerdb.SearchTransactionsParams{ Limit: int64(limit), Offset: int64(offset), + HashSubstr: txHash, BlockHeight: blockHeight, TxType: txType, + TxSubtype: txSubtype, + TxSigner: txSigner, }) if err != nil { return nil, 0, err } - list := []*indexertypes.Transaction{} + list := []*indexertypes.TransactionMetadata{} for _, row := range results { - list = append(list, &indexertypes.Transaction{ - Index: uint64(row.ID), - Hash: row.Hash, - BlockHeight: uint32(row.BlockHeight), - TxBlockIndex: int32(row.BlockIndex), - TxType: row.Type, - }) + list = append(list, indexertypes.TransactionMetadataFromDBRow(&row)) } if len(results) == 0 { return list, 0, nil @@ -99,13 +105,38 @@ func (idx *Indexer) SearchTransactions(limit, offset int, blockHeight uint64, tx func (idx *Indexer) OnNewTx(tx *vochaintx.Tx, blockHeight uint32, txIndex int32) { idx.blockMu.Lock() defer idx.blockMu.Unlock() + + idx.indexTx(tx, blockHeight, txIndex) +} + +func (idx *Indexer) indexTx(tx *vochaintx.Tx, blockHeight uint32, txIndex int32) { + rawtx, err := proto.Marshal(tx.Tx) + if err != nil { + log.Errorw(err, "indexer cannot marshal transaction") + return + } + + signer := []byte{} + if len(tx.Signature) > 0 { // not all txs are signed, for example zk ones + addr, err := ethereum.AddrFromSignature(tx.SignedBody, tx.Signature) + if err != nil { + log.Errorw(err, "indexer cannot recover signer from signature") + return + } + signer = addr.Bytes() + } + queries := idx.blockTxQueries() if _, err := queries.CreateTransaction(context.TODO(), indexerdb.CreateTransactionParams{ Hash: tx.TxID[:], BlockHeight: int64(blockHeight), BlockIndex: int64(txIndex), Type: tx.TxModelType, + Subtype: strings.ToLower(tx.TxSubtype()), + RawTx: rawtx, + Signature: nonNullBytes(tx.Signature), + Signer: nonNullBytes(signer), }); err != nil { - log.Errorw(err, "cannot index new transaction") + log.Errorw(err, "cannot index transaction") } } diff --git a/vochain/indexer/vote.go b/vochain/indexer/vote.go index ca66e59d3..61d13c92c 100644 --- a/vochain/indexer/vote.go +++ b/vochain/indexer/vote.go @@ -8,6 +8,7 @@ import ( "errors" "fmt" "math/big" + "slices" "strings" "time" @@ -138,8 +139,8 @@ func unmarshalVote(VotePackage []byte, keys []string) (*state.VotePackage, error // if encryption keys, decrypt the vote if len(keys) > 0 { rawVote = bytes.Clone(VotePackage) - for i := len(keys) - 1; i >= 0; i-- { - priv, err := nacl.DecodePrivate(keys[i]) + for i, key := range slices.Backward(keys) { + priv, err := nacl.DecodePrivate(key) if err != nil { return nil, fmt.Errorf("cannot create private key cipher: (%s)", err) } diff --git a/vochain/keykeeper/keykeeper.go b/vochain/keykeeper/keykeeper.go index 7f46f654d..4a4425cd1 100644 --- a/vochain/keykeeper/keykeeper.go +++ b/vochain/keykeeper/keykeeper.go @@ -268,9 +268,6 @@ func (*KeyKeeper) OnVote(_ *state.Vote, _ int32) {} // OnNewTx is not used by the KeyKeeper func (*KeyKeeper) OnNewTx(_ *vochaintx.Tx, _ uint32, _ int32) {} -// OnBeginBlock is not used by the KeyKeeper -func (*KeyKeeper) OnBeginBlock(_ state.BeginBlock) {} - // OnCensusUpdate is not used by the KeyKeeper func (*KeyKeeper) OnCensusUpdate(_, _ []byte, _ string, _ uint64) {} diff --git a/vochain/offchaindatahandler/offchaindatahandler.go b/vochain/offchaindatahandler/offchaindatahandler.go index d6e97bd9b..4bc3be6b4 100644 --- a/vochain/offchaindatahandler/offchaindatahandler.go +++ b/vochain/offchaindatahandler/offchaindatahandler.go @@ -166,7 +166,6 @@ func (d *OffChainDataHandler) OnSetAccount(_ []byte, account *state.Account) { func (*OffChainDataHandler) OnCancel(_ []byte, _ int32) {} func (*OffChainDataHandler) OnVote(_ *state.Vote, _ int32) {} func (*OffChainDataHandler) OnNewTx(_ *vochaintx.Tx, _ uint32, _ int32) {} -func (*OffChainDataHandler) OnBeginBlock(state.BeginBlock) {} func (*OffChainDataHandler) OnProcessKeys(_ []byte, _ string, _ int32) {} func (*OffChainDataHandler) OnRevealKeys(_ []byte, _ string, _ int32) {} func (*OffChainDataHandler) OnProcessStatusChange(_ []byte, _ models.ProcessStatus, _ int32) {} diff --git a/vochain/results/compute.go b/vochain/results/compute.go index cc59b932e..5157c4281 100644 --- a/vochain/results/compute.go +++ b/vochain/results/compute.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "math/big" + "slices" "sync" "time" @@ -93,15 +94,13 @@ func unmarshalVote(VotePackage []byte, keys []string) (*state.VotePackage, error var vote state.VotePackage rawVote := bytes.Clone(VotePackage) // if encryption keys, decrypt the vote - if len(keys) > 0 { - for i := len(keys) - 1; i >= 0; i-- { - priv, err := nacl.DecodePrivate(keys[i]) - if err != nil { - return nil, fmt.Errorf("cannot create private key cipher: (%s)", err) - } - if rawVote, err = priv.Decrypt(rawVote); err != nil { - return nil, fmt.Errorf("cannot decrypt vote with index key %d: %w", i, err) - } + for i, key := range slices.Backward(keys) { + priv, err := nacl.DecodePrivate(key) + if err != nil { + return nil, fmt.Errorf("cannot create private key cipher: (%s)", err) + } + if rawVote, err = priv.Decrypt(rawVote); err != nil { + return nil, fmt.Errorf("cannot decrypt vote with index key %d: %w", i, err) } } if err := vote.Decode(rawVote); err != nil { diff --git a/vochain/state/account.go b/vochain/state/account.go index 8bbe4264a..6c12ef107 100644 --- a/vochain/state/account.go +++ b/vochain/state/account.go @@ -2,6 +2,7 @@ package state import ( "bytes" + "encoding/hex" "errors" "fmt" @@ -102,6 +103,20 @@ func (v *State) GetAccount(address common.Address, committed bool) (*Account, er return &acc, acc.Unmarshal(raw) } +// AccountBalance retrieves the Account.Balance for an address. +// Returns 0 and no error if the account does not exist. +// Committed is relative to the state on which the function is executed. +func (v *State) AccountBalance(address common.Address, committed bool) (uint64, error) { + acc, err := v.GetAccount(address, committed) + if err != nil { + return 0, err + } + if acc == nil { + return 0, nil + } + return acc.Balance, nil +} + // CountAccounts returns the overall number of accounts the vochain has func (v *State) CountAccounts(committed bool) (uint64, error) { // TODO: Once statedb.TreeView.Size() works, replace this by that. @@ -310,16 +325,16 @@ func (v *State) SetAccountDelegate(accountAddr common.Address, } switch txType { case models.TxType_ADD_DELEGATE_FOR_ACCOUNT: - log.Debugf("adding delegates %+v for account %s", delegateAddrs, accountAddr) for _, delegate := range delegateAddrs { + log.Debugw("adding delegate", "account", accountAddr.Hex(), "delegate", hex.EncodeToString(delegate)) if err := acc.AddDelegate(common.BytesToAddress(delegate)); err != nil { return fmt.Errorf("cannot add delegate, AddDelegate: %w", err) } } return v.SetAccount(accountAddr, acc) case models.TxType_DEL_DELEGATE_FOR_ACCOUNT: - log.Debugf("deleting delegates %+v for account %s", delegateAddrs, accountAddr) for _, delegate := range delegateAddrs { + log.Debugw("deleting delegate", "account", accountAddr.Hex(), "delegate", hex.EncodeToString(delegate)) if err := acc.DelDelegate(common.BytesToAddress(delegate)); err != nil { return fmt.Errorf("cannot delete delegate, DelDelegate: %w", err) } diff --git a/vochain/state/eventlistener.go b/vochain/state/eventlistener.go index 1c2d05281..7b599702b 100644 --- a/vochain/state/eventlistener.go +++ b/vochain/state/eventlistener.go @@ -1,8 +1,6 @@ package state import ( - "time" - "go.vocdoni.io/dvote/vochain/transaction/vochaintx" "go.vocdoni.io/proto/build/go/models" ) @@ -32,7 +30,6 @@ type EventListener interface { OnSpendTokens(addr []byte, txType models.TxType, cost uint64, reference string) OnCensusUpdate(pid, censusRoot []byte, censusURI string, censusSize uint64) Commit(height uint32) (err error) - OnBeginBlock(BeginBlock) Rollback() } @@ -46,15 +43,3 @@ func (v *State) AddEventListener(l EventListener) { func (v *State) CleanEventListeners() { v.eventListeners = nil } - -type BeginBlock struct { - Height int64 - Time time.Time - DataHash []byte -} - -func (v *State) OnBeginBlock(bb BeginBlock) { - for _, l := range v.eventListeners { - l.OnBeginBlock(bb) - } -} diff --git a/vochain/state/state_test.go b/vochain/state/state_test.go index e2b76c685..b36dc7722 100644 --- a/vochain/state/state_test.go +++ b/vochain/state/state_test.go @@ -182,7 +182,6 @@ type Listener struct { func (*Listener) OnVote(_ *Vote, _ int32) {} func (*Listener) OnNewTx(_ *vochaintx.Tx, _ uint32, _ int32) {} -func (*Listener) OnBeginBlock(BeginBlock) {} func (*Listener) OnProcess(_ *models.Process, _ int32) {} func (*Listener) OnProcessStatusChange(_ []byte, _ models.ProcessStatus, _ int32) {} func (*Listener) OnProcessDurationChange(_ []byte, _ uint32, _ int32) {} diff --git a/vochain/transaction/account_tx.go b/vochain/transaction/account_tx.go index f46abaf57..6c1e6b39c 100644 --- a/vochain/transaction/account_tx.go +++ b/vochain/transaction/account_tx.go @@ -2,7 +2,6 @@ package transaction import ( "bytes" - "encoding/binary" "errors" "fmt" @@ -13,7 +12,6 @@ import ( vstate "go.vocdoni.io/dvote/vochain/state" "go.vocdoni.io/dvote/vochain/transaction/vochaintx" "go.vocdoni.io/proto/build/go/models" - "google.golang.org/protobuf/proto" ) // CreateAccountTxCheck checks if an account creation tx is valid @@ -56,56 +54,13 @@ func (t *TransactionHandler) CreateAccountTxCheck(vtx *vochaintx.Tx) error { if err != nil { return fmt.Errorf("cannot get tx cost: %w", err) } - if txCost == 0 { - return nil - } - if tx.FaucetPackage == nil { - return fmt.Errorf("invalid faucet package provided") - } - if tx.FaucetPackage.Payload == nil { - return fmt.Errorf("invalid faucet package payload") - } - faucetPayload := &models.FaucetPayload{} - if err := proto.Unmarshal(tx.FaucetPackage.Payload, faucetPayload); err != nil { - return fmt.Errorf("could not unmarshal faucet package: %w", err) - } - if faucetPayload.Amount == 0 { - return fmt.Errorf("invalid faucet payload amount provided") - } - if faucetPayload.To == nil { - return fmt.Errorf("invalid to address provided") - } - if !bytes.Equal(faucetPayload.To, txSenderAddress.Bytes()) { - return fmt.Errorf("payload to and tx sender missmatch (%x != %x)", - faucetPayload.To, txSenderAddress.Bytes()) - } - issuerAddress, err := ethereum.AddrFromSignature(tx.FaucetPackage.Payload, tx.FaucetPackage.Signature) + // Check the faucet package + canPayForTx, err := t.checkFaucetPackageAndTransfer(tx.FaucetPackage, txCost, txSenderAddress, vtx.TxID[:], false) if err != nil { - return fmt.Errorf("cannot extract issuer address from faucet package vtx.Signature: %w", err) - } - issuerAcc, err := t.state.GetAccount(issuerAddress, false) - if err != nil { - return fmt.Errorf("cannot get faucet issuer address account: %w", err) - } - if issuerAcc == nil { - return fmt.Errorf("the account signing the faucet payload does not exist (%s)", issuerAddress) - } - b := make([]byte, 8) - binary.LittleEndian.PutUint64(b, faucetPayload.Identifier) - keyHash := ethereum.HashRaw(append(issuerAddress.Bytes(), b...)) - used, err := t.state.FaucetNonce(keyHash, false) - if err != nil { - return fmt.Errorf("cannot check if faucet payload already used: %w", err) - } - if used { - return fmt.Errorf("faucet payload %x already used", keyHash) + return err } - if issuerAcc.Balance < faucetPayload.Amount+txCost { - return fmt.Errorf( - "issuer address does not have enough balance %d, required %d", - issuerAcc.Balance, - faucetPayload.Amount+txCost, - ) + if !canPayForTx { + return fmt.Errorf("faucet package is not enough for paying for the transaction cost") } return nil } @@ -126,6 +81,7 @@ func (t *TransactionHandler) SetAccountDelegateTxCheck(vtx *vochaintx.Tx) error if len(tx.Delegates) == 0 { return fmt.Errorf("invalid delegates") } + txSenderAccount, txSenderAddr, err := t.checkAccountCanPayCost(tx.Txtype, vtx) if err != nil { return err diff --git a/vochain/transaction/proofs/arboproof/arboproof.go b/vochain/transaction/proofs/arboproof/arboproof.go index 7301c6c21..f9e933d4a 100644 --- a/vochain/transaction/proofs/arboproof/arboproof.go +++ b/vochain/transaction/proofs/arboproof/arboproof.go @@ -61,12 +61,12 @@ func (*ProofVerifierArbo) Verify(process *models.Process, envelope *models.VoteE return true, bigOne, nil } - availableWeight := arbo.BytesToBigInt(p.AvailableWeight) + availableWeight := arbo.BytesLEToBigInt(p.AvailableWeight) if p.VoteWeight == nil { return true, availableWeight, nil } - voteWeight := arbo.BytesToBigInt(p.VoteWeight) + voteWeight := arbo.BytesLEToBigInt(p.VoteWeight) if voteWeight.Cmp(availableWeight) == 1 { return false, nil, fmt.Errorf("assigned weight exceeded") } diff --git a/vochain/transaction/proofs/farcasterproof/proto/farcastermessage.pb.go b/vochain/transaction/proofs/farcasterproof/proto/farcastermessage.pb.go index 88729dfa8..38e1c0942 100644 --- a/vochain/transaction/proofs/farcasterproof/proto/farcastermessage.pb.go +++ b/vochain/transaction/proofs/farcasterproof/proto/farcastermessage.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.26.0 -// protoc v4.25.3 +// protoc-gen-go v1.35.2 +// protoc v5.28.3 // source: farcastermessage.proto package proto @@ -130,9 +130,9 @@ const ( MessageType_MESSAGE_TYPE_LINK_REMOVE MessageType = 6 // Remove an existing Link MessageType_MESSAGE_TYPE_VERIFICATION_ADD_ETH_ADDRESS MessageType = 7 // Add a Verification of an Ethereum Address MessageType_MESSAGE_TYPE_VERIFICATION_REMOVE MessageType = 8 // Remove a Verification - // Deprecated - // MESSAGE_TYPE_SIGNER_ADD = 9; // Add a new Ed25519 key pair that signs messages for a user - // MESSAGE_TYPE_SIGNER_REMOVE = 10; // Remove an Ed25519 key pair that signs messages for a user + // Deprecated + // MESSAGE_TYPE_SIGNER_ADD = 9; // Add a new Ed25519 key pair that signs messages for a user + // MESSAGE_TYPE_SIGNER_REMOVE = 10; // Remove an Ed25519 key pair that signs messages for a user MessageType_MESSAGE_TYPE_USER_DATA_ADD MessageType = 11 // Add metadata about a user MessageType_MESSAGE_TYPE_USERNAME_PROOF MessageType = 12 // Add or replace a username proof MessageType_MESSAGE_TYPE_FRAME_ACTION MessageType = 13 // A Farcaster Frame action @@ -477,11 +477,9 @@ type Message struct { func (x *Message) Reset() { *x = Message{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[0] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Message) String() string { @@ -492,7 +490,7 @@ func (*Message) ProtoMessage() {} func (x *Message) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[0] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -569,6 +567,7 @@ type MessageData struct { Timestamp uint32 `protobuf:"varint,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` // Farcaster epoch timestamp in seconds Network FarcasterNetwork `protobuf:"varint,4,opt,name=network,proto3,enum=farcaster.types.v1.FarcasterNetwork" json:"network,omitempty"` // Farcaster network the message is intended for // Types that are assignable to Body: + // // *MessageData_CastAddBody // *MessageData_CastRemoveBody // *MessageData_ReactionBody @@ -584,11 +583,9 @@ type MessageData struct { func (x *MessageData) Reset() { *x = MessageData{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[1] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *MessageData) String() string { @@ -599,7 +596,7 @@ func (*MessageData) ProtoMessage() {} func (x *MessageData) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[1] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -798,11 +795,9 @@ type UserDataBody struct { func (x *UserDataBody) Reset() { *x = UserDataBody{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[2] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UserDataBody) String() string { @@ -813,7 +808,7 @@ func (*UserDataBody) ProtoMessage() {} func (x *UserDataBody) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[2] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -848,6 +843,7 @@ type Embed struct { unknownFields protoimpl.UnknownFields // Types that are assignable to Embed: + // // *Embed_Url // *Embed_CastId Embed isEmbed_Embed `protobuf_oneof:"embed"` @@ -855,11 +851,9 @@ type Embed struct { func (x *Embed) Reset() { *x = Embed{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[3] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *Embed) String() string { @@ -870,7 +864,7 @@ func (*Embed) ProtoMessage() {} func (x *Embed) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[3] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -931,6 +925,7 @@ type CastAddBody struct { EmbedsDeprecated []string `protobuf:"bytes,1,rep,name=embeds_deprecated,json=embedsDeprecated,proto3" json:"embeds_deprecated,omitempty"` // URLs to be embedded in the cast Mentions []uint64 `protobuf:"varint,2,rep,packed,name=mentions,proto3" json:"mentions,omitempty"` // Fids mentioned in the cast // Types that are assignable to Parent: + // // *CastAddBody_ParentCastId // *CastAddBody_ParentUrl Parent isCastAddBody_Parent `protobuf_oneof:"parent"` @@ -941,11 +936,9 @@ type CastAddBody struct { func (x *CastAddBody) Reset() { *x = CastAddBody{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[4] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CastAddBody) String() string { @@ -956,7 +949,7 @@ func (*CastAddBody) ProtoMessage() {} func (x *CastAddBody) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[4] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1054,11 +1047,9 @@ type CastRemoveBody struct { func (x *CastRemoveBody) Reset() { *x = CastRemoveBody{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[5] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CastRemoveBody) String() string { @@ -1069,7 +1060,7 @@ func (*CastRemoveBody) ProtoMessage() {} func (x *CastRemoveBody) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[5] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1103,11 +1094,9 @@ type CastId struct { func (x *CastId) Reset() { *x = CastId{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[6] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *CastId) String() string { @@ -1118,7 +1107,7 @@ func (*CastId) ProtoMessage() {} func (x *CastId) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[6] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1155,6 +1144,7 @@ type ReactionBody struct { Type ReactionType `protobuf:"varint,1,opt,name=type,proto3,enum=farcaster.types.v1.ReactionType" json:"type,omitempty"` // Type of reaction // Types that are assignable to Target: + // // *ReactionBody_TargetCastId // *ReactionBody_TargetUrl Target isReactionBody_Target `protobuf_oneof:"target"` @@ -1162,11 +1152,9 @@ type ReactionBody struct { func (x *ReactionBody) Reset() { *x = ReactionBody{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[7] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *ReactionBody) String() string { @@ -1177,7 +1165,7 @@ func (*ReactionBody) ProtoMessage() {} func (x *ReactionBody) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[7] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1252,11 +1240,9 @@ type VerificationAddAddressBody struct { func (x *VerificationAddAddressBody) Reset() { *x = VerificationAddAddressBody{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[8] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VerificationAddAddressBody) String() string { @@ -1267,7 +1253,7 @@ func (*VerificationAddAddressBody) ProtoMessage() {} func (x *VerificationAddAddressBody) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[8] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1336,11 +1322,9 @@ type VerificationRemoveBody struct { func (x *VerificationRemoveBody) Reset() { *x = VerificationRemoveBody{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[9] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *VerificationRemoveBody) String() string { @@ -1351,7 +1335,7 @@ func (*VerificationRemoveBody) ProtoMessage() {} func (x *VerificationRemoveBody) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[9] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1389,17 +1373,16 @@ type LinkBody struct { Type string `protobuf:"bytes,1,opt,name=type,proto3" json:"type,omitempty"` // Type of link, <= 8 characters DisplayTimestamp *uint32 `protobuf:"varint,2,opt,name=displayTimestamp,proto3,oneof" json:"displayTimestamp,omitempty"` // User-defined timestamp that preserves original timestamp when message.data.timestamp needs to be updated for compaction // Types that are assignable to Target: + // // *LinkBody_TargetFid Target isLinkBody_Target `protobuf_oneof:"target"` } func (x *LinkBody) Reset() { *x = LinkBody{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[10] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *LinkBody) String() string { @@ -1410,7 +1393,7 @@ func (*LinkBody) ProtoMessage() {} func (x *LinkBody) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[10] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1475,11 +1458,9 @@ type LinkCompactStateBody struct { func (x *LinkCompactStateBody) Reset() { *x = LinkCompactStateBody{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[11] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *LinkCompactStateBody) String() string { @@ -1490,7 +1471,7 @@ func (*LinkCompactStateBody) ProtoMessage() {} func (x *LinkCompactStateBody) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[11] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1536,11 +1517,9 @@ type FrameActionBody struct { func (x *FrameActionBody) Reset() { *x = FrameActionBody{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[12] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *FrameActionBody) String() string { @@ -1551,7 +1530,7 @@ func (*FrameActionBody) ProtoMessage() {} func (x *FrameActionBody) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[12] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -1630,11 +1609,9 @@ type UserNameProof struct { func (x *UserNameProof) Reset() { *x = UserNameProof{} - if protoimpl.UnsafeEnabled { - mi := &file_farcastermessage_proto_msgTypes[13] - ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) - ms.StoreMessageInfo(mi) - } + mi := &file_farcastermessage_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) } func (x *UserNameProof) String() string { @@ -1645,7 +1622,7 @@ func (*UserNameProof) ProtoMessage() {} func (x *UserNameProof) ProtoReflect() protoreflect.Message { mi := &file_farcastermessage_proto_msgTypes[13] - if protoimpl.UnsafeEnabled && x != nil { + if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { ms.StoreMessageInfo(mi) @@ -2000,7 +1977,7 @@ func file_farcastermessage_proto_rawDescGZIP() []byte { var file_farcastermessage_proto_enumTypes = make([]protoimpl.EnumInfo, 8) var file_farcastermessage_proto_msgTypes = make([]protoimpl.MessageInfo, 14) -var file_farcastermessage_proto_goTypes = []interface{}{ +var file_farcastermessage_proto_goTypes = []any{ (HashScheme)(0), // 0: farcaster.types.v1.HashScheme (SignatureScheme)(0), // 1: farcaster.types.v1.SignatureScheme (MessageType)(0), // 2: farcaster.types.v1.MessageType @@ -2062,178 +2039,8 @@ func file_farcastermessage_proto_init() { if File_farcastermessage_proto != nil { return } - if !protoimpl.UnsafeEnabled { - file_farcastermessage_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Message); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MessageData); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserDataBody); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*Embed); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CastAddBody); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CastRemoveBody); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*CastId); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ReactionBody); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VerificationAddAddressBody); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*VerificationRemoveBody); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LinkBody); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LinkCompactStateBody); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*FrameActionBody); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - file_farcastermessage_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*UserNameProof); i { - case 0: - return &v.state - case 1: - return &v.sizeCache - case 2: - return &v.unknownFields - default: - return nil - } - } - } - file_farcastermessage_proto_msgTypes[0].OneofWrappers = []interface{}{} - file_farcastermessage_proto_msgTypes[1].OneofWrappers = []interface{}{ + file_farcastermessage_proto_msgTypes[0].OneofWrappers = []any{} + file_farcastermessage_proto_msgTypes[1].OneofWrappers = []any{ (*MessageData_CastAddBody)(nil), (*MessageData_CastRemoveBody)(nil), (*MessageData_ReactionBody)(nil), @@ -2245,19 +2052,19 @@ func file_farcastermessage_proto_init() { (*MessageData_FrameActionBody)(nil), (*MessageData_LinkCompactStateBody)(nil), } - file_farcastermessage_proto_msgTypes[3].OneofWrappers = []interface{}{ + file_farcastermessage_proto_msgTypes[3].OneofWrappers = []any{ (*Embed_Url)(nil), (*Embed_CastId)(nil), } - file_farcastermessage_proto_msgTypes[4].OneofWrappers = []interface{}{ + file_farcastermessage_proto_msgTypes[4].OneofWrappers = []any{ (*CastAddBody_ParentCastId)(nil), (*CastAddBody_ParentUrl)(nil), } - file_farcastermessage_proto_msgTypes[7].OneofWrappers = []interface{}{ + file_farcastermessage_proto_msgTypes[7].OneofWrappers = []any{ (*ReactionBody_TargetCastId)(nil), (*ReactionBody_TargetUrl)(nil), } - file_farcastermessage_proto_msgTypes[10].OneofWrappers = []interface{}{ + file_farcastermessage_proto_msgTypes[10].OneofWrappers = []any{ (*LinkBody_TargetFid)(nil), } type x struct{} diff --git a/vochain/transaction/transaction.go b/vochain/transaction/transaction.go index 474dac6c8..14bc47fe5 100644 --- a/vochain/transaction/transaction.go +++ b/vochain/transaction/transaction.go @@ -1,6 +1,8 @@ package transaction import ( + "bytes" + "encoding/binary" "encoding/hex" "fmt" @@ -131,13 +133,23 @@ func (t *TransactionHandler) CheckTx(vtx *vochaintx.Tx, forCommit bool) (*Transa }); err != nil { return nil, fmt.Errorf("newProcessTx: cannot schedule end process: %w", err) } + + cost := t.txElectionCostFromProcess(p) + + // check for a faucet package and transfer amount to sender account + sender := common.Address(txSender) + if _, err := t.checkFaucetPackageAndTransfer(tx.FaucetPackage, cost, sender, vtx.TxID[:], true); err != nil { + return nil, err + } + return response, t.state.BurnTxCostIncrementNonce( - common.Address(txSender), + sender, models.TxType_NEW_PROCESS, - t.txElectionCostFromProcess(p), + cost, hex.EncodeToString(p.GetProcessId()), ) } + case *models.Tx_SetProcess: cost := uint64(0) txSender, err := t.SetProcessTxCheck(vtx) @@ -203,7 +215,13 @@ func (t *TransactionHandler) CheckTx(vtx *vochaintx.Tx, forCommit bool) (*Transa return nil, fmt.Errorf("unknown set process tx type") } - return response, t.state.BurnTxCostIncrementNonce(common.Address(txSender), tx.Txtype, cost, hex.EncodeToString(tx.ProcessId)) + // check for a faucet package and transfer amount to sender account + sender := common.Address(txSender) + if _, err := t.checkFaucetPackageAndTransfer(tx.FaucetPackage, cost, sender, vtx.TxID[:], true); err != nil { + return nil, err + } + + return response, t.state.BurnTxCostIncrementNonce(sender, tx.Txtype, cost, hex.EncodeToString(tx.ProcessId)) } case *models.Tx_SetAccount: @@ -253,41 +271,24 @@ func (t *TransactionHandler) CheckTx(vtx *vochaintx.Tx, forCommit bool) (*Transa return nil, fmt.Errorf("setAccountTx: SetAddressSIK %w", err) } } - if tx.FaucetPackage != nil { - faucetIssuerAddress, err := ethereum.AddrFromSignature(tx.FaucetPackage.Payload, tx.FaucetPackage.Signature) - if err != nil { - return nil, fmt.Errorf("createAccountTx: faucetIssuerAddress %w", err) - } - txCost, err := t.state.TxBaseCost(models.TxType_CREATE_ACCOUNT, false) - if err != nil { - return nil, fmt.Errorf("createAccountTx: txCost %w", err) - } - if txCost != 0 { - if err := t.state.BurnTxCost(faucetIssuerAddress, txCost); err != nil { - return nil, fmt.Errorf("setAccountTx: burnTxCost %w", err) - } - } - faucetPayload := &models.FaucetPayload{} - if err := proto.Unmarshal(tx.FaucetPackage.Payload, faucetPayload); err != nil { - return nil, fmt.Errorf("createAccountTx: cannot unmarshal faucetPayload %w", err) - } - if err := t.state.ConsumeFaucetPayload( - faucetIssuerAddress, - faucetPayload, - ); err != nil { - return nil, fmt.Errorf("setAccountTx: consumeFaucet %w", err) - } - if err := t.state.TransferBalance(&vochaintx.TokenTransfer{ - FromAddress: faucetIssuerAddress, - ToAddress: txSenderAddress, - Amount: faucetPayload.Amount, - TxHash: vtx.TxID[:], - }, false); err != nil { - return nil, fmt.Errorf("setAccountTx: transferBalance %w", err) - } - // transfer balance from faucet package issuer to created account - return response, nil + txCost, err := t.state.TxBaseCost(models.TxType_CREATE_ACCOUNT, false) + if err != nil { + return nil, fmt.Errorf("createAccountTx: txCost %w", err) + } + + // transfer balance from faucet package issuer to created account + canPayWithFaucet, err := t.checkFaucetPackageAndTransfer(tx.FaucetPackage, txCost, txSenderAddress, vtx.TxID[:], true) + if err != nil { + return nil, fmt.Errorf("could not verify the faucet package: %w", err) + } + if !canPayWithFaucet { + return nil, fmt.Errorf("faucet package is not enough for paying for the transaction cost") } + // burn the cost of the transaction from the txSender account + if err := t.state.BurnTxCost(txSenderAddress, txCost); err != nil { + return nil, err + } + return response, nil case models.TxType_SET_ACCOUNT_INFO_URI: @@ -295,11 +296,19 @@ func (t *TransactionHandler) CheckTx(vtx *vochaintx.Tx, forCommit bool) (*Transa if err != nil { return nil, fmt.Errorf("setAccountInfo: txSenderAddress %w", err) } + txCost, err := t.state.TxBaseCost(models.TxType_SET_ACCOUNT_INFO_URI, false) + if err != nil { + return nil, fmt.Errorf("setAccountInfoUriTx: txCost: %w", err) + } + // check for a faucet package and if exist, transfer the amount to the tx sender + if _, err := t.checkFaucetPackageAndTransfer(tx.FaucetPackage, txCost, txSenderAddress, vtx.TxID[:], true); err != nil { + return nil, err + } // consume cost for setAccount if err := t.state.BurnTxCostIncrementNonce( txSenderAddress, models.TxType_SET_ACCOUNT_INFO_URI, - 0, + txCost, tx.GetInfoURI(), ); err != nil { return nil, fmt.Errorf("setAccountInfo: burnCostIncrementNonce %w", err) @@ -321,10 +330,18 @@ func (t *TransactionHandler) CheckTx(vtx *vochaintx.Tx, forCommit bool) (*Transa if err != nil { return nil, fmt.Errorf("addDelegate: txSenderAddress %w", err) } + txCost, err := t.state.TxBaseCost(models.TxType_ADD_DELEGATE_FOR_ACCOUNT, false) + if err != nil { + return nil, fmt.Errorf("addDelegate: txCost: %w", err) + } + // check for a faucet package and if exist, transfer the amount to the tx sender + if _, err := t.checkFaucetPackageAndTransfer(tx.FaucetPackage, txCost, txSenderAddress, vtx.TxID[:], true); err != nil { + return nil, err + } if err := t.state.BurnTxCostIncrementNonce( txSenderAddress, models.TxType_ADD_DELEGATE_FOR_ACCOUNT, - 0, + txCost, "", ); err != nil { return nil, fmt.Errorf("addDelegate: burnTxCostIncrementNonce %w", err) @@ -341,10 +358,18 @@ func (t *TransactionHandler) CheckTx(vtx *vochaintx.Tx, forCommit bool) (*Transa if err != nil { return nil, fmt.Errorf("delDelegate: txSenderAddress %w", err) } + txCost, err := t.state.TxBaseCost(models.TxType_DEL_DELEGATE_FOR_ACCOUNT, false) + if err != nil { + return nil, fmt.Errorf("delDelegate: txCost: %w", err) + } + // check for a faucet package and if exist, transfer the amount to the tx sender + if _, err := t.checkFaucetPackageAndTransfer(tx.FaucetPackage, txCost, txSenderAddress, vtx.TxID[:], true); err != nil { + return nil, err + } if err := t.state.BurnTxCostIncrementNonce( txSenderAddress, models.TxType_DEL_DELEGATE_FOR_ACCOUNT, - 0, + txCost, "", ); err != nil { return nil, fmt.Errorf("delDelegate: burnTxCostIncrementNonce %w", err) @@ -361,6 +386,14 @@ func (t *TransactionHandler) CheckTx(vtx *vochaintx.Tx, forCommit bool) (*Transa if err != nil { return nil, fmt.Errorf("setValidator: txSenderAddress %w", err) } + txCost, err := t.state.TxBaseCost(models.TxType_SET_ACCOUNT_VALIDATOR, false) + if err != nil { + return nil, fmt.Errorf("setValidator: txCost: %w", err) + } + // check for a faucet package and if exist, transfer the amount to the tx sender + if _, err := t.checkFaucetPackageAndTransfer(tx.FaucetPackage, txCost, txSenderAddress, vtx.TxID[:], true); err != nil { + return nil, err + } validatorAddr, err := ethereum.AddrFromPublicKey(tx.GetPublicKey()) if err != nil { return nil, fmt.Errorf("setValidator: %w", err) @@ -368,7 +401,7 @@ func (t *TransactionHandler) CheckTx(vtx *vochaintx.Tx, forCommit bool) (*Transa if err := t.state.BurnTxCostIncrementNonce( txSenderAddress, models.TxType_SET_ACCOUNT_VALIDATOR, - 0, + txCost, validatorAddr.Hex(), ); err != nil { return nil, fmt.Errorf("setValidator: burnTxCostIncrementNonce %w", err) @@ -456,10 +489,18 @@ func (t *TransactionHandler) CheckTx(vtx *vochaintx.Tx, forCommit bool) (*Transa return nil, fmt.Errorf("setSIKTx: %w", err) } if forCommit { + txCost, err := t.state.TxBaseCost(models.TxType_SET_ACCOUNT_SIK, false) + if err != nil { + return nil, fmt.Errorf("setAccountInfoUriTx: txCost: %w", err) + } + // check for a faucet package and if exist, transfer the amount to the tx sender + if _, err := t.checkFaucetPackageAndTransfer(vtx.Tx.GetSetSIK().FaucetPackage, txCost, txAddress, vtx.TxID[:], true); err != nil { + return nil, err + } if err := t.state.BurnTxCostIncrementNonce( txAddress, models.TxType_SET_ACCOUNT_SIK, - 0, + txCost, newSIK.String(), ); err != nil { return nil, fmt.Errorf("setSIKTx: burnTxCostIncrementNonce %w", err) @@ -476,10 +517,18 @@ func (t *TransactionHandler) CheckTx(vtx *vochaintx.Tx, forCommit bool) (*Transa return nil, fmt.Errorf("delSIKTx: %w", err) } if forCommit { + txCost, err := t.state.TxBaseCost(models.TxType_DEL_ACCOUNT_SIK, false) + if err != nil { + return nil, fmt.Errorf("delSIKTx: txCost: %w", err) + } + // check for a faucet package and if exist, transfer the amount to the tx sender + if _, err := t.checkFaucetPackageAndTransfer(vtx.Tx.GetSetSIK().FaucetPackage, txCost, txAddress, vtx.TxID[:], true); err != nil { + return nil, err + } if err := t.state.BurnTxCostIncrementNonce( txAddress, models.TxType_DEL_ACCOUNT_SIK, - 0, + txCost, "", ); err != nil { return nil, fmt.Errorf("delSIKTx: burnTxCostIncrementNonce %w", err) @@ -522,6 +571,7 @@ func (t *TransactionHandler) CheckTx(vtx *vochaintx.Tx, forCommit bool) (*Transa // checkAccountCanPayCost checks if the account can pay the cost of the transaction. // It returns the account and the address of the sender. +// It also checks if a faucet package is available in the transaction and can pay for it. func (t *TransactionHandler) checkAccountCanPayCost(txType models.TxType, vtx *vochaintx.Tx) (*vstate.Account, *common.Address, error) { // extract sender address from signature pubKey, err := ethereum.PubKeyFromSignature(vtx.SignedBody, vtx.Signature) @@ -544,9 +594,106 @@ func (t *TransactionHandler) checkAccountCanPayCost(txType models.TxType, vtx *v if err != nil { return nil, nil, fmt.Errorf("cannot get tx cost for %s: %w", txType.String(), err) } - // check tx sender balance - if txSenderAcc.Balance < cost { - return nil, nil, fmt.Errorf("unauthorized: %s", vstate.ErrNotEnoughBalance) + + if cost > 0 { + // check if faucet package can pay for the transaction + canFaucetPackagePay, err := t.checkFaucetPackageAndTransfer(vtx.GetFaucetPackage(), cost, txSenderAddress, vtx.TxID[:], false) + if err != nil { + return nil, nil, err + } + + // if faucet cannot pay for it, check tx sender balance + if !canFaucetPackagePay { + if txSenderAcc.Balance < cost { + return nil, nil, fmt.Errorf("unauthorized: %s", vstate.ErrNotEnoughBalance) + } + } } return txSenderAcc, &txSenderAddress, nil } + +// checkFaucetPackageAndTransfer checks if the txFaucetPackage is a valid Faucet package issued for txSenderAddress and the account signing the faucet package has +// enough funds for paying for the txCost. +// If forCommit is true, the faucet package balance is transferred to the txSender account. +// Returns false and no error if the faucet package does not exist. If it exists but there is an issue, returns false and the error. +func (t *TransactionHandler) checkFaucetPackageAndTransfer(txFaucetPackage *models.FaucetPackage, txCost uint64, txSenderAddress common.Address, txHash []byte, forCommit bool) (bool, error) { + if txFaucetPackage == nil { + if txCost == 0 { + return true, nil + } + return false, nil + } + if txFaucetPackage.Payload == nil { + return false, fmt.Errorf("invalid faucet package payload") + } + faucetPayload := &models.FaucetPayload{} + if err := proto.Unmarshal(txFaucetPackage.Payload, faucetPayload); err != nil { + return false, fmt.Errorf("could not unmarshal faucet package: %w", err) + } + if faucetPayload.Amount == 0 { + return false, fmt.Errorf("invalid faucet payload amount provided") + } + if faucetPayload.To == nil { + return false, fmt.Errorf("invalid to address provided") + } + if !bytes.Equal(faucetPayload.To, txSenderAddress.Bytes()) { + return false, fmt.Errorf("payload to and tx sender missmatch (%x != %x)", + faucetPayload.To, txSenderAddress.Bytes()) + } + issuerAddress, err := ethereum.AddrFromSignature(txFaucetPackage.Payload, txFaucetPackage.Signature) + if err != nil { + return false, fmt.Errorf("cannot extract issuer address from faucet package vtx.Signature: %w", err) + } + issuerBalance, err := t.state.AccountBalance(issuerAddress, false) + if err != nil { + return false, fmt.Errorf("cannot get faucet issuer balance: %w", err) + } + b := make([]byte, 8) + binary.LittleEndian.PutUint64(b, faucetPayload.Identifier) + keyHash := ethereum.HashRaw(append(issuerAddress.Bytes(), b...)) + used, err := t.state.FaucetNonce(keyHash, false) + if err != nil { + return false, fmt.Errorf("cannot check if faucet payload already used: %w", err) + } + if used { + return false, fmt.Errorf("faucet payload %x already used", keyHash) + } + if issuerBalance < faucetPayload.Amount { + return false, fmt.Errorf( + "issuer address does not have enough balance %d, required %d", + issuerBalance, + faucetPayload.Amount, + ) + } + + balance, err := t.state.AccountBalance(txSenderAddress, false) + if err != nil { + return false, fmt.Errorf("cannot get tx sender balance: %w", err) + } + if balance+faucetPayload.Amount < txCost { + return false, fmt.Errorf( + "account balance (%d) + faucet amount (%d) is not enough to pay the tx cost %d", + balance, faucetPayload.Amount, txCost, + ) + } + + // if forCommit, then the cost of the transaction is consumed from the faucet + if forCommit { + if err := t.state.ConsumeFaucetPayload( + issuerAddress, + faucetPayload, + ); err != nil { + return false, fmt.Errorf("consumeFaucet: %w", err) + } + if err := t.state.TransferBalance(&vochaintx.TokenTransfer{ + FromAddress: issuerAddress, + ToAddress: txSenderAddress, + Amount: faucetPayload.Amount, + TxHash: txHash, + }, false); err != nil { + return false, fmt.Errorf("consumeFaucet: %w", err) + } + } + + return true, nil +} diff --git a/vochain/transaction/vochaintx/vochaintx.go b/vochain/transaction/vochaintx/vochaintx.go index f413e5e3b..5781135a7 100644 --- a/vochain/transaction/vochaintx/vochaintx.go +++ b/vochain/transaction/vochaintx/vochaintx.go @@ -50,6 +50,32 @@ func (tx *Tx) Unmarshal(content []byte, chainID string) error { return nil } +// TxSubtype returns the content of the "txtype" field inside the tx.Tx. +// +// The function determines the type of the transaction using Protocol Buffers reflection. +// If the field doesn't exist, it returns the empty string "". +func (tx *Tx) TxSubtype() string { + txReflectDescriptor := tx.Tx.ProtoReflect().Descriptor().Oneofs().Get(0) + if txReflectDescriptor == nil { + return "" + } + whichOneTxModelType := tx.Tx.ProtoReflect().WhichOneof(txReflectDescriptor) + if whichOneTxModelType == nil { + return "" + } + // Get the value of the selected field in the oneof + fieldValue := tx.Tx.ProtoReflect().Get(whichOneTxModelType) + // Now, fieldValue is a protoreflect.Value, retrieve the txtype field + txtypeFieldDescriptor := fieldValue.Message().Descriptor().Fields().ByName("txtype") + if txtypeFieldDescriptor == nil { + return "" + } + // Get the integer value of txtype as protoreflect.EnumNumber + enumNumber := fieldValue.Message().Get(txtypeFieldDescriptor).Enum() + // Convert the EnumNumber to a string using the EnumType descriptor + return string(txtypeFieldDescriptor.Enum().Values().ByNumber(enumNumber).Name()) +} + // TxKey computes the checksum of the tx func TxKey(tx []byte) [32]byte { return comettypes.Tx(tx).Key() @@ -62,3 +88,23 @@ type TokenTransfer struct { Amount uint64 TxHash []byte } + +// GetFaucetPackage returns the FaucetPackage found inside the tx.Tx.Payload, or nil if not found. +func (tx *Tx) GetFaucetPackage() *models.FaucetPackage { + switch tx.Tx.Payload.(type) { + case *models.Tx_NewProcess: + return tx.Tx.GetNewProcess().GetFaucetPackage() + case *models.Tx_SetProcess: + return tx.Tx.GetSetProcess().GetFaucetPackage() + case *models.Tx_SetAccount: + return tx.Tx.GetSetAccount().GetFaucetPackage() + case *models.Tx_CollectFaucet: + return tx.Tx.GetCollectFaucet().GetFaucetPackage() + case *models.Tx_SetSIK: + return tx.Tx.GetSetSIK().GetFaucetPackage() + case *models.Tx_DelSIK: + return tx.Tx.GetDelSIK().GetFaucetPackage() + default: + return nil + } +} diff --git a/vochain/transaction_zk_test.go b/vochain/transaction_zk_test.go index 73d3839ab..89422d271 100644 --- a/vochain/transaction_zk_test.go +++ b/vochain/transaction_zk_test.go @@ -187,7 +187,7 @@ func TestMaxCensusSizeRegisterSIKTx(t *testing.T) { c.Assert(app.State.AddProcess(process), qt.IsNil) app.AdvanceTestBlock() - encWeight := arbo.BigIntToBytes(arbo.HashFunctionPoseidon.Len(), testWeight) + encWeight := arbo.BigIntToBytesLE(arbo.HashFunctionPoseidon.Len(), testWeight) tx := testBuildSignedRegisterSIKTx(t, accounts[0], pid, proofs[0], encWeight, app.chainID) _, _, _, _, err := app.TransactionHandler.RegisterSIKTxCheck(tx) c.Assert(err, qt.IsNil) diff --git a/vochain/vote_test.go b/vochain/vote_test.go index 0af7ba480..cf04fcec9 100644 --- a/vochain/vote_test.go +++ b/vochain/vote_test.go @@ -31,7 +31,7 @@ func testCreateKeysAndBuildWeightedZkCensus(t *testing.T, size int, weight *big. t.Fatal(err) } - encWeight := arbo.BigIntToBytes(arbo.HashFunctionPoseidon.Len(), weight) + encWeight := arbo.BigIntToBytesLE(arbo.HashFunctionPoseidon.Len(), weight) keys := ethereum.NewSignKeysBatch(size) for _, k := range keys { qt.Check(t, err, qt.IsNil)