From 56d86caf5666c07a9d89d3950a56d980f02024d9 Mon Sep 17 00:00:00 2001 From: John Lee Date: Tue, 17 Sep 2024 11:00:30 -0400 Subject: [PATCH 01/13] CI: update CircleCI Ubuntu image to 24.04 (#1633) * Update CircleCI ubuntu image to 24.04 * Also remove deprecated CODEOWNERS file. * Force lower cython for PyYAML version, which is necessary for newer Python. Otherwise we should vet newer PyYAML. * Revert "Force lower cython for PyYAML version, which is necessary for newer Python. Otherwise we should vet newer PyYAML." This reverts commit 018c354f3fd55e92ac5e0ddb71bcb9943a2ec38b. * Instead of forcing cython we should just bump PyYAML * Also bump PyYAML in e2e_tests. --- .circleci/config.yml | 2 +- CODEOWNERS | 2 -- e2e_tests/pyproject.toml | 2 +- misc/requirements.txt | 4 ++-- 4 files changed, 4 insertions(+), 6 deletions(-) delete mode 100644 CODEOWNERS diff --git a/.circleci/config.yml b/.circleci/config.yml index a1e3e1fce..ea2584127 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -8,7 +8,7 @@ orbs: parameters: ubuntu_image: type: string - default: "ubuntu-2204:2022.04.2" + default: "ubuntu-2404:2024.05.1" workflows: version: 2 diff --git a/CODEOWNERS b/CODEOWNERS deleted file mode 100644 index 5ffa97e9d..000000000 --- a/CODEOWNERS +++ /dev/null @@ -1,2 +0,0 @@ -.github/ @algorand/lamprey -.circleci/ @algorand/lamprey diff --git a/e2e_tests/pyproject.toml b/e2e_tests/pyproject.toml index 26a0da0fd..d440b5d17 100644 --- a/e2e_tests/pyproject.toml +++ b/e2e_tests/pyproject.toml @@ -12,7 +12,7 @@ dependencies = [ "msgpack==1.0.4", "py-algorand-sdk==1.17.0", "pytest==6.2.5", - "PyYAML==6.0", + "PyYAML==6.0.2", "setuptools ==70.0.0", ] diff --git a/misc/requirements.txt b/misc/requirements.txt index 611315496..1551f18cb 100644 --- a/misc/requirements.txt +++ b/misc/requirements.txt @@ -4,5 +4,5 @@ msgpack >=1,<2 py-algorand-sdk >=1.3.0,<2 pytest==6.2.5 GitPython==3.1.41 -PyYAML==6.0 -requests==2.32.0 \ No newline at end of file +PyYAML==6.0.2 +requests==2.32.0 From 6dce903c2d5f807962dd03c41903ede7067e4f7d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 18 Sep 2024 11:48:22 -0400 Subject: [PATCH 02/13] build(deps): bump github.com/docker/docker (#1621) Bumps [github.com/docker/docker](https://github.com/docker/docker) from 24.0.9+incompatible to 25.0.6+incompatible. - [Release notes](https://github.com/docker/docker/releases) - [Commits](https://github.com/docker/docker/compare/v24.0.9...v25.0.6) --- updated-dependencies: - dependency-name: github.com/docker/docker dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 33 ++++++++++++++-------- go.sum | 86 +++++++++++++++++++++++++++++++++++++++++----------------- 2 files changed, 82 insertions(+), 37 deletions(-) diff --git a/go.mod b/go.mod index 3c460e5cc..af91e6d66 100644 --- a/go.mod +++ b/go.mod @@ -20,11 +20,11 @@ require ( github.com/orlangure/gnomock v0.28.0 github.com/pmezard/go-difflib v1.0.0 github.com/prometheus/client_golang v1.11.1 - github.com/sirupsen/logrus v1.8.1 + github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.3.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.10.0 - github.com/stretchr/testify v1.8.2 + github.com/stretchr/testify v1.9.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -35,19 +35,22 @@ require ( github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/containerd/log v0.1.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect github.com/distribution/reference v0.5.0 // indirect - github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v24.0.9+incompatible // indirect + github.com/docker/docker v25.0.6+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.5.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.19.6 // indirect github.com/go-openapi/swag v0.22.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/uuid v1.3.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect github.com/invopop/yaml v0.1.0 // indirect @@ -81,20 +84,26 @@ require ( github.com/spf13/afero v1.6.0 // indirect github.com/spf13/cast v1.4.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect - github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.2.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasttemplate v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect + go.opentelemetry.io/otel v1.28.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 // indirect + go.opentelemetry.io/otel/metric v1.28.0 // indirect + go.opentelemetry.io/otel/sdk v1.28.0 // indirect + go.opentelemetry.io/otel/trace v1.28.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.7.0 // indirect go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.21.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/text v0.14.0 // indirect + golang.org/x/crypto v0.24.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect - google.golang.org/protobuf v1.33.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.66.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 88241e1b1..a199eea41 100644 --- a/go.sum +++ b/go.sum @@ -102,7 +102,10 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= github.com/casbin/casbin/v2 v2.31.2/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= +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.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/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -132,6 +135,8 @@ github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -150,10 +155,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= -github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0= -github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg= +github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= @@ -178,6 +181,8 @@ github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= @@ -197,6 +202,11 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= @@ -267,8 +277,8 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -291,8 +301,8 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLe github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -308,7 +318,10 @@ github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= @@ -636,8 +649,8 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -666,8 +679,9 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -677,8 +691,8 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= @@ -714,7 +728,23 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 h1:4K4tsIXefpVJtvA/8srF4V4y0akAoPHkIslgAkjixJA= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= +go.opentelemetry.io/otel v1.28.0 h1:/SqNcYk+idO0CxKEUOtKQClMK/MimZihKYMruSMViUo= +go.opentelemetry.io/otel v1.28.0/go.mod h1:q68ijF8Fc8CnMHKyzqL6akLO46ePnjkgfIMIjUIX9z4= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0 h1:3Q/xZUyC1BBkualc9ROb4G8qkH90LXEIICcs5zv1OYY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.28.0/go.mod h1:s75jGIWA9OfCMzF0xr+ZgfrB5FEbbV7UuYo32ahUiFI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 h1:j9+03ymgYhPKmeXGk5Zu+cIZOlVzd9Zv7QIiyItjFBU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0/go.mod h1:Y5+XiUG4Emn1hTfciPzGPJaSI+RpDts6BnCIir0SLqk= +go.opentelemetry.io/otel/metric v1.28.0 h1:f0HGvSl1KRAU1DLgLGFjrwVyismPlnuU6JD6bOeuA5Q= +go.opentelemetry.io/otel/metric v1.28.0/go.mod h1:Fb1eVBFZmLVTMb6PPohq3TO9IIhUisDsbJoL/+uQW4s= +go.opentelemetry.io/otel/sdk v1.28.0 h1:b9d7hIry8yZsgtbmM0DKyPWMMUMlK9NEKuIG4aBqWyE= +go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= +go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+lkx9g= +go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +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= @@ -754,8 +784,8 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= -golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= 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= @@ -844,8 +874,8 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -874,8 +904,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= -golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -956,8 +986,9 @@ golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -969,8 +1000,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.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= @@ -1157,7 +1188,10 @@ google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1190,6 +1224,8 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +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/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= 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= @@ -1204,8 +1240,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= 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= From ecbedc4c50e46daaeeccf0ca78d0e8a88e8cc9c1 Mon Sep 17 00:00:00 2001 From: cce <51567+cce@users.noreply.github.com> Date: Thu, 19 Sep 2024 10:34:12 -0400 Subject: [PATCH 03/13] CI: Enable linting for tests (#1632) * use linter for tests * fix lint * remove failing AddBlock(&genBlock) from TestDeleteTransactions --- .golangci.yml | 4 +-- api/app_boxes_fixtures_test.go | 7 ++--- api/handlers_e2e_test.go | 5 ++-- api/handlers_test.go | 11 ++++---- api/util_test.go | 4 +-- cmd/algorand-indexer/daemon_test.go | 17 ++++++------ cmd/validator/core/validator_test.go | 4 +-- idb/idb_test.go | 3 ++- .../internal/encoding/encoding_test.go | 9 ++++--- .../migrations/convert_account_data/m_test.go | 3 ++- idb/postgres/postgres_boxes_test.go | 2 +- .../postgres_integration_common_test.go | 7 ++--- idb/postgres/postgres_integration_test.go | 23 +++++++--------- idb/postgres/postgres_migrations_test.go | 3 ++- idb/postgres/postgres_rand_test.go | 4 +-- idb/postgres/postgres_test.go | 26 +++++++++---------- types/min_balance_test.go | 6 +++-- util/util_test.go | 4 +-- 18 files changed, 74 insertions(+), 68 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 1854949cd..c9ccc8849 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,6 +1,6 @@ run: timeout: 5m - tests: false + tests: true linters: disable-all: true @@ -66,4 +66,4 @@ issues: # revive: ignore some rules - "^unused-parameter: parameter" - - "^package-comments: should have a package comment" \ No newline at end of file + - "^package-comments: should have a package comment" diff --git a/api/app_boxes_fixtures_test.go b/api/app_boxes_fixtures_test.go index 8d067b25e..df05e2f38 100644 --- a/api/app_boxes_fixtures_test.go +++ b/api/app_boxes_fixtures_test.go @@ -6,13 +6,14 @@ import ( "fmt" "testing" - "github.com/algorand/indexer/v3/idb/postgres" "github.com/stretchr/testify/require" "github.com/algorand/avm-abi/apps" + "github.com/algorand/indexer/v3/idb/postgres" + "github.com/algorand/indexer/v3/util/test" + "github.com/algorand/go-algorand-sdk/v2/crypto" sdk "github.com/algorand/go-algorand-sdk/v2/types" - "github.com/algorand/indexer/v3/util/test" ) func goalEncode(t *testing.T, s string) string { @@ -23,7 +24,7 @@ func goalEncode(t *testing.T, s string) string { return string(b2) } -var goalEncodingExamples map[string]string = map[string]string{ +var goalEncodingExamples = map[string]string{ "str": "str", "string": "string", "int": "42", diff --git a/api/handlers_e2e_test.go b/api/handlers_e2e_test.go index 0808b60cd..a581bcc47 100644 --- a/api/handlers_e2e_test.go +++ b/api/handlers_e2e_test.go @@ -19,6 +19,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/algorand/avm-abi/apps" "github.com/algorand/indexer/v3/api/generated/v2" "github.com/algorand/indexer/v3/idb" "github.com/algorand/indexer/v3/idb/postgres" @@ -27,7 +28,6 @@ import ( "github.com/algorand/indexer/v3/util" "github.com/algorand/indexer/v3/util/test" - "github.com/algorand/avm-abi/apps" "github.com/algorand/go-algorand-sdk/v2/crypto" "github.com/algorand/go-algorand-sdk/v2/encoding/json" sdk "github.com/algorand/go-algorand-sdk/v2/types" @@ -80,7 +80,7 @@ func setupIdb(t *testing.T, genesis sdk.Genesis) (*postgres.IndexerDb, func()) { Block: test.MakeGenesisBlock(), Delta: sdk.LedgerStateDelta{}, } - db.AddBlock(&vb) + require.NoError(t, db.AddBlock(&vb)) require.NoError(t, err) return db, newShutdownFunc @@ -1738,6 +1738,7 @@ func TestGetBlockWithCompression(t *testing.T) { // we now make sure that compression flag works with other flags. notCompressedBlock = getBlockFunc(t, true, false) compressedBlock = getBlockFunc(t, true, true) + require.Equal(t, notCompressedBlock, compressedBlock) require.Equal(t, len(*notCompressedBlock.Transactions), 0) } diff --git a/api/handlers_test.go b/api/handlers_test.go index c5b2e40da..6a2938900 100644 --- a/api/handlers_test.go +++ b/api/handlers_test.go @@ -17,13 +17,14 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" - sdkcrypto "github.com/algorand/go-algorand-sdk/v2/crypto" - "github.com/algorand/go-algorand-sdk/v2/encoding/msgpack" - sdk "github.com/algorand/go-algorand-sdk/v2/types" "github.com/algorand/indexer/v3/api/generated/v2" "github.com/algorand/indexer/v3/idb" "github.com/algorand/indexer/v3/idb/mocks" "github.com/algorand/indexer/v3/types" + + sdkcrypto "github.com/algorand/go-algorand-sdk/v2/crypto" + "github.com/algorand/go-algorand-sdk/v2/encoding/msgpack" + sdk "github.com/algorand/go-algorand-sdk/v2/types" ) func TestTransactionParamToTransactionFilter(t *testing.T) { @@ -1187,7 +1188,7 @@ func TestBigNumbers(t *testing.T) { c := e.NewContext(req, rec1) // call handler - tc.callHandler(c, *si) + require.NoError(t, tc.callHandler(c, *si)) assert.Equal(t, http.StatusNotFound, rec1.Code) bodyStr := rec1.Body.String() require.Contains(t, bodyStr, tc.errString) @@ -1234,7 +1235,7 @@ func TestRewindRoundParameterRejected(t *testing.T) { c := e.NewContext(req, rec1) // call handler - tc.callHandler(c, *si) + require.NoError(t, tc.callHandler(c, *si)) assert.Equal(t, http.StatusBadRequest, rec1.Code) bodyStr := rec1.Body.String() require.Contains(t, bodyStr, tc.errString) diff --git a/api/util_test.go b/api/util_test.go index 95d4ab39a..8fa07b1af 100644 --- a/api/util_test.go +++ b/api/util_test.go @@ -9,9 +9,9 @@ import ( "github.com/sirupsen/logrus/hooks/test" "github.com/stretchr/testify/require" - "github.com/algorand/go-algorand-sdk/v2/types" - "github.com/algorand/indexer/v3/idb" + + "github.com/algorand/go-algorand-sdk/v2/types" ) func TestCallWithTimeoutTimesOut(t *testing.T) { diff --git a/cmd/algorand-indexer/daemon_test.go b/cmd/algorand-indexer/daemon_test.go index 62262d3f8..36aa887e4 100644 --- a/cmd/algorand-indexer/daemon_test.go +++ b/cmd/algorand-indexer/daemon_test.go @@ -12,6 +12,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/spf13/pflag" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/algorand/indexer/v3/config" "github.com/algorand/indexer/v3/util" @@ -23,7 +24,7 @@ func TestParameterConfigErrorWhenBothFileTypesArePresent(t *testing.T) { indexerDataDir := t.TempDir() for _, configFiletype := range config.FileTypes { autoloadPath := filepath.Join(indexerDataDir, autoLoadParameterConfigFileName+"."+configFiletype) - os.WriteFile(autoloadPath, []byte{}, fs.ModePerm) + require.NoError(t, os.WriteFile(autoloadPath, []byte{}, fs.ModePerm)) } daemonConfig := &daemonConfig{} @@ -41,7 +42,7 @@ func TestIndexerConfigErrorWhenBothFileTypesArePresent(t *testing.T) { indexerDataDir := t.TempDir() for _, configFiletype := range config.FileTypes { autoloadPath := filepath.Join(indexerDataDir, autoLoadIndexerConfigFileName+"."+configFiletype) - os.WriteFile(autoloadPath, []byte{}, fs.ModePerm) + require.NoError(t, os.WriteFile(autoloadPath, []byte{}, fs.ModePerm)) } daemonConfig := &daemonConfig{} @@ -59,7 +60,7 @@ func TestConfigWithEnableAllParamsExpectError(t *testing.T) { for _, configFiletype := range config.FileTypes { indexerDataDir := t.TempDir() autoloadPath := filepath.Join(indexerDataDir, autoLoadIndexerConfigFileName+"."+configFiletype) - os.WriteFile(autoloadPath, []byte{}, fs.ModePerm) + require.NoError(t, os.WriteFile(autoloadPath, []byte{}, fs.ModePerm)) daemonConfig := &daemonConfig{} daemonConfig.flags = pflag.NewFlagSet("indexer", 0) daemonConfig.indexerDataDir = indexerDataDir @@ -88,7 +89,7 @@ func TestConfigInvalidExpectError(t *testing.T) { b := bytes.NewBufferString("") indexerDataDir := t.TempDir() tempConfigFile := indexerDataDir + "/indexer-alt.yml" - os.WriteFile(tempConfigFile, []byte(";;;"), fs.ModePerm) + require.NoError(t, os.WriteFile(tempConfigFile, []byte(";;;"), fs.ModePerm)) daemonConfig := &daemonConfig{} daemonConfig.flags = pflag.NewFlagSet("indexer", 0) daemonConfig.indexerDataDir = indexerDataDir @@ -102,7 +103,7 @@ func TestConfigInvalidExpectError(t *testing.T) { func TestConfigSpecifiedTwiceExpectError(t *testing.T) { indexerDataDir := t.TempDir() tempConfigFile := indexerDataDir + "/indexer.yml" - os.WriteFile(tempConfigFile, []byte{}, fs.ModePerm) + require.NoError(t, os.WriteFile(tempConfigFile, []byte{}, fs.ModePerm)) daemonConfig := &daemonConfig{} daemonConfig.flags = pflag.NewFlagSet("indexer", 0) daemonConfig.indexerDataDir = indexerDataDir @@ -120,7 +121,7 @@ func TestLoadAPIConfigGivenAutoLoadAndUserSuppliedExpectError(t *testing.T) { autoloadPath := filepath.Join(indexerDataDir, autoLoadParameterConfigFileName+"."+configFiletype) userSuppliedPath := filepath.Join(indexerDataDir, "foobar.yml") - os.WriteFile(autoloadPath, []byte{}, fs.ModePerm) + require.NoError(t, os.WriteFile(autoloadPath, []byte{}, fs.ModePerm)) cfg := &daemonConfig{} cfg.indexerDataDir = indexerDataDir cfg.suppliedAPIConfigFile = userSuppliedPath @@ -149,7 +150,7 @@ func TestLoadAPIConfigGivenAutoLoadExpectSuccess(t *testing.T) { indexerDataDir := t.TempDir() autoloadPath := filepath.Join(indexerDataDir, autoLoadParameterConfigFileName+"."+configFiletype) - os.WriteFile(autoloadPath, []byte{}, fs.ModePerm) + require.NoError(t, os.WriteFile(autoloadPath, []byte{}, fs.ModePerm)) cfg := &daemonConfig{} cfg.indexerDataDir = indexerDataDir @@ -180,7 +181,7 @@ func TestIndexerPidFileCreateFailExpectError(t *testing.T) { for _, configFiletype := range config.FileTypes { indexerDataDir := t.TempDir() autoloadPath := filepath.Join(indexerDataDir, autoLoadIndexerConfigFileName+"."+configFiletype) - os.WriteFile(autoloadPath, []byte{}, fs.ModePerm) + require.NoError(t, os.WriteFile(autoloadPath, []byte{}, fs.ModePerm)) invalidDir := filepath.Join(indexerDataDir, "foo", "bar") cfg := &daemonConfig{} diff --git a/cmd/validator/core/validator_test.go b/cmd/validator/core/validator_test.go index deb8b26ef..c7755b956 100644 --- a/cmd/validator/core/validator_test.go +++ b/cmd/validator/core/validator_test.go @@ -7,9 +7,9 @@ import ( "github.com/jarcoal/httpmock" "github.com/stretchr/testify/require" - "github.com/algorand/go-algorand-sdk/v2/types" - "github.com/algorand/indexer/v3/api" + + "github.com/algorand/go-algorand-sdk/v2/types" ) type mockProcessor struct { diff --git a/idb/idb_test.go b/idb/idb_test.go index 0fa7af7a2..51653ce68 100644 --- a/idb/idb_test.go +++ b/idb/idb_test.go @@ -6,9 +6,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - sdk "github.com/algorand/go-algorand-sdk/v2/types" "github.com/algorand/indexer/v3/idb" "github.com/algorand/indexer/v3/util/test" + + sdk "github.com/algorand/go-algorand-sdk/v2/types" ) func TestTxnRowNext(t *testing.T) { diff --git a/idb/postgres/internal/encoding/encoding_test.go b/idb/postgres/internal/encoding/encoding_test.go index 50ca9ff76..8b8e1b6ed 100644 --- a/idb/postgres/internal/encoding/encoding_test.go +++ b/idb/postgres/internal/encoding/encoding_test.go @@ -4,14 +4,15 @@ import ( "fmt" "testing" - "github.com/algorand/go-algorand-sdk/v2/encoding/msgpack" - sdk "github.com/algorand/go-algorand-sdk/v2/types" - itypes "github.com/algorand/indexer/v3/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/algorand/indexer/v3/idb" "github.com/algorand/indexer/v3/idb/postgres/internal/types" + itypes "github.com/algorand/indexer/v3/types" + + "github.com/algorand/go-algorand-sdk/v2/encoding/msgpack" + sdk "github.com/algorand/go-algorand-sdk/v2/types" ) func TestEncodeSignedTxnWithAD(t *testing.T) { @@ -42,7 +43,7 @@ func TestEncodeSignedTxnWithAD(t *testing.T) { var stxn sdk.SignedTxnWithAD for _, mt := range testTxns { t.Run(mt.name, func(t *testing.T) { - msgpack.Decode(mt.msgpack, &stxn) + require.NoError(t, msgpack.Decode(mt.msgpack, &stxn)) js := EncodeSignedTxnWithAD(stxn) require.Equal(t, mt.json, string(js)) }) diff --git a/idb/postgres/internal/migrations/convert_account_data/m_test.go b/idb/postgres/internal/migrations/convert_account_data/m_test.go index a00fd27c5..f4a97fb39 100644 --- a/idb/postgres/internal/migrations/convert_account_data/m_test.go +++ b/idb/postgres/internal/migrations/convert_account_data/m_test.go @@ -5,7 +5,6 @@ import ( "fmt" "testing" - sdk "github.com/algorand/go-algorand-sdk/v2/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -16,6 +15,8 @@ import ( cad "github.com/algorand/indexer/v3/idb/postgres/internal/migrations/convert_account_data" pgtest "github.com/algorand/indexer/v3/idb/postgres/internal/testing" pgutil "github.com/algorand/indexer/v3/idb/postgres/internal/util" + + sdk "github.com/algorand/go-algorand-sdk/v2/types" ) func makeAddress(i int) sdk.Address { diff --git a/idb/postgres/postgres_boxes_test.go b/idb/postgres/postgres_boxes_test.go index 3f77d18d9..dfa51ec59 100644 --- a/idb/postgres/postgres_boxes_test.go +++ b/idb/postgres/postgres_boxes_test.go @@ -11,7 +11,6 @@ import ( "github.com/stretchr/testify/require" "github.com/algorand/avm-abi/apps" - sdk "github.com/algorand/go-algorand-sdk/v2/types" "github.com/algorand/indexer/v3/idb" "github.com/algorand/indexer/v3/idb/postgres/internal/encoding" "github.com/algorand/indexer/v3/idb/postgres/internal/writer" @@ -19,6 +18,7 @@ import ( "github.com/algorand/go-algorand-sdk/v2/protocol" "github.com/algorand/go-algorand-sdk/v2/protocol/config" + sdk "github.com/algorand/go-algorand-sdk/v2/types" ) type boxTestComparator func(t *testing.T, db *IndexerDb, appBoxes map[sdk.AppIndex]map[string]string, diff --git a/idb/postgres/postgres_integration_common_test.go b/idb/postgres/postgres_integration_common_test.go index 9392cd9ef..4c17c446e 100644 --- a/idb/postgres/postgres_integration_common_test.go +++ b/idb/postgres/postgres_integration_common_test.go @@ -4,14 +4,15 @@ import ( "context" "testing" - sdk "github.com/algorand/go-algorand-sdk/v2/types" - "github.com/algorand/indexer/v3/types" "github.com/jackc/pgx/v4/pgxpool" "github.com/stretchr/testify/require" "github.com/algorand/indexer/v3/idb" pgtest "github.com/algorand/indexer/v3/idb/postgres/internal/testing" + "github.com/algorand/indexer/v3/types" "github.com/algorand/indexer/v3/util/test" + + sdk "github.com/algorand/go-algorand-sdk/v2/types" ) func setupIdbWithConnectionString(t *testing.T, connStr string, genesis sdk.Genesis) *IndexerDb { @@ -37,7 +38,7 @@ func setupIdb(t *testing.T, genesis sdk.Genesis) (*IndexerDb, func()) { Block: test.MakeGenesisBlock(), Delta: sdk.LedgerStateDelta{}, } - db.AddBlock(&vb) + require.NoError(t, db.AddBlock(&vb)) return db, newShutdownFunc } diff --git a/idb/postgres/postgres_integration_test.go b/idb/postgres/postgres_integration_test.go index ac3414407..b2c991d86 100644 --- a/idb/postgres/postgres_integration_test.go +++ b/idb/postgres/postgres_integration_test.go @@ -11,27 +11,27 @@ import ( "testing" "time" - "github.com/algorand/indexer/v3/types" "github.com/jackc/pgx/v4" "github.com/jackc/pgx/v4/pgxpool" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - crypto2 "github.com/algorand/go-algorand-sdk/v2/crypto" - "github.com/algorand/go-algorand-sdk/v2/encoding/msgpack" - sdk "github.com/algorand/go-algorand-sdk/v2/types" + "github.com/algorand/go-codec/codec" "github.com/algorand/indexer/v3/api/generated/v2" "github.com/algorand/indexer/v3/idb" "github.com/algorand/indexer/v3/idb/postgres/internal/encoding" "github.com/algorand/indexer/v3/idb/postgres/internal/schema" pgtest "github.com/algorand/indexer/v3/idb/postgres/internal/testing" pgutil "github.com/algorand/indexer/v3/idb/postgres/internal/util" + "github.com/algorand/indexer/v3/types" "github.com/algorand/indexer/v3/util" "github.com/algorand/indexer/v3/util/test" + crypto2 "github.com/algorand/go-algorand-sdk/v2/crypto" "github.com/algorand/go-algorand-sdk/v2/encoding/json" + "github.com/algorand/go-algorand-sdk/v2/encoding/msgpack" "github.com/algorand/go-algorand-sdk/v2/protocol" - "github.com/algorand/go-codec/codec" + sdk "github.com/algorand/go-algorand-sdk/v2/types" ) // TestMaxRoundOnUninitializedDB makes sure we return 0 when getting the max round on a new DB. @@ -1334,7 +1334,7 @@ func TestAddBlockIncrementsMaxRoundAccounted(t *testing.T) { Block: block, Delta: sdk.LedgerStateDelta{}, } - db.AddBlock(&vb) + require.NoError(t, db.AddBlock(&vb)) round, err = db.GetNextRoundToAccount() require.NoError(t, err) @@ -1347,7 +1347,7 @@ func TestAddBlockIncrementsMaxRoundAccounted(t *testing.T) { Block: block, Delta: sdk.LedgerStateDelta{}, } - db.AddBlock(&vb) + require.NoError(t, db.AddBlock(&vb)) require.NoError(t, err) round, err = db.GetNextRoundToAccount() @@ -1361,7 +1361,7 @@ func TestAddBlockIncrementsMaxRoundAccounted(t *testing.T) { Block: block, Delta: sdk.LedgerStateDelta{}, } - db.AddBlock(&vb) + require.NoError(t, db.AddBlock(&vb)) round, err = db.GetNextRoundToAccount() require.NoError(t, err) @@ -1626,7 +1626,7 @@ func TestSearchForInnerTransactionReturnsRootTransaction(t *testing.T) { Block: test.MakeGenesisBlock(), Delta: sdk.LedgerStateDelta{}, } - db.AddBlock(&genblk) + require.NoError(t, db.AddBlock(&genblk)) return db.AddBlock(&vb) }, nil) require.NoError(t, err) @@ -2186,11 +2186,6 @@ func TestDeleteTransactions(t *testing.T) { txns := []sdk.SignedTxn{} - genBlock := types.ValidatedBlock{ - Block: test.MakeGenesisBlock(), - Delta: sdk.LedgerStateDelta{}, - } - db.AddBlock(&genBlock) // add 4 rounds of txns // txnA := test.MakeCreateAppTxn(test.AccountA) // txnB := test.MakeCreateAppTxn(test.AccountB) diff --git a/idb/postgres/postgres_migrations_test.go b/idb/postgres/postgres_migrations_test.go index 6837ceacb..afb4c22c9 100644 --- a/idb/postgres/postgres_migrations_test.go +++ b/idb/postgres/postgres_migrations_test.go @@ -7,9 +7,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - sdk "github.com/algorand/go-algorand-sdk/v2/types" pgtest "github.com/algorand/indexer/v3/idb/postgres/internal/testing" "github.com/algorand/indexer/v3/idb/postgres/internal/types" + + sdk "github.com/algorand/go-algorand-sdk/v2/types" ) func TestConvertAccountDataIncrementsMigrationNumber(t *testing.T) { diff --git a/idb/postgres/postgres_rand_test.go b/idb/postgres/postgres_rand_test.go index bcf433ac7..c6bcdae9a 100644 --- a/idb/postgres/postgres_rand_test.go +++ b/idb/postgres/postgres_rand_test.go @@ -11,12 +11,12 @@ import ( "github.com/jackc/pgx/v4" "github.com/stretchr/testify/require" - sdk "github.com/algorand/go-algorand-sdk/v2/types" - models "github.com/algorand/indexer/v3/api/generated/v2" "github.com/algorand/indexer/v3/idb" "github.com/algorand/indexer/v3/idb/postgres/internal/writer" "github.com/algorand/indexer/v3/util/test" + + sdk "github.com/algorand/go-algorand-sdk/v2/types" ) func generateAddress(t *testing.T) sdk.Address { diff --git a/idb/postgres/postgres_test.go b/idb/postgres/postgres_test.go index c797b1b55..d034a02d3 100644 --- a/idb/postgres/postgres_test.go +++ b/idb/postgres/postgres_test.go @@ -8,10 +8,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - sdk "github.com/algorand/go-algorand-sdk/v2/types" - "github.com/algorand/indexer/v3/idb" "github.com/algorand/indexer/v3/types" + + sdk "github.com/algorand/go-algorand-sdk/v2/types" ) func Test_txnFilterOptimization(t *testing.T) { @@ -76,11 +76,11 @@ func Test_UnknownProtocol(t *testing.T) { } func Test_buildTransactionQueryTime(t *testing.T) { - us_east_tz, err := time.LoadLocation("America/New_York") + usEastTZ, err := time.LoadLocation("America/New_York") require.NoError(t, err) - us_west_tz, err := time.LoadLocation("America/Los_Angeles") + usWestTZ, err := time.LoadLocation("America/Los_Angeles") require.NoError(t, err) - random_date_utc := time.Date(1000, time.December, 25, 1, 2, 3, 4, time.UTC) + randomDateUTC := time.Date(1000, time.December, 25, 1, 2, 3, 4, time.UTC) tests := []struct { name string arg idb.TransactionFilter @@ -89,26 +89,26 @@ func Test_buildTransactionQueryTime(t *testing.T) { { "BeforeTime UTC to UTC", idb.TransactionFilter{ - BeforeTime: random_date_utc, + BeforeTime: randomDateUTC, }, - []interface{}{random_date_utc}, + []interface{}{randomDateUTC}, }, { "AfterTime UTC to UTC", idb.TransactionFilter{ - AfterTime: random_date_utc, + AfterTime: randomDateUTC, }, - []interface{}{random_date_utc}, + []interface{}{randomDateUTC}, }, { "BeforeTime AfterTime Conversion", idb.TransactionFilter{ - BeforeTime: time.Date(1000, time.December, 25, 1, 2, 3, 4, us_east_tz), - AfterTime: time.Date(1000, time.December, 25, 1, 2, 3, 4, us_west_tz), + BeforeTime: time.Date(1000, time.December, 25, 1, 2, 3, 4, usEastTZ), + AfterTime: time.Date(1000, time.December, 25, 1, 2, 3, 4, usWestTZ), }, []interface{}{ - time.Date(1000, time.December, 25, 1, 2, 3, 4, us_east_tz).UTC(), - time.Date(1000, time.December, 25, 1, 2, 3, 4, us_west_tz).UTC(), + time.Date(1000, time.December, 25, 1, 2, 3, 4, usEastTZ).UTC(), + time.Date(1000, time.December, 25, 1, 2, 3, 4, usWestTZ).UTC(), }, }, } diff --git a/types/min_balance_test.go b/types/min_balance_test.go index 485deae5f..8f97d028e 100644 --- a/types/min_balance_test.go +++ b/types/min_balance_test.go @@ -1,10 +1,12 @@ package types import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/algorand/go-algorand-sdk/v2/protocol/config" sdk "github.com/algorand/go-algorand-sdk/v2/types" - "github.com/stretchr/testify/assert" - "testing" ) func TestMinBalance(t *testing.T) { diff --git a/util/util_test.go b/util/util_test.go index d20997d19..5a4bbd271 100644 --- a/util/util_test.go +++ b/util/util_test.go @@ -101,7 +101,7 @@ func TestDecodeSignedTxnErrors(t *testing.T) { // v16.RequireGenesisHash = true b.BlockHeader.CurrentProtocol = "https://github.com/algorand/spec/tree/22726c9dcd12d9cddce4a8bd7e8ccaa707f74101" txib.HasGenesisHash = true - _, ad, err := DecodeSignedTxn(b.BlockHeader, txib) + _, _, err = DecodeSignedTxn(b.BlockHeader, txib) require.Contains(t, err.Error(), "HasGenesisHash set to true but RequireGenesisHash obviates the flag") // gh not empty @@ -112,7 +112,7 @@ func TestDecodeSignedTxnErrors(t *testing.T) { // if !proto.SupportSignedTxnInBlock, applyData is empty b.BlockHeader.CurrentProtocol = "v10" - _, ad, err = DecodeSignedTxn(b.BlockHeader, txib) + _, ad, err := DecodeSignedTxn(b.BlockHeader, txib) require.Equal(t, sdk.ApplyData{}, ad) // genesisID not empty From 25c7ab7619bd5c8eb3fbe8efcafc84929726afa5 Mon Sep 17 00:00:00 2001 From: nullun Date: Thu, 19 Sep 2024 18:19:26 +0100 Subject: [PATCH 04/13] api: Add support for Private Network Access header preflight requests (#1620) Add Private Network Access headers on preflight requests * Add config option * Add PNA tests * Add further PNA test for coverage --- api/handlers_e2e_test.go | 36 ++++++++++++++++++ api/middlewares/pna.go | 20 ++++++++++ api/middlewares/pna_test.go | 69 ++++++++++++++++++++++++++++++++++ api/server.go | 8 +++- cmd/algorand-indexer/daemon.go | 57 +++++++++++++++------------- 5 files changed, 162 insertions(+), 28 deletions(-) create mode 100644 api/middlewares/pna.go create mode 100644 api/middlewares/pna_test.go diff --git a/api/handlers_e2e_test.go b/api/handlers_e2e_test.go index a581bcc47..e02fcf1dc 100644 --- a/api/handlers_e2e_test.go +++ b/api/handlers_e2e_test.go @@ -2614,3 +2614,39 @@ func TestAccounts(t *testing.T) { assert.Equal(t, uint64(1000000000000), (*acctA.Account.CreatedAssets)[0].Params.Total) assert.Equal(t, "bogo", *(*acctA.Account.CreatedAssets)[0].Params.UnitName) } + +func TestPNAHeader(t *testing.T) { + db, shutdownFunc := setupIdb(t, test.MakeGenesis()) + defer shutdownFunc() + + ////////// + // When // We preflight an endpoint with the PNA "Request" header set + ////////// + + serverCtx, serverCancel := context.WithCancel(context.Background()) + defer serverCancel() + opts := defaultOpts + opts.EnablePrivateNetworkAccessHeader = true + listenAddr := "localhost:8894" + go Serve(serverCtx, listenAddr, db, nil, logrus.New(), opts) + + waitForServer(t, listenAddr) + + path := "/health" + client := &http.Client{} + req, err := http.NewRequest("OPTIONS", "http://"+listenAddr+path, nil) + require.NoError(t, err) + req.Header.Add("Access-Control-Request-Private-Network", "true") + + t.Log("making HTTP request path", req.URL) + + resp, err := client.Do(req) + require.NoError(t, err) + + ////////// + // Then // We expect the PNA "Allow" header to be set + ////////// + + require.Equal(t, resp.Header.Get("Access-Control-Allow-Private-Network"), "true") + defer resp.Body.Close() +} diff --git a/api/middlewares/pna.go b/api/middlewares/pna.go new file mode 100644 index 000000000..13f565de8 --- /dev/null +++ b/api/middlewares/pna.go @@ -0,0 +1,20 @@ +package middlewares + +import ( + "net/http" + + "github.com/labstack/echo/v4" +) + +// MakePNA constructs the Private Network Access middleware function +func MakePNA() echo.MiddlewareFunc { + return func(next echo.HandlerFunc) echo.HandlerFunc { + return func(ctx echo.Context) error { + req := ctx.Request() + if req.Method == http.MethodOptions && req.Header.Get("Access-Control-Request-Private-Network") == "true" { + ctx.Response().Header().Set("Access-Control-Allow-Private-Network", "true") + } + return next(ctx) + } + } +} diff --git a/api/middlewares/pna_test.go b/api/middlewares/pna_test.go new file mode 100644 index 000000000..364508bfc --- /dev/null +++ b/api/middlewares/pna_test.go @@ -0,0 +1,69 @@ +package middlewares + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/labstack/echo/v4" + "github.com/stretchr/testify/assert" +) + +func TestMakePNA(t *testing.T) { + // Create a new Echo instance + e := echo.New() + + // Create a handler to be wrapped by the middleware + handler := func(c echo.Context) error { + return c.String(http.StatusOK, "OK") + } + + // Create the middleware + middleware := MakePNA() + + // Test case 1: OPTIONS request with Access-Control-Request-Private-Network header + t.Run("OPTIONS request with PNA header", func(t *testing.T) { + // Create a new HTTP request and response recorder + req := httptest.NewRequest(http.MethodOptions, "/", nil) + rec := httptest.NewRecorder() + + // Set the expected PNA header + req.Header.Set("Access-Control-Request-Private-Network", "true") + + // Create Echo context + c := e.NewContext(req, rec) + + // Call our MakePNA middleware + err := middleware(handler)(c) + + // Assert there's no error and check the PNA header was set correctly + assert.NoError(t, err) + assert.Equal(t, "true", rec.Header().Get("Access-Control-Allow-Private-Network")) + }) + + // Test case 2: Non-OPTIONS request + t.Run("Non-OPTIONS request", func(t *testing.T) { + req := httptest.NewRequest(http.MethodGet, "/", nil) + rec := httptest.NewRecorder() + c := e.NewContext(req, rec) + + err := middleware(handler)(c) + + // Assert there's no error and check the PNA header wasn't set + assert.NoError(t, err) + assert.Empty(t, rec.Header().Get("Access-Control-Allow-Private-Network")) + }) + + // Test case 3: OPTIONS request without Access-Control-Request-Private-Network header + t.Run("OPTIONS request without Private Network header", func(t *testing.T) { + req := httptest.NewRequest(http.MethodOptions, "/", nil) + rec := httptest.NewRecorder() + c := e.NewContext(req, rec) + + err := middleware(handler)(c) + + // Assert there's no error and check the PNA header wasn't set + assert.NoError(t, err) + assert.Empty(t, rec.Header().Get("Access-Control-Allow-Private-Network")) + }) +} diff --git a/api/server.go b/api/server.go index 0f4d402d5..c8f21531e 100644 --- a/api/server.go +++ b/api/server.go @@ -18,11 +18,14 @@ import ( "github.com/algorand/indexer/v3/idb" ) -// ExtraOptions are options which change the behavior or the HTTP server. +// ExtraOptions are options which change the behavior of the HTTP server. type ExtraOptions struct { // Tokens are the access tokens which can access the API. Tokens []string + // Respond to Private Network Access preflight requests sent to the indexer. + EnablePrivateNetworkAccessHeader bool + // MetricsEndpoint turns on the /metrics endpoint for prometheus metrics. MetricsEndpoint bool @@ -101,6 +104,9 @@ func Serve(ctx context.Context, serveAddr string, db idb.IndexerDb, dataError fu } e.Use(middlewares.MakeLogger(log)) + if options.EnablePrivateNetworkAccessHeader { + e.Use(middlewares.MakePNA()) + } e.Use(middleware.CORS()) e.Use(middleware.GzipWithConfig(middleware.GzipConfig{ // we currently support compressed result only for GET /v2/blocks/ API diff --git a/cmd/algorand-indexer/daemon.go b/cmd/algorand-indexer/daemon.go index ce73ea764..421bfd4fb 100644 --- a/cmd/algorand-indexer/daemon.go +++ b/cmd/algorand-indexer/daemon.go @@ -23,33 +23,34 @@ import ( ) type daemonConfig struct { - flags *pflag.FlagSet - daemonServerAddr string - developerMode bool - metricsMode string - tokenString string - writeTimeout time.Duration - readTimeout time.Duration - maxConn uint32 - maxAPIResourcesPerAccount uint32 - maxTransactionsLimit uint32 - defaultTransactionsLimit uint32 - maxAccountsLimit uint32 - defaultAccountsLimit uint32 - maxAssetsLimit uint32 - defaultAssetsLimit uint32 - maxBoxesLimit uint32 - defaultBoxesLimit uint32 - maxBalancesLimit uint32 - defaultBalancesLimit uint32 - maxApplicationsLimit uint32 - defaultApplicationsLimit uint32 - enableAllParameters bool - indexerDataDir string - cpuProfile string - pidFilePath string - configFile string - suppliedAPIConfigFile string + flags *pflag.FlagSet + daemonServerAddr string + developerMode bool + enablePrivateNetworkAccessHeader bool + metricsMode string + tokenString string + writeTimeout time.Duration + readTimeout time.Duration + maxConn uint32 + maxAPIResourcesPerAccount uint32 + maxTransactionsLimit uint32 + defaultTransactionsLimit uint32 + maxAccountsLimit uint32 + defaultAccountsLimit uint32 + maxAssetsLimit uint32 + defaultAssetsLimit uint32 + maxBoxesLimit uint32 + defaultBoxesLimit uint32 + maxBalancesLimit uint32 + defaultBalancesLimit uint32 + maxApplicationsLimit uint32 + defaultApplicationsLimit uint32 + enableAllParameters bool + indexerDataDir string + cpuProfile string + pidFilePath string + configFile string + suppliedAPIConfigFile string } // DaemonCmd creates the main cobra command, initializes flags, and viper aliases @@ -71,6 +72,7 @@ func DaemonCmd() *cobra.Command { cfg.flags.StringVarP(&cfg.daemonServerAddr, "server", "S", ":8980", "host:port to serve API on (default :8980)") cfg.flags.StringVarP(&cfg.tokenString, "token", "t", "", "an optional auth token, when set REST calls must use this token in a bearer format, or in a 'X-Indexer-API-Token' header") cfg.flags.BoolVarP(&cfg.developerMode, "dev-mode", "", false, "has no effect currently, reserved for future performance intensive operations") + cfg.flags.BoolVarP(&cfg.enablePrivateNetworkAccessHeader, "enable-private-network-access-header", "", false, "respond to Private Network Access preflight requests") cfg.flags.StringVarP(&cfg.metricsMode, "metrics-mode", "", "OFF", "configure the /metrics endpoint to [ON, OFF, VERBOSE]") cfg.flags.DurationVarP(&cfg.writeTimeout, "write-timeout", "", 30*time.Second, "set the maximum duration to wait before timing out writes to a http response, breaking connection") cfg.flags.DurationVarP(&cfg.readTimeout, "read-timeout", "", 5*time.Second, "set the maximum duration for reading the entire request") @@ -300,6 +302,7 @@ func runDaemon(daemonConfig *daemonConfig) error { // makeOptions converts CLI options to server options func makeOptions(daemonConfig *daemonConfig) (options api.ExtraOptions) { + options.EnablePrivateNetworkAccessHeader = daemonConfig.enablePrivateNetworkAccessHeader if daemonConfig.tokenString != "" { options.Tokens = append(options.Tokens, daemonConfig.tokenString) } From e0fc3407aa3f09988c509af82671210bd1595923 Mon Sep 17 00:00:00 2001 From: Gary Malouf <982483+gmalouf@users.noreply.github.com> Date: Tue, 29 Oct 2024 12:02:32 -0400 Subject: [PATCH 05/13] Address import collision due to https://github.com/googleapis/go-genproto/issues/1015 (#1634) --- go.mod | 36 +++++++++++++------------- go.sum | 80 +++++++++++++++++++++++++++++----------------------------- 2 files changed, 59 insertions(+), 57 deletions(-) diff --git a/go.mod b/go.mod index af91e6d66..f8fea6038 100644 --- a/go.mod +++ b/go.mod @@ -17,7 +17,7 @@ require ( github.com/jarcoal/httpmock v1.2.0 github.com/labstack/echo-contrib v0.11.0 github.com/labstack/echo/v4 v4.9.1 - github.com/orlangure/gnomock v0.28.0 + github.com/orlangure/gnomock v0.31.0 github.com/pmezard/go-difflib v1.0.0 github.com/prometheus/client_golang v1.11.1 github.com/sirupsen/logrus v1.9.3 @@ -34,11 +34,10 @@ require ( github.com/Microsoft/go-winio v0.5.2 // indirect github.com/apapsch/go-jsonmerge/v2 v2.0.0 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/containerd/log v0.1.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.1 // indirect - github.com/distribution/reference v0.5.0 // indirect - github.com/docker/docker v25.0.6+incompatible // indirect + github.com/distribution/reference v0.6.0 // indirect + github.com/docker/docker v27.3.1+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.4.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -49,7 +48,7 @@ require ( github.com/go-openapi/swag v0.22.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect @@ -64,13 +63,14 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/kr/pretty v0.3.0 // indirect github.com/labstack/gommon v0.4.0 // indirect - github.com/lib/pq v1.10.8 // indirect + github.com/lib/pq v1.10.9 // indirect github.com/magiconair/properties v1.8.5 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.14 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/moby/docker-image-spec v1.3.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.0.2 // indirect @@ -94,16 +94,18 @@ require ( go.opentelemetry.io/otel/metric v1.28.0 // indirect go.opentelemetry.io/otel/sdk v1.28.0 // indirect go.opentelemetry.io/otel/trace v1.28.0 // indirect - go.uber.org/atomic v1.9.0 // indirect - go.uber.org/multierr v1.7.0 // indirect - go.uber.org/zap v1.24.0 // indirect - golang.org/x/crypto v0.24.0 // indirect - golang.org/x/net v0.26.0 // indirect - golang.org/x/sync v0.7.0 // indirect - golang.org/x/sys v0.21.0 // indirect - golang.org/x/text v0.16.0 // indirect - golang.org/x/time v0.0.0-20220411224347-583f2d630306 // indirect - google.golang.org/protobuf v1.34.2 // indirect + go.uber.org/multierr v1.10.0 // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/crypto v0.27.0 // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.25.0 // indirect + golang.org/x/text v0.18.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect + google.golang.org/grpc v1.67.1 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/ini.v1 v1.66.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index a199eea41..44a74d8e3 100644 --- a/go.sum +++ b/go.sum @@ -92,8 +92,6 @@ github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6l github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -110,8 +108,9 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chrismcguire/gobberish v0.0.0-20150821175641-1d8adb509a0e h1:CHPYEbz71w8DqJ7DRIq+MXyCQsdibK08vdcQTY4ufas= github.com/chrismcguire/gobberish v0.0.0-20150821175641-1d8adb509a0e/go.mod h1:6Xhs0ZlsRjXLIiSMLKafbZxML/j30pg9Z1priLuha5s= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -153,10 +152,10 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK2OFGvA0= -github.com/distribution/reference v0.5.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v25.0.6+incompatible h1:5cPwbwriIcsua2REJe8HqQV+6WlWc1byg2QSXzBxBGg= -github.com/docker/docker v25.0.6+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= +github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= @@ -259,8 +258,8 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -473,8 +472,8 @@ github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.8 h1:3fdt97i/cwSU83+E0hZTC/Xpc9mTZxc6UWSCRcSbxiE= -github.com/lib/pq v1.10.8/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= @@ -526,6 +525,8 @@ github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 h1:dcztxKSvZ4Id8iPpHERQBbIJfabdt4wUm5qy3wOL2Zc= github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -568,8 +569,8 @@ github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJ 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.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= -github.com/orlangure/gnomock v0.28.0 h1:3xlGullCJxjWjWGjEXUzvGH1tP6nXL0HY/lHt9w8oC8= -github.com/orlangure/gnomock v0.28.0/go.mod h1:mPcZ4UaVkWrN5pdOkkNWtaWwiTA/4KMME9pH/IHg5Gc= +github.com/orlangure/gnomock v0.31.0 h1:dgjlQ8DYUPMyNwMZJuYBH+/GF+e7h3sloldPzIJF4k4= +github.com/orlangure/gnomock v0.31.0/go.mod h1:RagxeYv3bKi+li9Lio2Faw5t6Mcy4akkeqXzkgAS3w0= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= @@ -750,23 +751,21 @@ 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= 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.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/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/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= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0 h1:zaiO/rmgFjbmCXdSYJWQcdvOCsthmdaHfr3Gm2Kx4Ec= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/multierr v1.10.0 h1:S0h4aNzvfcFsC3dRF1jLoaov7oRaKqRGC/pUEJ2yvPQ= +go.uber.org/multierr v1.10.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= -go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= -go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -784,8 +783,8 @@ golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= 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= @@ -874,8 +873,8 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -904,8 +903,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= 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= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -987,8 +986,8 @@ golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1000,15 +999,15 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= 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= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220411224347-583f2d630306 h1:+gHMid33q6pen7kv9xvT+JRinntgeXO2AeZVd0AWD3w= -golang.org/x/time v0.0.0-20220411224347-583f2d630306/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1188,10 +1187,11 @@ google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa h1:I0YcKz0I7OAhddo7ya8kMnvprhcWM045PmkBdMO9zN0= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto/googleapis/api v0.0.0-20240701130421-f6361c86f094 h1:0+ozOGcrp+Y8Aq8TLNN2Aliibms5LEzsq99ZZmAGYm0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240701130421-f6361c86f094 h1:BwIjyKYGsK9dMCBOorzRri8MQwmi7mT9rGHsCEinZkA= +google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1:fVoAXEKA4+yufmbdVYv+SE73+cPZbbbe8paLsHfkK+U= +google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1224,8 +1224,8 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -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/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= 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= @@ -1240,8 +1240,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= -google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/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= From bff11e95ca04e698da479c592ffa49cce4d3dfdc Mon Sep 17 00:00:00 2001 From: Gary Malouf <982483+gmalouf@users.noreply.github.com> Date: Thu, 14 Nov 2024 19:12:48 -0500 Subject: [PATCH 06/13] Go 1.23 support, go-algorand-sdk dependency on develop commit (#1636) * Go 1.23 support, go-algorand-sdk dependency on develop commit. * Adjust to loop variable changes Go 1.22 --- .circleci/config.yml | 8 +- .github/workflows/goreleaser.yml | 4 +- .github/workflows/pr-type-category.yml | 2 +- .github/workflows/reviewdog.yml | 20 +- Makefile | 2 +- api/handlers.go | 4 +- api/handlers_e2e_test.go | 2 +- api/handlers_test.go | 11 +- config/datadir_test.go | 10 +- .../indexer-filtered/e2e-read/Dockerfile | 2 +- .../indexer-filtered/e2e-write/Dockerfile | 2 +- e2e_tests/docker/indexer/Dockerfile | 2 +- go.mod | 40 ++- go.sum | 298 +++--------------- idb/mocks/IndexerDb.go | 75 ++++- monitoring/Dockerfile-indexer | 2 +- types/min_balance.go | 20 +- util/test/account_testutil.go | 8 +- 18 files changed, 178 insertions(+), 334 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ea2584127..4b32f3206 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ version: 2.1 orbs: - go: circleci/go@1.7.3 + go: circleci/go@1.12.0 slack: circleci/slack@4.7.1 codecov: codecov/codecov@3.2.4 @@ -18,7 +18,7 @@ workflows: name: test_with_go_<< matrix.go_version >> matrix: &go-version-matrix parameters: - go_version: ["1.21.10"] + go_version: ["1.23.3"] circleci_build_and_test_nightly: triggers: @@ -33,7 +33,7 @@ workflows: context: lamprey-secrets matrix: &go-version-matrix parameters: - go_version: ["1.21.10"] + go_version: ["1.23.3"] - indexer_vs_algod_nightly: name: nightly_test_indexer_vs_algod context: lamprey-secrets @@ -135,7 +135,7 @@ commands: steps: - run: name: Install golangci-lint - command: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.53.2 + command: go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0 run_e2e_tests: steps: diff --git a/.github/workflows/goreleaser.yml b/.github/workflows/goreleaser.yml index 1677c7cb1..05801edab 100644 --- a/.github/workflows/goreleaser.yml +++ b/.github/workflows/goreleaser.yml @@ -12,13 +12,13 @@ jobs: goreleaser: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.5.3 + - uses: actions/checkout@v4 with: fetch-depth: 0 - run: git fetch --force --tags - name: go dependency - uses: actions/setup-go@v4.0.1 + uses: actions/setup-go@v5 with: go-version-file: 'go.mod' diff --git a/.github/workflows/pr-type-category.yml b/.github/workflows/pr-type-category.yml index c33fce940..ed2983321 100644 --- a/.github/workflows/pr-type-category.yml +++ b/.github/workflows/pr-type-category.yml @@ -10,7 +10,7 @@ jobs: name: Check PR Category and Type steps: - name: Checking for correct number of required github pr labels - uses: mheap/github-action-required-labels@v2 + uses: mheap/github-action-required-labels@v5 with: mode: exactly count: 1 diff --git a/.github/workflows/reviewdog.yml b/.github/workflows/reviewdog.yml index 914c95eff..5e244805e 100644 --- a/.github/workflows/reviewdog.yml +++ b/.github/workflows/reviewdog.yml @@ -7,18 +7,18 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out code into the Go module directory - uses: actions/checkout@v3.5.3 + uses: actions/checkout@v4 with: fetch-depth: 0 # required for new-from-rev option in .golangci.yml - name: Install specific golang - uses: actions/setup-go@v4.0.1 + uses: actions/setup-go@v5 with: - go-version: '1.21.10' + go-version: '1.23.3' - name: reviewdog-golangci-lint - uses: reviewdog/action-golangci-lint@v2.6.1 + uses: reviewdog/action-golangci-lint@v2.6.2 with: go_version_file: go.mod - golangci_lint_version: "v1.58.0" + golangci_lint_version: "v1.62.0" golangci_lint_flags: "-c .golangci.yml --allow-parallel-runners" reporter: "github-pr-check" tool_name: "Lint Errors" @@ -30,18 +30,18 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out code into the Go module directory - uses: actions/checkout@v3.5.3 + uses: actions/checkout@v4 with: fetch-depth: 0 # required for new-from-rev option in .golangci.yml - name: Install specific golang - uses: actions/setup-go@v4.0.1 + uses: actions/setup-go@v5 with: - go-version: '1.21.10' + go-version: '1.23.3' - name: reviewdog-golangci-lint - uses: reviewdog/action-golangci-lint@v2.6.1 + uses: reviewdog/action-golangci-lint@v2.6.2 with: go_version_file: go.mod - golangci_lint_version: "v1.58.0" + golangci_lint_version: "v1.62.0" golangci_lint_flags: "-c .golangci-warnings.yml --allow-parallel-runners" reporter: "github-pr-check" tool_name: "Lint Warnings" diff --git a/Makefile b/Makefile index 6a46da177..b937929bd 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ idb/postgres/internal/schema/setup_postgres_sql.go: idb/postgres/internal/schema cd idb/postgres/internal/schema && go generate idb/mocks/IndexerDb.go: idb/idb.go - go install github.com/vektra/mockery/v2@v2.20.0 + go install github.com/vektra/mockery/v2@v2.47.0 cd idb && mockery --name=IndexerDb # check that all packages (except tests) compile diff --git a/api/handlers.go b/api/handlers.go index 78f15ef7c..76d40f9c0 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -600,7 +600,7 @@ func (si *ServerImplementation) LookupApplicationBoxByIDAndName(ctx echo.Context if len(boxes) == 0 { // this is an unexpected situation as should have received a sql.ErrNoRows from fetchApplicationBoxes's err msg := fmt.Sprintf("%s: round=?=%d, appid=%d, boxName=%s", ErrFailedLookingUpBoxes, round, applicationID, encodedBoxName) - return indexerError(ctx, fmt.Errorf(msg)) + return indexerError(ctx, errors.New(msg)) } if appid != generated.ApplicationId(applicationID) { @@ -668,7 +668,7 @@ func (si *ServerImplementation) SearchForApplicationBoxes(ctx echo.Context, appl if len(boxes) == 0 { // this is an unexpected situation as should have received a sql.ErrNoRows from fetchApplicationBoxes's err msg := fmt.Sprintf("%s: round=?=%d, appid=%d", errFailedSearchingBoxes, round, applicationID) - return indexerError(ctx, fmt.Errorf(msg)) + return indexerError(ctx, errors.New(msg)) } if appid != generated.ApplicationId(applicationID) { diff --git a/api/handlers_e2e_test.go b/api/handlers_e2e_test.go index e02fcf1dc..95a09ee58 100644 --- a/api/handlers_e2e_test.go +++ b/api/handlers_e2e_test.go @@ -1531,7 +1531,7 @@ func TestFetchBlockWithOptions(t *testing.T) { } for _, tc := range testCases { - t.Run(fmt.Sprintf(tc.name), func(t *testing.T) { + t.Run(tc.name, func(t *testing.T) { c, api, rec := setupReq("/v2/blocks/:round-number", "round-number", "1") if tc.name == "default" { err = api.LookupBlock(c, 1, generated.LookupBlockParams{}) diff --git a/api/handlers_test.go b/api/handlers_test.go index 6a2938900..a64aa31e0 100644 --- a/api/handlers_test.go +++ b/api/handlers_test.go @@ -992,12 +992,13 @@ func TestApplicationLimits(t *testing.T) { }, } - // Mock backend to capture default limits - mockIndexer := &mocks.IndexerDb{} - si := testServerImplementation(mockIndexer) - si.timeout = 5 * time.Millisecond - for _, tc := range testcases { + + // Mock backend to capture default limits + mockIndexer := &mocks.IndexerDb{} + si := testServerImplementation(mockIndexer) + si.timeout = 5 * time.Millisecond + t.Run(tc.name, func(t *testing.T) { // Setup context... e := echo.New() diff --git a/config/datadir_test.go b/config/datadir_test.go index d252fcc0a..a1d5f40f5 100644 --- a/config/datadir_test.go +++ b/config/datadir_test.go @@ -19,11 +19,11 @@ func TestAlgodArgsForDataDirNetDoesNotExist(t *testing.T) { func TestAlgodArgsForDataDirTokenDoesNotExist(t *testing.T) { dir, err := os.MkdirTemp("", "datadir") if err != nil { - t.Fatalf(err.Error()) + t.Fatal(err.Error()) } err = os.WriteFile(filepath.Join(dir, "algod.net"), []byte("127.0.0.1:8080"), fs.ModePerm) if err != nil { - t.Fatalf(err.Error()) + t.Fatal(err.Error()) } defer os.RemoveAll(dir) _, _, _, err = AlgodArgsForDataDir(dir) @@ -34,15 +34,15 @@ func TestAlgodArgsForDataDirTokenDoesNotExist(t *testing.T) { func TestAlgodArgsForDataDirSuccess(t *testing.T) { dir, err := os.MkdirTemp("", "datadir") if err != nil { - t.Fatalf(err.Error()) + t.Fatal(err.Error()) } err = os.WriteFile(filepath.Join(dir, "algod.net"), []byte("127.0.0.1:8080"), fs.ModePerm) if err != nil { - t.Fatalf(err.Error()) + t.Fatal(err.Error()) } err = os.WriteFile(filepath.Join(dir, "algod.token"), []byte("abc123"), fs.ModePerm) if err != nil { - t.Fatalf(err.Error()) + t.Fatal(err.Error()) } defer os.RemoveAll(dir) netAddr, token, lastmod, err := AlgodArgsForDataDir(dir) diff --git a/e2e_tests/docker/indexer-filtered/e2e-read/Dockerfile b/e2e_tests/docker/indexer-filtered/e2e-read/Dockerfile index 8d319fde7..4828f71fc 100644 --- a/e2e_tests/docker/indexer-filtered/e2e-read/Dockerfile +++ b/e2e_tests/docker/indexer-filtered/e2e-read/Dockerfile @@ -1,4 +1,4 @@ -ARG GO_IMAGE=golang:1.21.10 +ARG GO_IMAGE=golang:1.23.3 FROM $GO_IMAGE RUN echo "Go image: $GO_IMAGE" diff --git a/e2e_tests/docker/indexer-filtered/e2e-write/Dockerfile b/e2e_tests/docker/indexer-filtered/e2e-write/Dockerfile index ecd26f90f..8b820f6c3 100644 --- a/e2e_tests/docker/indexer-filtered/e2e-write/Dockerfile +++ b/e2e_tests/docker/indexer-filtered/e2e-write/Dockerfile @@ -1,4 +1,4 @@ -ARG GO_IMAGE=golang:1.21.10 +ARG GO_IMAGE=golang:1.23.3 FROM $GO_IMAGE ARG CHANNEL=stable ARG CI_E2E_FILENAME diff --git a/e2e_tests/docker/indexer/Dockerfile b/e2e_tests/docker/indexer/Dockerfile index bb10acf8d..754e1e8b4 100644 --- a/e2e_tests/docker/indexer/Dockerfile +++ b/e2e_tests/docker/indexer/Dockerfile @@ -1,4 +1,4 @@ -ARG GO_IMAGE=golang:1.21.10 +ARG GO_IMAGE=golang:1.213.3 FROM $GO_IMAGE ARG CHANNEL=stable diff --git a/go.mod b/go.mod index f8fea6038..6e2af3088 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,12 @@ module github.com/algorand/indexer/v3 -go 1.21 +go 1.23 -toolchain go1.21.10 +toolchain go1.23.3 require ( github.com/algorand/avm-abi v0.2.0 - github.com/algorand/go-algorand-sdk/v2 v2.6.0 + github.com/algorand/go-algorand-sdk/v2 v2.2.1-0.20241114170414-874d2110dae4 github.com/algorand/go-codec/codec v1.1.10 github.com/algorand/oapi-codegen v1.12.0-algorand.0 github.com/davecgh/go-spew v1.1.1 @@ -15,11 +15,11 @@ require ( github.com/jackc/pgerrcode v0.0.0-20201024163028-a0d42d470451 github.com/jackc/pgx/v4 v4.18.2 github.com/jarcoal/httpmock v1.2.0 - github.com/labstack/echo-contrib v0.11.0 - github.com/labstack/echo/v4 v4.9.1 + github.com/labstack/echo-contrib v0.17.1 + github.com/labstack/echo/v4 v4.12.0 github.com/orlangure/gnomock v0.31.0 github.com/pmezard/go-difflib v1.0.0 - github.com/prometheus/client_golang v1.11.1 + github.com/prometheus/client_golang v1.19.0 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.3.0 github.com/spf13/pflag v1.0.5 @@ -48,7 +48,6 @@ require ( github.com/go-openapi/swag v0.22.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang-jwt/jwt v3.2.2+incompatible // indirect - github.com/golang/protobuf v1.5.4 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/inconshreveable/mousetrap v1.0.0 // indirect @@ -61,14 +60,12 @@ require ( github.com/jackc/pgtype v1.14.0 // indirect github.com/jackc/puddle v1.3.0 // indirect github.com/josharian/intern v1.0.0 // indirect - github.com/kr/pretty v0.3.0 // indirect - github.com/labstack/gommon v0.4.0 // indirect + github.com/labstack/gommon v0.4.2 // indirect github.com/lib/pq v1.10.9 // indirect github.com/magiconair/properties v1.8.5 // indirect github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.12 // indirect - github.com/mattn/go-isatty v0.0.14 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect @@ -76,10 +73,9 @@ require ( github.com/opencontainers/image-spec v1.0.2 // indirect github.com/pelletier/go-toml v1.9.4 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/common v0.26.0 // indirect - github.com/prometheus/procfs v0.6.0 // indirect - github.com/rogpeppe/go-internal v1.8.0 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.53.0 // indirect + github.com/prometheus/procfs v0.13.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spf13/afero v1.6.0 // indirect github.com/spf13/cast v1.4.1 // indirect @@ -87,7 +83,7 @@ require ( github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.2.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect - github.com/valyala/fasttemplate v1.2.1 // indirect + github.com/valyala/fasttemplate v1.2.2 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0 // indirect go.opentelemetry.io/otel v1.28.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.28.0 // indirect @@ -96,12 +92,12 @@ require ( go.opentelemetry.io/otel/trace v1.28.0 // indirect go.uber.org/multierr v1.10.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.27.0 // indirect + golang.org/x/crypto v0.29.0 // indirect golang.org/x/net v0.29.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.25.0 // indirect - golang.org/x/text v0.18.0 // indirect - golang.org/x/time v0.3.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/time v0.5.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 // indirect google.golang.org/grpc v1.67.1 // indirect diff --git a/go.sum b/go.sum index 44a74d8e3..107f1976a 100644 --- a/go.sum +++ b/go.sum @@ -51,57 +51,37 @@ github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg6 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/HdrHistogram/hdrhistogram-go v1.1.0/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/Microsoft/go-winio v0.5.2 h1:a9IhgEQBCUEk6QCdml9CiJGhAws+YwffDHEMp1VMrpA= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/RaveNoX/go-jsoncommentstrip v1.0.0/go.mod h1:78ihd09MekBnJnxpICcwzCMzGrKSKYe4AqU6PDYYpjk= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 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/algorand/avm-abi v0.2.0 h1:bkjsG+BOEcxUcnGSALLosmltE0JZdg+ZisXKx0UDX2k= github.com/algorand/avm-abi v0.2.0/go.mod h1:+CgwM46dithy850bpTeHh9MC99zpn2Snirb3QTl2O/g= -github.com/algorand/go-algorand-sdk/v2 v2.6.0 h1:pfL8lloEi26l6PwAFicmPUguWgKpy1eZZTMlQcci5h0= -github.com/algorand/go-algorand-sdk/v2 v2.6.0/go.mod h1:4ayerzjoWChm3kuVhbgFgURTbaYTtlj0c41eP3av5lw= +github.com/algorand/go-algorand-sdk/v2 v2.2.1-0.20241114170414-874d2110dae4 h1:qQXdtMWlP9ynxeDEhWpUWer3AM51482pnfe7ptTDXm0= +github.com/algorand/go-algorand-sdk/v2 v2.2.1-0.20241114170414-874d2110dae4/go.mod h1:BkHnK2PuCqzdGPNeWUo5yo6lRjyDZ9QoMN8GIjfijrA= github.com/algorand/go-codec/codec v1.1.10 h1:zmWYU1cp64jQVTOG8Tw8wa+k0VfwgXIPbnDfiVa+5QA= github.com/algorand/go-codec/codec v1.1.10/go.mod h1:YkEx5nmr/zuCeaDYOIhlDg92Lxju8tj2d2NrYqP7g7k= github.com/algorand/oapi-codegen v1.12.0-algorand.0 h1:W9PvED+wAJc+9EeXPONnA+0zE9UhynEqoDs4OgAxKhk= github.com/algorand/oapi-codegen v1.12.0-algorand.0/go.mod h1:tIWJ9K/qrLDVDt5A1p82UmxZIEGxv2X+uoujdhEAL48= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0 h1:axGnT1gRIfimI7gJifB699GoE/oq+F2MU7Dml6nw9rQ= github.com/apapsch/go-jsonmerge/v2 v2.0.0/go.mod h1:lvDnEdqiQrp0O42VQGgmlKpxL1AP2+08jFMw88y4klk= -github.com/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4= -github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bmatcuk/doublestar v1.1.1/go.mod h1:UD6OnuiIn0yFxxA2le/rnRU1G4RaI4UvFv1sNto9p6w= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/casbin/casbin/v2 v2.31.2/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= -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.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= @@ -118,7 +98,6 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5P github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -132,18 +111,12 @@ github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.1 h1:r/myEWzV9lfsM1tFLgDyu0atFtJ1fXn261LKYj/3DxU= github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= @@ -151,7 +124,6 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= @@ -160,12 +132,6 @@ github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKoh github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -182,10 +148,6 @@ github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/getkin/kin-openapi v0.107.0 h1:bxhL6QArW7BXQj8NjXfIJQy680NsMKd25nwhvpCXchg= @@ -196,7 +158,6 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= 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= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= @@ -212,22 +173,17 @@ github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaL github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gofrs/uuid v4.3.1+incompatible h1:0/KbAdpx3UXAx1kEOWHJeOkpbgRFGHVgv+CFIY7dBJI= +github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= 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 v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -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= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -258,9 +214,6 @@ github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= -github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -298,7 +251,6 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -306,24 +258,12 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+HVt/4epWDjd4= -github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0 h1:bkypFPDjIYGfCYD5mRBvpqxfYX1YCS1PXdKYWi8FsN0= github.com/grpc-ecosystem/grpc-gateway/v2 v2.20.0/go.mod h1:P+Lt/0by1T8bfcF3z737NnSbmxQAppXMRziHUxPOC8k= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= @@ -337,37 +277,28 @@ github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iP github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= 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.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= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk= github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/invopop/yaml v0.1.0 h1:YW3WGUoJEXYfzWBjn00zIlrw7brGVD0fUKRYDPAPhrc= github.com/invopop/yaml v0.1.0/go.mod h1:2XuRLgs/ouIrW3XNzuNj7J3Nvu/Dig5MXvbCEdiBN3Q= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= @@ -423,61 +354,45 @@ github.com/jackc/puddle v1.3.0 h1:eHK/5clGOatcjX3oWGBO/MpxpbHzSwud5EWTSCI+MX0= github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc= github.com/jarcoal/httpmock v1.2.0/go.mod h1:oCoTsnAz4+UoOUIf5lJOWV2QQIW5UoeUI6aM2YnWAZk= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/gnuflag v0.0.0-20171113085948-2ce1bb71843d/go.mod h1:2PavIy+JPciBPrBUjwbNvtwB6RQlve+hkpll6QSNmOE= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 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 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/labstack/echo-contrib v0.11.0 h1:/B7meUKBP7AAoSEOrawpSivhFvu7GQG+kDhlzi5v0Wo= -github.com/labstack/echo-contrib v0.11.0/go.mod h1:Hk8Iyxe2GrYR/ch0cbI3BK7ZhR2Y60YEqtkoZilqDOc= -github.com/labstack/echo/v4 v4.3.0/go.mod h1:PvmtTvhVqKDzDQy4d3bWzPjZLzom4iQbAZy2sgZ/qI8= -github.com/labstack/echo/v4 v4.9.1 h1:GliPYSpzGKlyOhqIbG8nmHBo3i1saKWFOgh41AN3b+Y= -github.com/labstack/echo/v4 v4.9.1/go.mod h1:Pop5HLc+xoc4qhTZ1ip6C0RtP7Z+4VzRLWZZFKqbbjo= -github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= -github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8= -github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM= +github.com/labstack/echo-contrib v0.17.1 h1:7I/he7ylVKsDUieaGRZ9XxxTYOjfQwVzHzUYrNykfCU= +github.com/labstack/echo-contrib v0.17.1/go.mod h1:SnsCZtwHBAZm5uBSAtQtXQHI3wqEA73hvTn0bYMKnZA= +github.com/labstack/echo/v4 v4.12.0 h1:IKpw49IMryVB2p1a4dzwlhP1O2Tf2E0Ir/450lH+kI0= +github.com/labstack/echo/v4 v4.12.0/go.mod h1:UP9Cr2DJXbOK3Kr9ONYzNowSh7HP0aG0ShAyycHSJvM= +github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0= +github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.5 h1:b6kJs+EmPFMYGkow9GiUyCyOvIwYetYJ3fSaWak/Gls= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= @@ -486,40 +401,32 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/maxatome/go-testdeep v1.11.0 h1:Tgh5efyCYyJFGUYiT0qxBSIDeXw0F5zSoatlou685kk= github.com/maxatome/go-testdeep v1.11.0/go.mod h1:011SgQ6efzZYAen6fDn4BqQ+lUR72ysdyKe7Dyogw70= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 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= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= @@ -539,143 +446,82 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwd github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -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= github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM= github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -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.2.5/go.mod h1:KpXfKdgRDnnhsxw4pNIH9Md5lyFqKUa4YDFlwRYAMyE= github.com/orlangure/gnomock v0.31.0 h1:dgjlQ8DYUPMyNwMZJuYBH+/GF+e7h3sloldPzIJF4k4= github.com/orlangure/gnomock v0.31.0/go.mod h1:RagxeYv3bKi+li9Lio2Faw5t6Mcy4akkeqXzkgAS3w0= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.9.4 h1:tjENF6MfZAg8e4ZmZTeWaWiT2vXtsoO6+iuOjFhECwM= github.com/pelletier/go-toml v1.9.4/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= -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= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= 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= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.10.0/go.mod h1:WJM3cc3yu7XKBKa/I8WeZm+V3eltZnBwfENSU7mdogU= -github.com/prometheus/client_golang v1.11.1 h1:+4eQaD7vAZ6DsfsxB15hbE0odUjGI5ARs9yskGu1v4s= -github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= +github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= 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= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.25.0/go.mod h1:H6QK/N6XVT42whUeIdI3dp36w49c+/iMDk7UAI2qm7Q= -github.com/prometheus/common v0.26.0 h1:iMAkS2TDoNWnKM+Kopnx/8tnEStIfpYA0ur0xQzzhMQ= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.53.0 h1:U2pL9w9nmJwJDa4qqLQ3ZaePJ6ZTwt7cMD3AG3+aLCE= +github.com/prometheus/common v0.53.0/go.mod h1:BrxBKv3FWBIGXw89Mg1AeBq7FSyRzXWI3l3e7W3RN5U= 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= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/prometheus/procfs v0.13.0 h1:GqzLlQyfsPbaEHaQkO7tbDlriv/4o5Hudv6OXHGKX7o= +github.com/prometheus/procfs v0.13.0/go.mod h1:cd4PFCR54QLnGKPaKGA6l+cfuNXtht43ZKY6tow0Y1g= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.3.0 h1:R7cSvGu+Vv+qX0gW5R/85dx2kmmJT5z5NM8ifdYjdn0= github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.10.0 h1:mXH0UwHS4D2HwWZa75im4xIQynLfblmWV7qcWpfv0yk= github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM= github.com/spkg/bom v0.0.0-20160624110644-59b7046e48ad/go.mod h1:qLr4V1qq6nMqFKkMo8ZTx3f+BZEkzsRUY10Xsm2mwU0= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= @@ -696,18 +542,11 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/uber/jaeger-client-go v2.25.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= -github.com/uber/jaeger-lib v2.4.0+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= -github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= -github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= -github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo= +github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -715,13 +554,9 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.etcd.io/etcd/api/v3 v3.5.1/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -772,23 +607,18 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= -golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= -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/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-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= @@ -798,7 +628,6 @@ 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/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= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -828,13 +657,9 @@ golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -903,16 +728,13 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.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-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -925,16 +747,13 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -949,8 +768,6 @@ golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -962,7 +779,6 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -970,7 +786,6 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -982,12 +797,13 @@ golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -999,26 +815,19 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= -golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +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-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1079,11 +888,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T 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= -gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= -gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= -gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= -gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1117,7 +921,6 @@ google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUb google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -1129,7 +932,6 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -1192,15 +994,10 @@ google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53 h1: google.golang.org/genproto/googleapis/api v0.0.0-20241015192408-796eee8c2d53/go.mod h1:riSXTwQ4+nqmPGtobMFyW5FqVAmIs0St6VPp4Ug7CE4= google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53 h1:X58yt85/IXCx0Y3ZwN6sEIKZzQtDEYaBWrDvErdXrRE= google.golang.org/genproto/googleapis/rpc v0.0.0-20241015192408-796eee8c2d53/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -1246,27 +1043,18 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI= gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -1276,7 +1064,6 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1285,8 +1072,5 @@ 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= 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= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/idb/mocks/IndexerDb.go b/idb/mocks/IndexerDb.go index e03ad2cc0..15b508e10 100644 --- a/idb/mocks/IndexerDb.go +++ b/idb/mocks/IndexerDb.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.20.0. DO NOT EDIT. +// Code generated by mockery v2.47.0. DO NOT EDIT. package mocks @@ -22,6 +22,10 @@ type IndexerDb struct { func (_m *IndexerDb) AddBlock(block *types.ValidatedBlock) error { ret := _m.Called(block) + if len(ret) == 0 { + panic("no return value specified for AddBlock") + } + var r0 error if rf, ok := ret.Get(0).(func(*types.ValidatedBlock) error); ok { r0 = rf(block) @@ -36,6 +40,10 @@ func (_m *IndexerDb) AddBlock(block *types.ValidatedBlock) error { func (_m *IndexerDb) AppLocalState(ctx context.Context, filter idb.ApplicationQuery) (<-chan idb.AppLocalStateRow, uint64) { ret := _m.Called(ctx, filter) + if len(ret) == 0 { + panic("no return value specified for AppLocalState") + } + var r0 <-chan idb.AppLocalStateRow var r1 uint64 if rf, ok := ret.Get(0).(func(context.Context, idb.ApplicationQuery) (<-chan idb.AppLocalStateRow, uint64)); ok { @@ -62,6 +70,10 @@ func (_m *IndexerDb) AppLocalState(ctx context.Context, filter idb.ApplicationQu func (_m *IndexerDb) ApplicationBoxes(ctx context.Context, filter idb.ApplicationBoxQuery) (<-chan idb.ApplicationBoxRow, uint64) { ret := _m.Called(ctx, filter) + if len(ret) == 0 { + panic("no return value specified for ApplicationBoxes") + } + var r0 <-chan idb.ApplicationBoxRow var r1 uint64 if rf, ok := ret.Get(0).(func(context.Context, idb.ApplicationBoxQuery) (<-chan idb.ApplicationBoxRow, uint64)); ok { @@ -88,6 +100,10 @@ func (_m *IndexerDb) ApplicationBoxes(ctx context.Context, filter idb.Applicatio func (_m *IndexerDb) Applications(ctx context.Context, filter idb.ApplicationQuery) (<-chan idb.ApplicationRow, uint64) { ret := _m.Called(ctx, filter) + if len(ret) == 0 { + panic("no return value specified for Applications") + } + var r0 <-chan idb.ApplicationRow var r1 uint64 if rf, ok := ret.Get(0).(func(context.Context, idb.ApplicationQuery) (<-chan idb.ApplicationRow, uint64)); ok { @@ -114,6 +130,10 @@ func (_m *IndexerDb) Applications(ctx context.Context, filter idb.ApplicationQue func (_m *IndexerDb) AssetBalances(ctx context.Context, abq idb.AssetBalanceQuery) (<-chan idb.AssetBalanceRow, uint64) { ret := _m.Called(ctx, abq) + if len(ret) == 0 { + panic("no return value specified for AssetBalances") + } + var r0 <-chan idb.AssetBalanceRow var r1 uint64 if rf, ok := ret.Get(0).(func(context.Context, idb.AssetBalanceQuery) (<-chan idb.AssetBalanceRow, uint64)); ok { @@ -140,6 +160,10 @@ func (_m *IndexerDb) AssetBalances(ctx context.Context, abq idb.AssetBalanceQuer func (_m *IndexerDb) Assets(ctx context.Context, filter idb.AssetsQuery) (<-chan idb.AssetRow, uint64) { ret := _m.Called(ctx, filter) + if len(ret) == 0 { + panic("no return value specified for Assets") + } + var r0 <-chan idb.AssetRow var r1 uint64 if rf, ok := ret.Get(0).(func(context.Context, idb.AssetsQuery) (<-chan idb.AssetRow, uint64)); ok { @@ -171,6 +195,10 @@ func (_m *IndexerDb) Close() { func (_m *IndexerDb) DeleteTransactions(ctx context.Context, keep uint64) error { ret := _m.Called(ctx, keep) + if len(ret) == 0 { + panic("no return value specified for DeleteTransactions") + } + var r0 error if rf, ok := ret.Get(0).(func(context.Context, uint64) error); ok { r0 = rf(ctx, keep) @@ -185,6 +213,10 @@ func (_m *IndexerDb) DeleteTransactions(ctx context.Context, keep uint64) error func (_m *IndexerDb) GetAccounts(ctx context.Context, opts idb.AccountQueryOptions) (<-chan idb.AccountRow, uint64) { ret := _m.Called(ctx, opts) + if len(ret) == 0 { + panic("no return value specified for GetAccounts") + } + var r0 <-chan idb.AccountRow var r1 uint64 if rf, ok := ret.Get(0).(func(context.Context, idb.AccountQueryOptions) (<-chan idb.AccountRow, uint64)); ok { @@ -211,6 +243,10 @@ func (_m *IndexerDb) GetAccounts(ctx context.Context, opts idb.AccountQueryOptio func (_m *IndexerDb) GetBlock(ctx context.Context, round uint64, options idb.GetBlockOptions) (v2types.BlockHeader, []idb.TxnRow, error) { ret := _m.Called(ctx, round, options) + if len(ret) == 0 { + panic("no return value specified for GetBlock") + } + var r0 v2types.BlockHeader var r1 []idb.TxnRow var r2 error @@ -244,6 +280,10 @@ func (_m *IndexerDb) GetBlock(ctx context.Context, round uint64, options idb.Get func (_m *IndexerDb) GetNetworkState() (idb.NetworkState, error) { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetNetworkState") + } + var r0 idb.NetworkState var r1 error if rf, ok := ret.Get(0).(func() (idb.NetworkState, error)); ok { @@ -268,6 +308,10 @@ func (_m *IndexerDb) GetNetworkState() (idb.NetworkState, error) { func (_m *IndexerDb) GetNextRoundToAccount() (uint64, error) { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for GetNextRoundToAccount") + } + var r0 uint64 var r1 error if rf, ok := ret.Get(0).(func() (uint64, error)); ok { @@ -292,6 +336,10 @@ func (_m *IndexerDb) GetNextRoundToAccount() (uint64, error) { func (_m *IndexerDb) GetSpecialAccounts(ctx context.Context) (types.SpecialAddresses, error) { ret := _m.Called(ctx) + if len(ret) == 0 { + panic("no return value specified for GetSpecialAccounts") + } + var r0 types.SpecialAddresses var r1 error if rf, ok := ret.Get(0).(func(context.Context) (types.SpecialAddresses, error)); ok { @@ -316,6 +364,10 @@ func (_m *IndexerDb) GetSpecialAccounts(ctx context.Context) (types.SpecialAddre func (_m *IndexerDb) Health(ctx context.Context) (idb.Health, error) { ret := _m.Called(ctx) + if len(ret) == 0 { + panic("no return value specified for Health") + } + var r0 idb.Health var r1 error if rf, ok := ret.Get(0).(func(context.Context) (idb.Health, error)); ok { @@ -340,6 +392,10 @@ func (_m *IndexerDb) Health(ctx context.Context) (idb.Health, error) { func (_m *IndexerDb) LoadGenesis(genesis v2types.Genesis) error { ret := _m.Called(genesis) + if len(ret) == 0 { + panic("no return value specified for LoadGenesis") + } + var r0 error if rf, ok := ret.Get(0).(func(v2types.Genesis) error); ok { r0 = rf(genesis) @@ -354,6 +410,10 @@ func (_m *IndexerDb) LoadGenesis(genesis v2types.Genesis) error { func (_m *IndexerDb) SetNetworkState(genesis v2types.Digest) error { ret := _m.Called(genesis) + if len(ret) == 0 { + panic("no return value specified for SetNetworkState") + } + var r0 error if rf, ok := ret.Get(0).(func(v2types.Digest) error); ok { r0 = rf(genesis) @@ -368,6 +428,10 @@ func (_m *IndexerDb) SetNetworkState(genesis v2types.Digest) error { func (_m *IndexerDb) Transactions(ctx context.Context, tf idb.TransactionFilter) (<-chan idb.TxnRow, uint64) { ret := _m.Called(ctx, tf) + if len(ret) == 0 { + panic("no return value specified for Transactions") + } + var r0 <-chan idb.TxnRow var r1 uint64 if rf, ok := ret.Get(0).(func(context.Context, idb.TransactionFilter) (<-chan idb.TxnRow, uint64)); ok { @@ -390,13 +454,12 @@ func (_m *IndexerDb) Transactions(ctx context.Context, tf idb.TransactionFilter) return r0, r1 } -type mockConstructorTestingTNewIndexerDb interface { +// NewIndexerDb creates a new instance of IndexerDb. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewIndexerDb(t interface { mock.TestingT Cleanup(func()) -} - -// NewIndexerDb creates a new instance of IndexerDb. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -func NewIndexerDb(t mockConstructorTestingTNewIndexerDb) *IndexerDb { +}) *IndexerDb { mock := &IndexerDb{} mock.Mock.Test(t) diff --git a/monitoring/Dockerfile-indexer b/monitoring/Dockerfile-indexer index d2cf3597a..17fdea1cc 100644 --- a/monitoring/Dockerfile-indexer +++ b/monitoring/Dockerfile-indexer @@ -1,4 +1,4 @@ -ARG GO_VERSION=1.21.10 +ARG GO_VERSION=1.23.3 FROM golang:$GO_VERSION ENV DEBIAN_FRONTEND noninteractive diff --git a/types/min_balance.go b/types/min_balance.go index be9f99411..22813e96f 100644 --- a/types/min_balance.go +++ b/types/min_balance.go @@ -32,41 +32,41 @@ func minBalance( totalExtraAppPages uint64, totalBoxes uint64, totalBoxBytes uint64, ) uint64 { - var min uint64 + var minBal uint64 // First, base MinBalance - min = proto.MinBalance + minBal = proto.MinBalance // MinBalance for each Asset assetCost := proto.MinBalance * totalAssets - min += assetCost + minBal += assetCost // Base MinBalance for each created application appCreationCost := proto.AppFlatParamsMinBalance * totalAppParams - min += appCreationCost + minBal += appCreationCost // Base MinBalance for each opted in application appOptInCost := proto.AppFlatOptInMinBalance * totalAppLocalStates - min += appOptInCost + minBal += appOptInCost // MinBalance for state usage measured by LocalStateSchemas and // GlobalStateSchemas schemaCost := stateSchemaMinBalance(totalAppSchema, proto) - min += schemaCost + minBal += schemaCost // MinBalance for each extra app program page extraAppProgramLenCost := proto.AppFlatParamsMinBalance * totalExtraAppPages - min += extraAppProgramLenCost + minBal += extraAppProgramLenCost // Base MinBalance for each created box boxBaseCost := proto.BoxFlatMinBalance * totalBoxes - min += boxBaseCost + minBal += boxBaseCost // Per byte MinBalance for boxes boxByteCost := proto.BoxByteMinBalance * totalBoxBytes - min += boxByteCost + minBal += boxByteCost - return min + return minBal } // AccountMinBalance computes the minimum balance requirements for an account diff --git a/util/test/account_testutil.go b/util/test/account_testutil.go index 876d6e1cc..a5e475e69 100644 --- a/util/test/account_testutil.go +++ b/util/test/account_testutil.go @@ -100,7 +100,7 @@ func MakeAssetConfigTxn(configid, total, decimals uint64, defaultFrozen bool, un } // MakeAssetTransferTxn creates an asset transfer transaction. -func MakeAssetTransferTxn(assetid, amt uint64, sender, receiver, close sdk.Address) sdk.SignedTxnWithAD { +func MakeAssetTransferTxn(assetid, amt uint64, sender, receiver, closeTo sdk.Address) sdk.SignedTxnWithAD { return sdk.SignedTxnWithAD{ SignedTxn: sdk.SignedTxn{ Txn: sdk.Transaction{ @@ -117,7 +117,7 @@ func MakeAssetTransferTxn(assetid, amt uint64, sender, receiver, close sdk.Addre //only used for clawback transactions //AssetSender: sdk.Address{}, AssetReceiver: receiver, - AssetCloseTo: close, + AssetCloseTo: closeTo, }, }, Sig: Signature, @@ -127,7 +127,7 @@ func MakeAssetTransferTxn(assetid, amt uint64, sender, receiver, close sdk.Addre // MakePaymentTxn creates an algo transfer transaction. func MakePaymentTxn(fee, amt, closeAmt, sendRewards, receiveRewards, - closeRewards uint64, sender, receiver, close, rekeyTo sdk.Address) sdk.SignedTxnWithAD { + closeRewards uint64, sender, receiver, closeTo, rekeyTo sdk.Address) sdk.SignedTxnWithAD { return sdk.SignedTxnWithAD{ SignedTxn: sdk.SignedTxn{ Txn: sdk.Transaction{ @@ -143,7 +143,7 @@ func MakePaymentTxn(fee, amt, closeAmt, sendRewards, receiveRewards, PaymentTxnFields: sdk.PaymentTxnFields{ Receiver: receiver, Amount: sdk.MicroAlgos(amt), - CloseRemainderTo: close, + CloseRemainderTo: closeTo, }, }, Sig: Signature, From e6a823d9d7f89ac789c5621fcee753f318f6f843 Mon Sep 17 00:00:00 2001 From: Gary Malouf <982483+gmalouf@users.noreply.github.com> Date: Fri, 15 Nov 2024 16:19:16 -0500 Subject: [PATCH 07/13] Remove version tag from docker-compose files (deprecated warnings). (#1637) --- e2e_tests/docker/indexer-filtered/docker-compose.yml | 2 -- e2e_tests/docker/indexer/docker-compose.yml | 2 -- monitoring/docker-compose.yml | 1 - 3 files changed, 5 deletions(-) diff --git a/e2e_tests/docker/indexer-filtered/docker-compose.yml b/e2e_tests/docker/indexer-filtered/docker-compose.yml index 7d7494502..4a7c1bd16 100644 --- a/e2e_tests/docker/indexer-filtered/docker-compose.yml +++ b/e2e_tests/docker/indexer-filtered/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3' - services: e2e-write: build: diff --git a/e2e_tests/docker/indexer/docker-compose.yml b/e2e_tests/docker/indexer/docker-compose.yml index 96528bf09..6171f0143 100644 --- a/e2e_tests/docker/indexer/docker-compose.yml +++ b/e2e_tests/docker/indexer/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3' - services: e2e: build: diff --git a/monitoring/docker-compose.yml b/monitoring/docker-compose.yml index afc8431fb..0cbdd5b3d 100644 --- a/monitoring/docker-compose.yml +++ b/monitoring/docker-compose.yml @@ -1,4 +1,3 @@ -version: '3' services: indexer: container_name: "indexer" From a99e6f7b6c43852704e28258fb505ba5e5116304 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Agust=C3=ADn=20Godnic?= Date: Fri, 20 Dec 2024 16:32:13 -0300 Subject: [PATCH 08/13] Implement the endpoint `GET /v2/block-headers` (#1638) * Implement `GET /v2/blocks` Currently using the exact same implementation as https://github.com/AlgoNode/indexer-api-cdb/pull/10 * Rename function * Rename function * Fix compiler error * Revert f17423ba2ad117cd23ff7d9eba49a7c5cc9ee3ee * Update file generated by mockery * Fix typo * Improve parameter descriptions * Change route to `GET /v2/block-headers` * Remove the `updates` and `participation` params Remove the `updates` and `participation` parameters from `GET /v2/block-headers`. The underlying SQL code is now simpler. * Lints * Rename struct * Fix outdated comment * Use faster/simpler sorting function * Use a more descriptive name for func `rowToBlock` * Remove decodeAddress / decodeAddressToBytes Remove the functions `decodeAddress` and `decodeAddressToBytes`. Also, add more context information to the errors being returned. * Attempt at fixing broken test Attempt at fixing `TestTimeouts/LookupAccountTransactions` * Change function `hdrRowToBlock` signature Change function `hdrRowToBlock` signature to be in line with other similar functions. * Rename `proposer` parameter to `proposers` In `GET /v2/block-headers`, rename the `proposer` parameter to `proposers` to follow conventions through the rest of the API. --- api/converter_utils.go | 244 +++++++++++++-- api/error_messages.go | 2 + api/generated/common/routes.go | 368 +++++++++++------------ api/generated/common/types.go | 20 ++ api/generated/v2/routes.go | 529 +++++++++++++++++++-------------- api/generated/v2/types.go | 50 ++++ api/handlers.go | 127 +++++++- api/handlers_test.go | 2 +- api/indexer.oas2.json | 130 +++++++- api/indexer.oas3.yml | 255 ++++++++++++++++ api/server.go | 10 + cmd/algorand-indexer/daemon.go | 9 + idb/dummy/dummy.go | 5 + idb/idb.go | 45 +++ idb/mocks/IndexerDb.go | 30 ++ idb/postgres/postgres.go | 179 +++++++++++ 16 files changed, 1554 insertions(+), 451 deletions(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index 8b4081acd..8a854c231 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -5,6 +5,7 @@ import ( "encoding/base64" "errors" "fmt" + "slices" "sort" "strconv" "strings" @@ -34,19 +35,6 @@ func decodeDigest(str *string, field string, errorArr []string) (string, []strin return "", errorArr } -// decodeAddress returns the byte representation of the input string, or appends an error to errorArr -func decodeAddress(str *string, field string, errorArr []string) ([]byte, []string) { - if str != nil { - addr, err := sdk.DecodeAddress(*str) - if err != nil { - return nil, append(errorArr, fmt.Sprintf("%s '%s': %v", errUnableToParseAddress, field, err)) - } - return addr[:], errorArr - } - // Pass through - return nil, errorArr -} - // decodeAddress converts the role information into a bitmask, or appends an error to errorArr func decodeAddressRole(role *string, excludeCloseTo *bool, errorArr []string) (idb.AddressRole, []string) { // If the string is nil, return early. @@ -298,6 +286,94 @@ func txnRowToTransaction(row idb.TxnRow) (generated.Transaction, error) { return txn, nil } +func hdrRowToBlock(row idb.BlockRow) generated.Block { + + rewards := generated.BlockRewards{ + FeeSink: row.BlockHeader.FeeSink.String(), + RewardsCalculationRound: uint64(row.BlockHeader.RewardsRecalculationRound), + RewardsLevel: row.BlockHeader.RewardsLevel, + RewardsPool: row.BlockHeader.RewardsPool.String(), + RewardsRate: row.BlockHeader.RewardsRate, + RewardsResidue: row.BlockHeader.RewardsResidue, + } + + upgradeState := generated.BlockUpgradeState{ + CurrentProtocol: string(row.BlockHeader.CurrentProtocol), + NextProtocol: strPtr(string(row.BlockHeader.NextProtocol)), + NextProtocolApprovals: uint64Ptr(row.BlockHeader.NextProtocolApprovals), + NextProtocolSwitchOn: uint64Ptr(uint64(row.BlockHeader.NextProtocolSwitchOn)), + NextProtocolVoteBefore: uint64Ptr(uint64(row.BlockHeader.NextProtocolVoteBefore)), + } + + upgradeVote := generated.BlockUpgradeVote{ + UpgradeApprove: boolPtr(row.BlockHeader.UpgradeApprove), + UpgradeDelay: uint64Ptr(uint64(row.BlockHeader.UpgradeDelay)), + UpgradePropose: strPtr(string(row.BlockHeader.UpgradePropose)), + } + + var partUpdates *generated.ParticipationUpdates = &generated.ParticipationUpdates{} + if len(row.BlockHeader.ExpiredParticipationAccounts) > 0 { + addrs := make([]string, len(row.BlockHeader.ExpiredParticipationAccounts)) + for i := 0; i < len(addrs); i++ { + addrs[i] = row.BlockHeader.ExpiredParticipationAccounts[i].String() + } + partUpdates.ExpiredParticipationAccounts = strArrayPtr(addrs) + } + if len(row.BlockHeader.AbsentParticipationAccounts) > 0 { + addrs := make([]string, len(row.BlockHeader.AbsentParticipationAccounts)) + for i := 0; i < len(addrs); i++ { + addrs[i] = row.BlockHeader.AbsentParticipationAccounts[i].String() + } + partUpdates.AbsentParticipationAccounts = strArrayPtr(addrs) + } + if *partUpdates == (generated.ParticipationUpdates{}) { + partUpdates = nil + } + + // order these so they're deterministic + orderedTrackingTypes := make([]sdk.StateProofType, len(row.BlockHeader.StateProofTracking)) + trackingArray := make([]generated.StateProofTracking, len(row.BlockHeader.StateProofTracking)) + elems := 0 + for key := range row.BlockHeader.StateProofTracking { + orderedTrackingTypes[elems] = key + elems++ + } + slices.Sort(orderedTrackingTypes) + for i := 0; i < len(orderedTrackingTypes); i++ { + stpfTracking := row.BlockHeader.StateProofTracking[orderedTrackingTypes[i]] + thing1 := generated.StateProofTracking{ + NextRound: uint64Ptr(uint64(stpfTracking.StateProofNextRound)), + Type: uint64Ptr(uint64(orderedTrackingTypes[i])), + VotersCommitment: byteSliceOmitZeroPtr(stpfTracking.StateProofVotersCommitment), + OnlineTotalWeight: uint64Ptr(uint64(stpfTracking.StateProofOnlineTotalWeight)), + } + trackingArray[orderedTrackingTypes[i]] = thing1 + } + + ret := generated.Block{ + Bonus: uint64PtrOrNil(uint64(row.BlockHeader.Bonus)), + FeesCollected: uint64PtrOrNil(uint64(row.BlockHeader.FeesCollected)), + GenesisHash: row.BlockHeader.GenesisHash[:], + GenesisId: row.BlockHeader.GenesisID, + ParticipationUpdates: partUpdates, + PreviousBlockHash: row.BlockHeader.Branch[:], + Proposer: addrPtr(row.BlockHeader.Proposer), + ProposerPayout: uint64PtrOrNil(uint64(row.BlockHeader.ProposerPayout)), + Rewards: &rewards, + Round: uint64(row.BlockHeader.Round), + Seed: row.BlockHeader.Seed[:], + StateProofTracking: &trackingArray, + Timestamp: uint64(row.BlockHeader.TimeStamp), + Transactions: nil, + TransactionsRoot: row.BlockHeader.TxnCommitments.NativeSha512_256Commitment[:], + TransactionsRootSha256: row.BlockHeader.TxnCommitments.Sha256Commitment[:], + TxnCounter: uint64Ptr(row.BlockHeader.TxnCounter), + UpgradeState: &upgradeState, + UpgradeVote: &upgradeVote, + } + return ret +} + func signedTxnWithAdToTransaction(stxn *sdk.SignedTxnWithAD, extra rowData) (generated.Transaction, error) { var payment *generated.TransactionPayment var keyreg *generated.TransactionKeyreg @@ -640,9 +716,14 @@ func edIndexToAddress(index uint64, txn sdk.Transaction, shared []sdk.Address) ( } func (si *ServerImplementation) assetParamsToAssetQuery(params generated.SearchForAssetsParams) (idb.AssetsQuery, error) { - creator, errorArr := decodeAddress(params.Creator, "creator", make([]string, 0)) - if len(errorArr) != 0 { - return idb.AssetsQuery{}, errors.New(errUnableToParseAddress) + + var creatorAddressBytes []byte + if params.Creator != nil { + creator, err := sdk.DecodeAddress(*params.Creator) + if err != nil { + return idb.AssetsQuery{}, fmt.Errorf("unable to parse creator address: %w", err) + } + creatorAddressBytes = creator[:] } var assetGreaterThan *uint64 @@ -657,7 +738,7 @@ func (si *ServerImplementation) assetParamsToAssetQuery(params generated.SearchF query := idb.AssetsQuery{ AssetID: params.AssetId, AssetIDGreaterThan: assetGreaterThan, - Creator: creator, + Creator: creatorAddressBytes, Name: strOrDefault(params.Name), Unit: strOrDefault(params.Unit), Query: "", @@ -669,9 +750,14 @@ func (si *ServerImplementation) assetParamsToAssetQuery(params generated.SearchF } func (si *ServerImplementation) appParamsToApplicationQuery(params generated.SearchForApplicationsParams) (idb.ApplicationQuery, error) { - addr, errorArr := decodeAddress(params.Creator, "creator", make([]string, 0)) - if len(errorArr) != 0 { - return idb.ApplicationQuery{}, errors.New(errUnableToParseAddress) + + var creatorAddressBytes []byte + if params.Creator != nil { + addr, err := sdk.DecodeAddress(*params.Creator) + if err != nil { + return idb.ApplicationQuery{}, fmt.Errorf("unable to parse creator address: %w", err) + } + creatorAddressBytes = addr[:] } var appGreaterThan *uint64 @@ -686,7 +772,7 @@ func (si *ServerImplementation) appParamsToApplicationQuery(params generated.Sea return idb.ApplicationQuery{ ApplicationID: params.ApplicationId, ApplicationIDGreaterThan: appGreaterThan, - Address: addr, + Address: creatorAddressBytes, IncludeDeleted: boolOrDefault(params.IncludeAll), Limit: min(uintOrDefaultValue(params.Limit, si.opts.DefaultApplicationsLimit), si.opts.MaxApplicationsLimit), }, nil @@ -708,7 +794,15 @@ func (si *ServerImplementation) transactionParamsToTransactionFilter(params gene filter.NextToken = strOrDefault(params.Next) // Address - filter.Address, errorArr = decodeAddress(params.Address, "address", errorArr) + if params.Address != nil { + addr, err := sdk.DecodeAddress(*params.Address) + if err != nil { + errorArr = append(errorArr, fmt.Sprintf("%s: %v", errUnableToParseAddress, err)) + } + filter.Address = addr[:] + } + + // Txid filter.Txid, errorArr = decodeDigest(params.Txid, "txid", errorArr) // Byte array @@ -749,6 +843,112 @@ func (si *ServerImplementation) transactionParamsToTransactionFilter(params gene return } +func (si *ServerImplementation) blockParamsToBlockFilter(params generated.SearchForBlockHeadersParams) (filter idb.BlockHeaderFilter, err error) { + + var errs []error + + // Integer + filter.Limit = min(uintOrDefaultValue(params.Limit, si.opts.DefaultBlocksLimit), si.opts.MaxBlocksLimit) + // If min/max are mixed up + // + // This check is performed here instead of in validateBlockFilter because + // when converting params into a filter, the next token is merged with params.MinRound. + if params.MinRound != nil && params.MaxRound != nil && *params.MinRound > *params.MaxRound { + errs = append(errs, errors.New(errInvalidRoundMinMax)) + } + filter.MaxRound = params.MaxRound + filter.MinRound = params.MinRound + + // String + if params.Next != nil { + n, err := idb.DecodeBlockRowNext(*params.Next) + if err != nil { + errs = append(errs, fmt.Errorf("%s: %w", errUnableToParseNext, err)) + } + // Set the MinRound + if filter.MinRound == nil { + filter.MinRound = uint64Ptr(n + 1) + } else { + filter.MinRound = uint64Ptr(max(*filter.MinRound, n+1)) + } + } + + // Time + if params.AfterTime != nil { + filter.AfterTime = *params.AfterTime + } + if params.BeforeTime != nil { + filter.BeforeTime = *params.BeforeTime + } + + // Address list + { + // Make sure at most one of the participation parameters is set + numParticipationFilters := 0 + if params.Proposers != nil { + numParticipationFilters++ + } + if params.Expired != nil { + numParticipationFilters++ + } + if params.Absent != nil { + numParticipationFilters++ + } + if numParticipationFilters > 1 { + errs = append(errs, errors.New("only one of `proposer`, `expired`, or `absent` can be specified")) + } + + // Validate the number of items in the participation account lists + if params.Proposers != nil && uint64(len(*params.Proposers)) > si.opts.MaxAccountListSize { + errs = append(errs, fmt.Errorf("proposers list too long, max size is %d", si.opts.MaxAccountListSize)) + } + if params.Expired != nil && uint64(len(*params.Expired)) > si.opts.MaxAccountListSize { + errs = append(errs, fmt.Errorf("expired list too long, max size is %d", si.opts.MaxAccountListSize)) + } + if params.Absent != nil && uint64(len(*params.Absent)) > si.opts.MaxAccountListSize { + errs = append(errs, fmt.Errorf("absent list too long, max size is %d", si.opts.MaxAccountListSize)) + } + + filter.Proposers = make(map[sdk.Address]struct{}, 0) + if params.Proposers != nil { + for _, s := range *params.Proposers { + addr, err := sdk.DecodeAddress(s) + if err != nil { + errs = append(errs, fmt.Errorf("unable to parse proposer address `%s`: %w", s, err)) + } else { + filter.Proposers[addr] = struct{}{} + } + } + } + + filter.ExpiredParticipationAccounts = make(map[sdk.Address]struct{}, 0) + if params.Expired != nil { + for _, s := range *params.Expired { + addr, err := sdk.DecodeAddress(s) + if err != nil { + errs = append(errs, fmt.Errorf("unable to parse expired address `%s`: %w", s, err)) + } else { + filter.ExpiredParticipationAccounts[addr] = struct{}{} + } + } + } + + filter.AbsentParticipationAccounts = make(map[sdk.Address]struct{}, 0) + if params.Absent != nil { + for _, s := range *params.Absent { + addr, err := sdk.DecodeAddress(s) + if err != nil { + errs = append(errs, fmt.Errorf("unable to parse absent address `%s`: %w", s, err)) + } else { + filter.AbsentParticipationAccounts[addr] = struct{}{} + } + } + } + } + + return filter, errors.Join(errs...) +} + func (si *ServerImplementation) maxAccountsErrorToAccountsErrorResponse(maxErr idb.MaxAPIResourcesPerAccountError) generated.ErrorResponse { addr := maxErr.Address.String() max := uint64(si.opts.MaxAPIResourcesPerAccount) diff --git a/api/error_messages.go b/api/error_messages.go index a1bfbfbc2..cd364ab46 100644 --- a/api/error_messages.go +++ b/api/error_messages.go @@ -11,6 +11,7 @@ import ( const ( errInvalidRoundAndMinMax = "cannot specify round and min-round/max-round" errInvalidRoundMinMax = "min-round must be less than max-round" + errInvalidTimeMinMax = "after-time must be less than before-time" errUnableToParseAddress = "unable to parse address" errInvalidCreatorAddress = "found an invalid creator address" errUnableToParseBase64 = "unable to parse base64 data" @@ -38,6 +39,7 @@ const ( ErrFailedLookingUpBoxes = "failed while looking up application boxes" errRewindingAccountNotSupported = "rewinding account is no longer supported, please remove the `round=` query parameter and try again" errLookingUpBlockForRound = "error while looking up block for round" + errBlockHeaderSearch = "error while searching for block headers" errTransactionSearch = "error while searching for transaction" errZeroAddressCloseRemainderToRole = "searching transactions by zero address with close address role is not supported" errZeroAddressAssetSenderRole = "searching transactions by zero address with asset sender role is not supported" diff --git a/api/generated/common/routes.go b/api/generated/common/routes.go index bf1f44d7f..e70663e5b 100644 --- a/api/generated/common/routes.go +++ b/api/generated/common/routes.go @@ -72,189 +72,191 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "H4sIAAAAAAAC/+x9f5PbNrLgV0HpXlXsnDjjOJvU26naeuXYScW1dtZlT7J3z5O7hciWhB0KYABwJCXn", - "736FboAESVCiZsZjb9X+ZY+IHw10o9Hon3/McrWplARpzezij1nFNd+ABY1/8TxXtbSZKNxfBZhci8oK", - "JWcX4RszVgu5ms1nwv1acbuezWeSb6Bt4/rPZxp+q4WGYnZhdQ3zmcnXsOFuYLuvXGs/0ocP8xkvCg3G", - "DGf9myz3TMi8rAtgVnNpeO4+GbYVds3sWhjmOzMhmZLA1JLZdacxWwooC3MWgP6tBr2PoPaTj4M4n+0y", - "Xq6U5rLIlkpvuJ1dzJ75fh+OfvYzZFqVMFzjc7VZCAlhRdAsqEEOs4oVsMRGa26Zg86tMzS0ihngOl+z", - "pdJHlklAxGsFWW9mF+9nBmQBGjGXg7jB/y41wO+QWa5XYGe/zlO4W1rQmRWbxNJeesxpMHVpDcO2uMaV", - "uAHJXK8z9ro2li2Accne/vCcff31139mtI0WCk9wo6tqZ4/X1GCh4BbC5ylIffvDc5z/nV/g1Fa8qkqR", - "c7fu5PF51n5nL1+MLaY7SIIghbSwAk0bbwykz+oz9+XANKHjsQlqu84c2Ywj1p94w3Ill2JVaygcNdYG", - "6GyaCmQh5Ipdw34Uhc00H+8ELmCpNEykUmp8r2Qaz/9J6XShdhnBNCAatlA75r45TrpSvMy4XuEK2Rcg", - "c+XweHHDyxq+OGM/KM2EtGbucQ2+oZD24qunX//JN9F8yxZ7C4N2i2//dPHsL3/xzSotpOWLEvw2Dpob", - "qy/WUJbKd/DMbDiu+3Dxv/73f5+dnX0xhgz857QLKq+1Bpnvs5UGjhxnzeVwD996CjJrVZcFW/MbJBe+", - "wavT92WuLx0P3M0z9lrkWj0rV8ow7gmvgCWvS8vCxKyWpWP1bjR/fJkwrNLqRhRQzB3OtmuRr1nO/YZg", - "O7YVZemotjZQjG1IenVHuEPTycF1q/3ABX2+m9Gu68hOwA75x3D53+88lywK4X7iJRMWNoaZOl8zbjxU", - "a1UWRPTRBcBKlfOSFdxyZqxyjHWptJd4iOvOff9WiGM5IrBgi32/pSw6ox/v4/YHdlWp3MqWvDSQ3q+w", - "+niTcJWxbMHLcuZvLCdo+Smz5gdeVSbDFWfGcgtxm6pyLaSSkBBAmh+41nzv/jZ276QsZK2zFjtZXioD", - "mVVHBLAgU+GGRSJTvGMniWPscg0MJ3cfSBRFypaOS5flnlmPAEcQLAhfcyaWbK9qtsWjU4pr7O9X42h6", - "wxzyEWUdSdFxszHiHmxGgrQXSpXAJZL2GngBOlOy3A/37Uf8yNxHtiz56oz9fQ3+MLu730FH4MyZBltr", - "6aisVPk1KxQYJpV1coPlQvZFdjMCfwzPEdD9qyFzpDcuv5ThSFJzJ6rg3hSNaDNnBZSA+GnPD/5qrFZ7", - "xJuj4jlTlaNXVdvhuZaFH5Y+94850vzoAyVeyZFFl2Ij7HC5r/lObOoNk/Vm4TC2bGQdqzxqkE41sBzJ", - "bdFhWhVfgWHgRCFBryucxyHZ4VADz9fjDJVgOsJDN3yXaVXLYsIjwjKlYyHNVJCLpYCCNaOMwdJOcwwe", - "IU+Dp33aROCEQUbBaWY5Ao6EXQKtjrO4L4igCKtn7Gd/7eFXq65BNrcj8XlglYYboWrTdBqTltzUh6Uj", - "qSxklYal2A2BfOe3wzE3auPv5o2Xpz0LgIJ5PuCGI0Y5ClM04amPhgU38O2fxiTm9quGa9gn74s+AdBy", - "Gi3F2n2hvodX0cxw5FBPpEMSD2L6O0h7k+gOG2XENhLinfvqmUpaI9TpP0HkjucmfUR2J90QjRFu5rGt", - "6M308Z6hRqwyGnFwSsTq0okRS1GiiPFPdzgCZmvj7qUuboPQYcRKcltruLiSX7q/WMbeWS4Lrgv3y4Z+", - "el2XVrwTK/dTST+9UiuRvxOrsU0JsCZ1RdhtQ/+48dK6IbtrlpuaInxOzVBx1/Aa9hrcHDxf4j+7JRIS", - "X+rfSWzEK9FWyzEAUvqRV0pd11W8oXlHX7jYs5cvxogFhzzED5F3mEpJA0i1z0iQeOt/cz85lgcSOXok", - "C5z/0yh8RLVjV1pVoK2AWD/r/vsfGpazi9n/OG/1uefUzZz7CWfNI82OXWV0gLn1LIxYl2dqJAxsqtrS", - "1Z7iDs1xft/A1p+zRYta/BNySxvUBeMRbCq7f+wA9rCb+9st03mQTNy3/qPiI+4jXe4ZXtLDkX82/uFX", - "8ZWQuPA52zoxe8OvHVfgUtk1aOZwAcaGa57YH938jWLZywr+rXA2S52YBE7NnZHaYu2VE3ffobh7Hyju", - "PRtPwHUKpH9jvsH8YGPvkwRW94T7gxr3q6v3vKpEsbu6+rXz4hKygF0aHx8V2aVaZQW3/HY0unrhuiYI", - "9HOmoa41474I6H6J5wQsPOyNel/bdc+H7VY89t+cNXEq7s5UjQH7HS+5zO/lOl34oSZj+LWQAoH4kVRd", - "/0ZzQHOzlfeBYr+793KQSeM++Qj/G7mpM9zYMe6M2vtC6SREPvCLEKe8j036VIT/b4q/X4r/rlT59a1w", - "eQhVOOqxmdXu/udVu9Ss36kdE5K0f17y+U7t4HN98iwcbJOPxXdq98JPqfS/9muEFj6Fgr/zfjEGjbwy", - "3lm35O+1VvoesBvehj145rMNGMNXkLa9xGsMDacsKgCMCAG3BNRQ/wi8tOvna/gIBzUa+8hxvWyVsfew", - "sR+VZUd642Prj1Z15LHXHfZELhtNYz733ft82EVny6czxA5O++xwOo7NaUj+EOwPsYEh4dLnfbaj68hh", - "inu3RjIPXskr+QKWQqK1/+JKOj50vuBG5Oa8NqD9A/NspdgF80O+4JZfydm8f0GN2erQBctDU9WLUuTs", - "GvYpLJBvWGIEZXkZOTBEbmLebNxaIIZ0RqNmjhxUbTPvlZpp2HJdJOA1jdEaRyZ/tUOzzpkfm2zr3uvV", - "j5+m/YHP09Dn/qA7mJBdfy2HyJ+U9RZovmVESKw2YNg/Nrx6L6T9lWVX9ZMnXwN7VlWt5vsfrXOZAxRt", - "X/eqRsfFIg4z2FnNM/QpSROKqTd405Ylw7ZdxzWtVppvvE9K3yXuwE7T5NNuqmhZuKJ31OvDPHpG9FCF", - "v7M1lENHulMRE725b42XI+/2A67dl1EEAl9xIU3g7UaspKNq7825AJa7uxyKM/ZyyZA3zTsBDD4Uw/O9", - "hgEIQw6Y7NKtC10kWM4lOmZWBbrCCcm43PeNsgasDZbwt3AN+8vIw+JES713x+JHLraidsM1l1uLVbbl", - "hm0UWulzkLbcew+vBAmmgamFtORq0nF1HAASOR66UxHpD8dcNyNnNl5VbFWqhecdDS1eNMQY+oyziTcO", - "AHMPLCL5nu66gh5bPR2zMZfV01fnxrvTITu4plsT11Jog36CwD2r5/FhuAWNeSfGISh/XwNKUUqjM1+X", - "jkw4vCnybnyU0NkSpBU3kEEpVmKRinPKeefGDJ6u3iO0GcEwsWTCGuZVqA4IIZnmcgVOenEShzK8pKiM", - "JDQlNzZbA9d2AXzEbw4R0zqKd5bt+rOtY1lKlkLC3G0O7BwdC7cTGiRsoXCrEdq3Ye4Or0euegSIAE+h", - "YBI8oTvuIe5Zeq6NkJnfuoQjaJBfmt0NAmpwC4yPEsJF3zeAAQxq6/DioFDe937gWV67J2gatIprK3JR", - "TbO7ESBvOn3cIMdkt6S0ppZ9oWwgPyVBpsaZW/NwptqQ17ZbV7jswuj07kGozxi6qvlNWpToyN1EThG+", - "uUYP87BUiiQaA8eMicdh8u7a40O35iYcPIyTCPfEJIl1hJm15Ov4aES/8btDuHlLuOFjOz3uG4e+4X13", - "NxQhhnEOwamUIkGDT1xwhAveb+5fx+/qsnTcppbXUm3dc+YU/7b5jI78EOAbhWIKfQ6E4UH8wkSocXD8", - "bblE/pExIQt3iPDRwW0IW1G5oOiAlic7Xr5yP565ARx1uQEmj5AiWz8kSthKlTQw+0nF50+uTgFSgsB7", - "hYex8YKJ/ob0KxzFdJTYyZ9eyDTF5eGUu3dCRypCwDDWaAEgyS2fCTlnjpXd8NKxMqtING0GST+1HnVe", - "SV5wN4/HnmBpDRGtCCWXk9ZEss5tVhOL/wHo9NvkAMQLtcswdm8IK4bgVVXWMDElyz1FuvTf6TiCW4/K", - "kUKCl/I17CnIBsO+8JSgRtbzjwWUykn6akBhLaKOAH9XwO8RmsMCfoqaDZIeSd4t2R0I1To69Yh8PUZ2", - "j5CG7gBAX//eOFd7Dc9RpUxXlBle/O1tOG+d2Ykjp9nI2FEcEnyXipJYHNnfoRqv8Wl905d+ksq6TitG", - "TRZeDxW9hVK3n2NHuZIGpKkxGtKqXJVnAy2dgRLwGZF1BLLsGhJBXu9C40hvxx6JpXufP45eBxpWwljo", - "xCk28QdteMUeY/sqbi1oN/z/efRfF++fZf/Ns9+fZH/+n+e//vGnD4+/HPz49MNf/vL/uj99/eEvj//r", - "P2Yj1zI4cVst02t6q1Rz8WFjho07S3twqG+UhQzffdkNL1PmvR/wUZiUtDqIZBRMK0Z07jjRNeyzQpR1", - "mhZ/arigqRfIqYVkwB0n5DZfozTdmdG1OTAbvn9GVvWK39uiJpCzdqjvDvwvQtc9fnroECeIKYX2IXJG", - "9/EAW0PJ6AWUZLwcz3pBB61wDc8OGQ4GB6MIYx96LUZQjN88NFJyLV1/0PFVoCUd5RZho7hbM1jRVB3Q", - "tgmZjUXQLW+UXB9d1xOvLtb3+FHSKhb/8Q7LGw4/dXnJ9ETTvB0QYaeoLEkAGtAUnhU/2BF6iuwiw8vV", - "PSOMf3DQAYmES4pHl30hs0dnTVjxNFwEWcFHOau6uQkPy7L3R3OQeGzR2lPkx5ZabfCwDWXNWAE5opfo", - "UF17tfRm9WmThvTi+CU+UI7agYGXf4X9L64tYtX1DhLm1FPSqmnCKy+8OO6EmrvZvFKU70c8SvkUtDBG", - "9phgh2wTHQv1iSegVCuTivFbtSGxMRUswD2KYQd5bVu1Z0+53uj/H1YG7BsS0uGLkc8BJXk6LCng/vix", - "jmDsTcMePybCeFVpdcPLzNtyk9wcWwRr7wPLWukDdfn9s1dvPMRoQASus+atkV4INmrfGJ/tWpyooY4Y", - "g1ERFRQA/SvdG3OF6RiAt5hSovd0dcKTpyLamNaIHx1TbxBeBlH7RPOudzKgJR5yNmgVPuRr0PUv4Ddc", - "lEFlH2BMXxW0pNaV4+TbIh7gzn4KkV9Jdq/8f3B40yfhCKOJZziQMWJDeUsMUz4zRIss9xhFowCS5Ybv", - "HbWQWnbIcWS9Qc1OZkqRMot11ZUMW428Z91Q7mo9NIj7biboxHpgRYMnty/4+Y/t1kJ5Z7dait9qYKIA", - "ad0njWeudwzdqQsJtG79eklYsCnR1gO+X3DCU14uPm/PnRbXjHKb94t7nySsiYQ1v54Gd3d5x7Qq3KEc", - "h0AcfsTETkQDcF80qslARY2FgcuOGfkE78J4xoHYMOIZGJ07Kbyd4xZYOZ5OMzyUfF6nNH846R0Up4m6", - "0+vHZEutfk950W6H00YTUq/0oJNfL71zMvKKEb10d7dAUZNg664gNa/eOwPVvx0b20abY7VFzughG5O7", - "YxtM1yV1hJHjecMwEK6vrn6lh2Ww83JJB+w55mrtPHnSxzR2UD6n8dtj6mEe6iP4dsHz68RiWq/AjiXa", - "KhY6NSnTutg5Y5GDYdPWZx+rQG+E7bL79kV1W8mWpp0s07YiLFJTLLz63IulUYlharnl0oYccp6B+d4G", - "yKTjem2VNhazWSZXWUAuNrwcMe+1DLIQK0FJ32oDUcoy359VSkhLRFMIU5V8T+6W7Y68XLIn84h5eSQU", - "4kYYsSgBW3xFLRbcoCzSaphCF7cqkHZtsPnTCc3XtSw0FHbts+kZxZpHBypoGs+PBdgtgGRPsN1Xf2aP", - "0MvFiBt47DbPy5Szi6/+jBZG+uNJmpdj3tFR3hpYeppq0aeHurpL0Q+W5rWUZ/ukM0NdppwYbOkZ/vET", - "s+GSr1LZvg7AQn1au35vH2RBKTNRZGLCpucFyx3XydbcrFPpiXO12Qi78f4ORm0ctbQJsWiuMArZ9Ild", - "N+CEj+iBXLG0cu1hNT7pXMw/8Q10N3HOuGGmdqC2SivP3M6YTwVXUC7OVpuIW0IpnckjjXS+yyjhcm2X", - "2X+yfM01zx0rOxuDMlt8+6chpN9hvjyG+aGhoLmmA/7g263BgL6ZdtCCmOT7sEdSyWzj2EPx2HPq7pkb", - "dWdKs+W+w8nhIafKSG6U7DBV8YjL3om+5IEB70hxzTJOIruTV/bgBFjrBDX8/PaVlwc2SkNXt7oIMUUd", - "yUKD1QJuMPQijRs35h1RoMtJm38X6D+tDT0Ih5EAFU5sSlSnQPPhdnj/9WbZY49epa6vASohV+fkv43C", - "NI3aF6MXStYjGstKOdlJ8JJhI1bxvdvlRgQ94Bu+BDBZrsoS8uQbtRd95Zqzigs6NnGGzeD4eGCuFUgw", - "woxc51dX71dr90Jxn91NHGlZKCCAfO7Mwx/RAPhIhP0KpIP75YtjUA8G7rpVUKjTUR1Oxx/sZ9/HDebT", - "92Y47/guu3YO3jch3S/B6do//Nb6GAY9Qtj+a8O/+9Q1VfkfBsroaIyFo9qalyG2E6l7CdoXMOmAgzoY", - "LDEBwIyQ10d984+mq3jr24471V9dvdeycJh77sPnyEeqa8cmZG452iVAFi30+ZqLEZ9UA5Ce0H1wM75T", - "2gpy2gH4xA58VvP8OqmAvHRfTOPER572kTufmRzIhdaIN67PZZgtZYwVGzCWb6rk3lnjdo7uArxX3PY1", - "XRzDNJArWRhHQTkwqJRZH8soYNJT7SROVgpDsk7MmXOlKfssyq5W9aK9p27Jwbj2LoyZVsqOAerg7CQk", - "UMoyXtu1u8JCHAFgrYD+Sij6Dd+tMgp6Yq+dlBHy9vKy3M+ZsF/QONp7dnK2AX1dArMagG3XygArgd9A", - "W1QER/vCsMudKAyWDClhJ3K10rxai5wpXYCmajOuOb6lqZOf78kZ81G9Pg7icidxeU1xg3idtMwQvdJY", - "tOIVz0mE6/+MtR4MlDdgztjlVhEQps1tYJz02+mxqC3FDBZiuQTkHrgcfIpjv/ZDBBOWR8FQg2ZYv6aH", - "5wEDCsvMmj/95tsxQnv6zbcpWnv347On33zrJGEuGa93ohRc7+NmrtWcLWpRWp9om7MbyK3SscZBSGOB", - "FwPaIm2UnwVlmWUtc++G1nSJi9i8+/HZN189/b9Pv/nWq6+iWUIUtA+wA3kjtJLuU1AYNhTip2xmg50w", - "9hNIS3YnM3wvp251h5oc0bKTz6kR84EXXXNuj4VtSD8VDn4JxQr0vL2IHV9tc464x53SkQS8BAoRc/ei", - "kFaros6BMl286/CNCCwxAKkpnxC52+BZD1WEWjiDJrWRWRh7iS/gJ/Qgk6q7QjxjcAOaYnragR7R5RDB", - "ZSzX6KeEbkt+qVA8Tl/tdbXSvIBpXgh4Wf1MPZrEDWGEG3XaAL+49v0HVucN0JGs0wJsFMjhZJT4zk3d", - "OQe4xOj77e1YBOUPVJlHQ0mhblgZBdvOB6+zJUDmBMEkxbtXEybgynOoHKXHlSgB3F1DJx3PMlbIC0Jb", - "EwRNQXhpDRbClOW8zOuSnhIHRMhtzku0BLWEXcLSKkd7caWt1hQg3FwL9BCnkiI0n3Z3WNQD00bdgN77", - "FqR5CRU83LnRPdedoaiclXADZRJw4Bplhx/Vlm243De4cFO0YMyjyLgGchKC0UOEsP2zVwpF4NM58wR5", - "GEiHipHNLWI8V6CFKkTOhPwn+IMePx2QYqgUkJJWyBqLP2lo4aarnmGIbj8Md0gBOulS7ODiFhxgbRSH", - "hG0H20X0UOgGQxjLr4HADsHEXrqZilMNRhR1GrKl5nkXstOI0R/et9zCuW5Qa+6JLnvMqznkhw5dn5Z7", - "ZNPD1nCXRvlUhy9PYVa8ifhinocnnMV9BqrQckRjoKzCSzvK3dKMfQPadN2QIzMB7I6M7Vp0xqe8XCG1", - "wemzZMEfzYzOtyd23NJckJ8p8B77+7QKqR0cSVrWAGC2wubrLBU44gGgFg6Gt/0n/HBKki7wFMJyCbmd", - "AgNG7VBFrFEo6LOD4gXwAiPG26grirfqg/LoJ8Xc0CYSeaQR+JBoJR4c5fEJCc0bCjlG/L+oibTvA+7R", - "E2LCMQgyjsd9cst8G088L5uod872YHBXGu/y6IxgZpK0iTdMWkDJ94emxAbdSRuZNxi36c7BBB7uQiFv", - "9tEg5DC1P2eHJndN+gtujufwVMSldgaYVAknt5BLswmh8lkJEz6bSRuWI2a+QTIO5WrnbNExSDy8UfF+", - "0mKk4xpD8MlgG/BL2Af8o78Rn9i6Esrs+nuSVvJrmlCipLJJkima71FINMUZ4PpD8j3uq8hOpKaeJStQ", - "1Gewb6l9+v6GlyOBlm+h0mBQT8DZ5ffPXnmnmLFwyzwd6Xh19Z5bR1PYj40mm/own41khri6er9Ajkl5", - "HxpsDK2LSR9qx4iE6+4+D3rfziVvLIlqtKHBF38I0F9DABiruPCOXm2s6XBnfdDxMLp7ShBZi+D+InxU", - "7+gR+pGb9Q88t0rvhxlc3dN6JLXO1dV7h+9Ttvirb9Ps3oGQnuQyyt/TVZE1/n/oexfkIbUc5PFhmMhn", - "zb3mLPzpXvpR0p7m+2w+G+gBWlzEeYgTfkZr/Ey5DVmo5DbE9Gi65mKRNWEjqYqO85lPtxznmD0aCiZM", - "thErjSJPetTxNNHRFZW4YUjUTpRF9mLNuCzeI9LOwnsQt+BFN4KfOUXQL2UBO9CtZeZ1u7qepZzUR1gY", - "2GStMjXNm4jYH1Y+oDh8N4WxUBzQ1ixPPIrk8VM6MW3S+OXtxpcZisky24JYrdMb++ZWQzsx+jjSbh4e", - "aSkG9xq1/s/cgUSKHGG0y5YNH0yGHnFs9A2wI/Z7u6blfy4hqRrcG6YaAdcWJxLCf45sdr+yUIJRG7Gp", - "SnL+9KxkkPvqpEQTbYDJx49Xuu+gj48evgG39ki8/6iN28JyPCXV4ViNv8nnalOVMC48V1yS+LwU0r/b", - "t2tu42LqwQak8rzWrRG3H43xCy8FVfk1mMVQKlVh2sLKCun+gwkcVG3p/8C1+w85FXX/R1QVyUluqBni", - "BZNfhYFCJOdsPqPOs0DZSSkq6Zg02JRuOquAT3TCRluaBCgwIKHNJn3Oc0v2T++sKcFulb5OPGMWBvVJ", - "Hb+quOzrkJtybeuK0xOFNx4UPoVrkxWuAc1DZmpD3jUd/4mjvBJ2laO10wEs9OZmIoTN5il5A9rbPpTP", - "KUlWDkpTO0jYxDx4p6wpxapvmQBokhvK8IWW2OZWSCTVYNq3CdVaOn4nR75CQ5fNXO8rq86xDTY5N1bX", - "uTXktdnOOaBKt9HkvHS8fl5fpHCSgDKC7JlWZRpugI+p6dFVC36rwSEZTXWuMWsGSCF2KtPu7zGNnd5a", - "BCR2haGgKXKwK/chWSZ3e77h1Xua5VeWsbcEcVNKAT3yNmZVne65RUOlQDe8tNnoK8fLl+wdL20sRjiA", - "vJ9H4yEznriWJNjk6PmneHI4mG5Pgm7BUBwS97e3EPdHeQfO21wUJIF1j9QNaIqFnkwOv4QeH+azB13H", - "2+bEDrlCtL5pq4g3JWINaRVL+BqOU5sqmcuCRfMbhmcj4SuIRxek1fvbpBkSq8yU6oTlvROrd67DkS0N", - "zQZ7Wqot6MzNewDFZTA1UrwNteykkm5qudB45CkBBXOLMbfbCBr4pJ3wXY7vRTt2zymFl7mSWWf2h+U6", - "xC8zpK6syXJwZPf4prt7VXhbn8q1kEnshVylMz86Rn8N+89Dl5DwOB7gE02848ocfGj81Dg0REamrTci", - "k5GwK+gcqSLhnmsoafpyOQfOle2eq9a/aCNyrTg6Y7Qpp2EgwfrHHvoyNrtxyMEkrVymxNzU+XJfQeOU", - "Oyy1s+FVeG/hO9wJwWcfU2nF3jbuyEOP0lxJywUW1EkK9+SMC2WFjKrVjZ99VuT7S3Qz93xNDu9PvkEC", - "igxXsf+2+/9wy6wGeHgP12vYZ6VYghUjBuly6VbyV9iz0Ozs3mSKsRxJHYMfah5Kiglo8z4xpenLCr/E", - "6aUY8VEMkjbhL8MKsKA3jhTXass2db5G2Z2vICRYQoMNepb3JuqMHjJSdNOD+fhAU/GcBqKw/5LrFWjm", - "I/GbuiTBALThAs9J6w3cj89FRzGeMsYdS/v0mlIBRLwLTadRDqhEdqkAxjXsz8kyiL/fgpGMp5IaAQzz", - "Sn1EkO6UnirOaXaEXq87RlUq9tVJ/taAf4/GVQefVyGcaFwdZmubujxcBx6H2sBwndOjceK9TTxx27VN", - "9QwYbu6IQf+YHX+kZIs39yIfx74M4WP/+OofTMMSNOqtvvwSh//yy7n3V/jH0+5nR21ffpl2akqenPvz", - "G2gqAbgx/HRJ6ugWgO3ZUOmSNxROS45r7kJTEl02y7IX8iQLhskGUDzhGAECpaog2RqLlcU3KCaA07Cq", - "S06hPkJK0J1OUzL90PPf7qRXdeGflzuZahuLk9g62o5UgdCoCvPtKuf2yslRnqUcMxrddsQ2J1I7ImVX", - "ucuIP1BKl2bEEGF6lzEv/RhHSjheXb03K4lquaCMEyFLAArAhOEuNTWZA0KZx5CpqAlng99qXvpwPYnB", - "cZeYtie/BkkVHB2X89V3GUhTa68SdLDieA4UP4yKL3PTNrltLcfxgmBXV+91Ttpf79Huk0Fg5inq6sSM", - "wiFHHS6q4tq7J+ZYMjon2XI3l28Y4ovRV/TY0wvJWG/Gbfi9bNFxZAlmXAz9R4Zv65e0pdDTuQjbpJK9", - "m5ny3z96+eIxE/1i6HHWx+ihdXzZcQmVaRBRhpEBLP3ck6dAsQQYC+fpBRayJYyogg+W73Bj4auQ6nhg", - "q74L9lEoJ2ZV+JEbrNLhm7eR9J9jKoUOkOzli6Sc0cmOe3JJiPlspVWdjtxeaTQN9X1B3SMABSx6wJNz", - "2fnTb75lhViBsWfs75hcjy7fYV20LjaZaOutdUp5MgSsSdBKYpAPRozmXHuEDoKDhQ9KxGEeHsO3yU8+", - "n6FcktldKsD95UBmYZWP4MTcohG/6bi930dYu5BWc2K+mVouk/l2/4a/t24ROvBkDUOsT+DK17DXcFvZ", - "5a/YuSkxOs55SuQ8WGvndoynBD4SOVDuEsfn66dZe4LO2CvXm4FcKu1e1ZsaLX2ww8R83uAWS6mYvs62", - "5aExc538HbRCpYFkyhu2+2es2WyMsuQ5yvPGRxE7GJrEuo1i8tE7lGbmBORjepMOjxqrpRUk/rht/CXa", - "xcpdPA7ov69FmaCCSrnvJoZjzqRiCp2D4paU1qDNukgw+7DwDiE97DGP04kXaVO/owSMh3wV1dZoNRL5", - "msu2YvvxkgxDmpxWk3lQlChxzNMVI9wCVrSA1b3A+Wkd9aQaCQ91H1AM0UAZEhvt2QMnA+L7DUh7S873", - "hnqTbwLWs9WHXwB65AUQeh+rA3wN+8yq9NhAhiWSzJunFupJidtGa5yPvHuaGLtQA7+VXekEORFhWaNB", - "NzJdBj2pf9I1/mTXsG+9XeJagfRsusUri67FtBb8UmygfZeQIJcSgcSkK5Gel+l3LeVEIpb9xYHlNMMc", - "pgozQhXU9zBNTLbzRmQbGXoHeY5ucQoiNyTMxXEgzGNfQTewDx0TG0VdJ8kF6gzO2IsmSQz6IVKsfZs5", - "hvRZfW9FyojSZEkWOui9uA76anRoRGc3PDUJRuAbkGzk2gylJN+E50tsMKYICs12S9Btu5QyJrRc6t/b", - "hkM9UGhWVehZMKLR8q2MrdA4NIbp1imz4vtZEAZn85lblvvHge3+Xerf3T9VVWKV02o59MlMH2BPExnO", - "kwhxn3VfrR1BsjmJLWkd0YAerKPnA3eXVIO3uVVPVU/GCnRKR97+8JyX5eVOej/AYdjbAc9LXlHo2yvv", - "cdlwaMfGvftu0Fp57hBbYnieOxGvaFM+RHB+YVi/bgolghhWTjngjXmUQ/dFgJg2uV6NrhsVVkMxVOSM", - "61VN6YceYH1HVjDysuGVKHxCxmEhOy+yEVuoNRRMaZ/KSyx9nraxSg7Hy1TR7lVeZhR5Kxq2WShGKH3u", - "Hj9Q+WTrSmZ541nu7kn3wrSKXZFH9tXsjL2knDEaeEEMVgsLqTpKnfVj8tstYFnnQNFZg92oCt6ZO0Wd", - "mlsGKVsD+k8kSqT9S9bjQoyZegRjY1yJpKoukj4Bhp4Pi4lhsQCp7L8QniZV5rq6eg8VHqxu2Ys4jqKq", - "mmJdJbh9/63GADjHsHHYER2t0iBWcqQWOxLIkoeLwPTRlbwOulzKpxuMEW8Gt0Qjjt+OiaLlhQajFAK8", - "yLCU/QGX7wR7bfZipDg8Mbgm2aRpY2+MX2VUA2PaEgObeROtEAk7iLL3ub5blFS7cx213gAdrnGsbyfA", - "KFF5Lb4L+0Mfk8wiK+dByYxKNpRu4cSfNGTh/gwcSxZUzaFu45Wu5DP2O2jlH6vNUO5AtLpxnwbc50c9", - "S3RqCquYQbf+lCcWrKHFH5AORwtAXV293/GBlIEw3UG+uF0Nr6M4/mGklEiM42Aq8zVE7lgJiGY8sLFt", - "zOXQIsYL3Neo/kLs40VMpikoQLvta6ogsfDtSBmTg9hcHsTmgfE7GZi24XVI6YfT7NO/JinX1TbsOPVI", - "xXWOxyi2FaWGU085/I3zwCTSCC/kuxJHmPUAeYyb0jknL9FnZER3rzLjBa8A3xnzLCSdyNtAuQzcLNjm", - "gvU4pjR3M9G9tuHVvVaPO8o8IojHfQ5g1OOgzWvmL+ZEKnMaofVtcLJmsEYmRMYT1x5GT6MQv/bTWfG4", - "KoRZq7osqDDEBnOxtW/MBHZ8AahGLmwLcpEbB3pdxEHWJpoh3mzGXrqRebnlexMUtS1ljQ8XdpXKRySU", - "hHGyRtIup/dG5+QmDrmoBEjb+NzEeHFEPq7eTA/s1aSO61AWOXHTaC284z1vK6l1TW/B8uarRfHohp77", - "beZlV11AAwdVtGvzPIwdVtSgNLrQjqcUSdXTa7b0CNPzttGD3M7rFU9lctSLuBxNM87epJLdAOARo4x0", - "jRzSXnN93bkE/WH1A8gVpRPojNqRMaIkAAZKSkXai0Eei5AxUHpTxpt6UYoczQjo9N0YFrzHf8Heclmo", - "DfshJPN59MvbHx4zDaYubSCykNnYEZ+H5NOWExhdeKWXfuXvomiZZvlCeovKShirE4rLB18V5nw85nDk", - "Gi2Nbb2OyGBN6R4HAeHCc8H0NYQTXsM+K0RZjxKya3VddBNumnqBZeGEpKy8C25z9GYZgGAOTH3Ew8G1", - "KWmp6OZw15VOOzC4XH9iOrNUvfPzuRHQkadEMK8e5p7ecnMq+/TdiH/6mW4nH5J42IZJRImAHT5DQZTe", - "xX8nKSuaguK0nPRhfFXCVtjqupS2RT9l4xkaGRKOupx2x0u7nQY5CyfBwmdiKHG5CfH293dLKxlh/8IX", - "Ky0j4WdZy8L0trAth3/A/npQ9vGiT2hz0JQ7JhRMlQQ6QbNdSNBw6YNO2nhpY1QuWiM81pqkqpJ/k+Xe", - "J6XrV/Rot7LS6kYUqUL0pVqJ3JAK5lSL8avQ98N8tqlLK245zuvQl0zY6etQrPxVKAuuCwbF02+++erP", - "3VQInxG7Gm5S0r3HL8trGbkVeVeObVY3gYkFVJ6t1JBljRrb9Kq1PTTGtVTi1uk2MgRkPPQ9KFq9g8hi", - "z3hE6sqJ7aUV7U9z99uam3XLOqOyxVhGmjPPr/pefxhfFBn6Hjj83BN2difHjN7xGGMc7SH5HM5GzB6J", - "HqayxNcRJxmscOOXSHpXRy8h6BL3uirByXYtDxxNoxNQQ1d+mPOdGFb5j8dL7zo2wNKBykkilJfVCZOt", - "xIUKghaqW3gHD/bnXQxXKi/eWoNxEKW9b9Y6mWnkUP7NNvNhIq/6Sbh919vTXmYS3LdRCbe6/kQJbA7R", - "wOeRxSHtiHVYZB7LxcCmBOY1yaj6SajGpecoK+wh0h/Nt9p9P0/PaOLB6Xu5jbmnmSo4qF1GoaNxhi72", - "ksi/9WpEOVZSvhqfco+Mv74AQHe/7h6S/wEjBJaKshtIy3PbphafPfMjzXyR39na2spcnJ9vt9uzMM1Z", - "rjbnK4xyyqyq8/V5GAjTSHZSp/kuvvqVu3bLvRW5Yc/evEQhWdgSMGACURcl1L2YPT17QqkXQfJKzC5m", - "X589OfuKjsga6eKc0hy7/64ozMFRDUrCLwsMQb+GOFEy1s7GVMjY/emTJ2Eb/DMxMk+e/9MQQ5tmMY2n", - "wU3ubsQjtKc9jgryJyooy2uptpJ9r7UiBmnqzYbrPUZA21pLw54+ecLE0qd3psQf3Ilp72cUkTv71fU7", - "v3l6HvmJ9X45/yO4aIjiw5HP57yqTBYZkI+2D1b4g60SUXzT+0yaoVeAMrRNzxf9ev5H10T9YWKz8wVW", - "ipjaFKZOf+79/EPb/uLx7/M/gmr5w4FP5z4txaHuI/tG1WbO/yD3aVJVRFOlO3XY/h9256FDja52x3x2", - "8f6PHp+BHd9UJSCLmX34tSHvhkN5Mv8wb34plbquq/gXA1zna+y+y5QWKyEd+W75agU66zGY/x8AAP//", - "+ge3+k7gAAA=", + "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", + "ZUqLlZCOqrd8tQKd9fjO/w8AAP//62VeisflAAA=", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/common/types.go b/api/generated/common/types.go index 3a0e083ca..a7c59f989 100644 --- a/api/generated/common/types.go +++ b/api/generated/common/types.go @@ -1144,6 +1144,9 @@ type TransactionStateProof struct { StateProofType *uint64 `json:"state-proof-type,omitempty"` } +// Absent defines model for absent. +type Absent = []string + // AccountId defines model for account-id. type AccountId = string @@ -1183,6 +1186,9 @@ type Exclude = []string // ExcludeCloseTo defines model for exclude-close-to. type ExcludeCloseTo = bool +// Expired defines model for expired. +type Expired = []string + // HeaderOnly defines model for header-only. type HeaderOnly = bool @@ -1204,6 +1210,9 @@ type Next = string // NotePrefix defines model for note-prefix. type NotePrefix = string +// Proposers defines model for proposers. +type Proposers = []string + // RekeyTo defines model for rekey-to. type RekeyTo = bool @@ -1334,6 +1343,17 @@ type AssetsResponse struct { NextToken *string `json:"next-token,omitempty"` } +// BlockHeadersResponse defines model for BlockHeadersResponse. +type BlockHeadersResponse struct { + Blocks []Block `json:"blocks"` + + // CurrentRound Round at which the results were computed. + CurrentRound uint64 `json:"current-round"` + + // NextToken Used for pagination, when making another request provide this token with the next parameter. + NextToken *string `json:"next-token,omitempty"` +} + // BlockResponse Block information. // // Definition: diff --git a/api/generated/v2/routes.go b/api/generated/v2/routes.go index 6b9f38d0d..ae2f05591 100644 --- a/api/generated/v2/routes.go +++ b/api/generated/v2/routes.go @@ -69,6 +69,9 @@ type ServerInterface interface { // (GET /v2/assets/{asset-id}/transactions) LookupAssetTransactions(ctx echo.Context, assetId uint64, params LookupAssetTransactionsParams) error + // (GET /v2/block-headers) + SearchForBlockHeaders(ctx echo.Context, params SearchForBlockHeadersParams) error + // (GET /v2/blocks/{round-number}) LookupBlock(ctx echo.Context, roundNumber uint64, params LookupBlockParams) error @@ -974,6 +977,80 @@ func (w *ServerInterfaceWrapper) LookupAssetTransactions(ctx echo.Context) error return err } +// SearchForBlockHeaders converts echo context to params. +func (w *ServerInterfaceWrapper) SearchForBlockHeaders(ctx echo.Context) error { + var err error + + // Parameter object where we will unmarshal all parameters from the context + var params SearchForBlockHeadersParams + // ------------- Optional query parameter "limit" ------------- + + err = runtime.BindQueryParameter("form", true, false, "limit", ctx.QueryParams(), ¶ms.Limit) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter limit: %s", err)) + } + + // ------------- Optional query parameter "next" ------------- + + err = runtime.BindQueryParameter("form", true, false, "next", ctx.QueryParams(), ¶ms.Next) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter next: %s", err)) + } + + // ------------- Optional query parameter "min-round" ------------- + + err = runtime.BindQueryParameter("form", true, false, "min-round", ctx.QueryParams(), ¶ms.MinRound) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter min-round: %s", err)) + } + + // ------------- Optional query parameter "max-round" ------------- + + err = runtime.BindQueryParameter("form", true, false, "max-round", ctx.QueryParams(), ¶ms.MaxRound) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter max-round: %s", err)) + } + + // ------------- Optional query parameter "before-time" ------------- + + err = runtime.BindQueryParameter("form", true, false, "before-time", ctx.QueryParams(), ¶ms.BeforeTime) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter before-time: %s", err)) + } + + // ------------- Optional query parameter "after-time" ------------- + + err = runtime.BindQueryParameter("form", true, false, "after-time", ctx.QueryParams(), ¶ms.AfterTime) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter after-time: %s", err)) + } + + // ------------- Optional query parameter "proposers" ------------- + + err = runtime.BindQueryParameter("form", false, false, "proposers", ctx.QueryParams(), ¶ms.Proposers) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter proposers: %s", err)) + } + + // ------------- Optional query parameter "expired" ------------- + + err = runtime.BindQueryParameter("form", false, false, "expired", ctx.QueryParams(), ¶ms.Expired) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter expired: %s", err)) + } + + // ------------- Optional query parameter "absent" ------------- + + err = runtime.BindQueryParameter("form", false, false, "absent", ctx.QueryParams(), ¶ms.Absent) + if err != nil { + return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("Invalid format for parameter absent: %s", err)) + } + + // Invoke the callback with all the unmarshalled arguments + err = w.Handler.SearchForBlockHeaders(ctx, params) + return err +} + // LookupBlock converts echo context to params. func (w *ServerInterfaceWrapper) LookupBlock(ctx echo.Context) error { var err error @@ -1203,6 +1280,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL router.GET(baseURL+"/v2/assets/:asset-id", wrapper.LookupAssetByID, m...) router.GET(baseURL+"/v2/assets/:asset-id/balances", wrapper.LookupAssetBalances, m...) router.GET(baseURL+"/v2/assets/:asset-id/transactions", wrapper.LookupAssetTransactions, m...) + router.GET(baseURL+"/v2/block-headers", wrapper.SearchForBlockHeaders, m...) router.GET(baseURL+"/v2/blocks/:round-number", wrapper.LookupBlock, m...) router.GET(baseURL+"/v2/transactions", wrapper.SearchForTransactions, m...) router.GET(baseURL+"/v2/transactions/:txid", wrapper.LookupTransaction, m...) @@ -1212,229 +1290,234 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "lrsEplHBUCfD7ulxPOC1avkiYIHke/RC2D+7HX2PFvGo89WCm6H57LfJ/UcLnsK/TuFfJ9H0Pr0H4JDP", - "//DXc7/HAFzzMUnObcPx0mRcsfzkK3CnvgJA5sbSwntMKg1TnsjNSZn3abs6dCnm+YyWVORsr0YOWW9t", - "QA3t6/aslxIIisuHDwRmJ0X1k51ko5NsdCpddwpsGhvYdDSm67jcSEw8R0lpr7ngp2ydqVdv1jwNJ5Ht", - "z8SAHJLqomWeAF2so0+78l1glgv7pGLmi50y3ynbxSnbxSnbxSnbxSnbxcexRp/yUpzyUpzEt3/vvBRj", - "PE6cEdMCKgVDV+ZWY3z+B7mQu3ZC6S3qmVzNuGCNAORX0BQLNdIeFDRaUhPeYd/QSKKDl8GedWVKlgPv", - "KzjhgFCcM34N/50rxn5nmaHKMtdj3tvWajyAUBozmj+ujXnQ2ixTjAo34vOBaFdGVa0gDa0JuWoJJX4l", - "U8snb2VN1nBZSn4F/V1dTbvpKyjI2qnRaiQxqh40TrvuGcCzN/PI9D4MQKckKqckKqckKn8CbcislPmV", - "Pv8DjjpDPcJeIzZ0GlJiPLUf9yku8DLidOm0UDFAtyRqPzBaMEWkffTnJV2ckX/Yywm3D1xLjafQ00Zn", - "A2skhWSoC3EKgC4PoAfo3xKmzOyUd0sCd0arwEmcAsM/4+s5SjUZeYaOzcDb1Uh6dj3NNnIN7HiXaQ9i", - "4mG5fYOX6knTedJ0njSdJ03nSdN5yut70p+e9Kcn/elJf3rSn570p3euP/2YOs+7rxV60qqetKontc1H", - "DQuKj/b8DysT7Q8MIlZ8LFsv5JCKNca6MdFBTii7vxxq90hCou066LKOv5ynGJoTeflUtMIfphPN1LW/", - "67UqJxeTpTGVvjg/Zxu6qkp2lsvVOSSpcP3/CHy/XK3goQq/uJGjXxwps903mVTcvr1lptd0sWAqszMj", - "zI/PHk0+/J8AAAD//3BbS4jifQEA", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/v2/types.go b/api/generated/v2/types.go index 36d8da56d..4916b726c 100644 --- a/api/generated/v2/types.go +++ b/api/generated/v2/types.go @@ -1232,6 +1232,9 @@ type TransactionStateProof struct { StateProofType *uint64 `json:"state-proof-type,omitempty"` } +// Absent defines model for absent. +type Absent = []string + // AccountId defines model for account-id. type AccountId = string @@ -1271,6 +1274,9 @@ type Exclude = []string // ExcludeCloseTo defines model for exclude-close-to. type ExcludeCloseTo = bool +// Expired defines model for expired. +type Expired = []string + // HeaderOnly defines model for header-only. type HeaderOnly = bool @@ -1292,6 +1298,9 @@ type Next = string // NotePrefix defines model for note-prefix. type NotePrefix = string +// Proposers defines model for proposers. +type Proposers = []string + // RekeyTo defines model for rekey-to. type RekeyTo = bool @@ -1422,6 +1431,17 @@ type AssetsResponse struct { NextToken *string `json:"next-token,omitempty"` } +// BlockHeadersResponse defines model for BlockHeadersResponse. +type BlockHeadersResponse struct { + Blocks []Block `json:"blocks"` + + // CurrentRound Round at which the results were computed. + CurrentRound uint64 `json:"current-round"` + + // NextToken Used for pagination, when making another request provide this token with the next parameter. + NextToken *string `json:"next-token,omitempty"` +} + // BlockResponse Block information. // // Definition: @@ -1811,6 +1831,36 @@ type LookupAssetTransactionsParamsSigType string // LookupAssetTransactionsParamsAddressRole defines parameters for LookupAssetTransactions. type LookupAssetTransactionsParamsAddressRole string +// SearchForBlockHeadersParams defines parameters for SearchForBlockHeaders. +type SearchForBlockHeadersParams struct { + // Limit Maximum number of results to return. There could be additional pages even if the limit is not reached. + Limit *uint64 `form:"limit,omitempty" json:"limit,omitempty"` + + // Next The next page of results. Use the next token provided by the previous results. + Next *string `form:"next,omitempty" json:"next,omitempty"` + + // MinRound Include results at or after the specified min-round. + MinRound *uint64 `form:"min-round,omitempty" json:"min-round,omitempty"` + + // MaxRound Include results at or before the specified max-round. + MaxRound *uint64 `form:"max-round,omitempty" json:"max-round,omitempty"` + + // BeforeTime Include results before the given time. Must be an RFC 3339 formatted string. + BeforeTime *time.Time `form:"before-time,omitempty" json:"before-time,omitempty"` + + // AfterTime Include results after the given time. Must be an RFC 3339 formatted string. + AfterTime *time.Time `form:"after-time,omitempty" json:"after-time,omitempty"` + + // Proposers Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses. + Proposers *[]string `form:"proposers,omitempty" json:"proposers,omitempty"` + + // Expired Accounts marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses. + Expired *[]string `form:"expired,omitempty" json:"expired,omitempty"` + + // Absent Accounts marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses. + Absent *[]string `form:"absent,omitempty" json:"absent,omitempty"` +} + // LookupBlockParams defines parameters for LookupBlock. type LookupBlockParams struct { // HeaderOnly Header only flag. When this is set to true, returned block does not contain the transactions diff --git a/api/handlers.go b/api/handlers.go index 76d40f9c0..6449c3d69 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -45,6 +45,27 @@ type ServerImplementation struct { // Helper functions // ////////////////////// +func validateBlockFilter(filter *idb.BlockHeaderFilter) error { + var errorArr = make([]string, 0) + + // Int64 overflows + if (filter.MaxRound != nil && *filter.MaxRound > math.MaxInt64) || + (filter.MinRound != nil && *filter.MinRound > math.MaxInt64) { + errorArr = append(errorArr, errValueExceedingInt64) + } + + // Time + if !filter.AfterTime.IsZero() && !filter.BeforeTime.IsZero() && filter.AfterTime.After(filter.BeforeTime) { + errorArr = append(errorArr, errInvalidTimeMinMax) + } + + if len(errorArr) > 0 { + return errors.New("invalid input: " + strings.Join(errorArr, ", ")) + } + + return nil +} + func validateTransactionFilter(filter *idb.TransactionFilter) error { var errorArr = make([]string, 0) @@ -193,9 +214,9 @@ func (si *ServerImplementation) LookupAccountByID(ctx echo.Context, accountID st return badRequest(ctx, errRewindingAccountNotSupported) } - addr, decodeErrors := decodeAddress(&accountID, "account-id", make([]string, 0)) - if len(decodeErrors) != 0 { - return badRequest(ctx, decodeErrors[0]) + addr, err := sdk.DecodeAddress(accountID) + if err != nil { + return badRequest(ctx, fmt.Sprintf("%s: %v", errUnableToParseAddress, err)) } options := idb.AccountQueryOptions{ @@ -293,9 +314,9 @@ func (si *ServerImplementation) LookupAccountAssets(ctx echo.Context, accountID return notFound(ctx, errValueExceedingInt64) } - addr, errors := decodeAddress(&accountID, "account-id", make([]string, 0)) - if len(errors) != 0 { - return badRequest(ctx, errors[0]) + addr, err := sdk.DecodeAddress(accountID) + if err != nil { + return badRequest(ctx, fmt.Sprintf("%s: %v", errUnableToParseAddress, err)) } var assetGreaterThan *uint64 @@ -308,7 +329,7 @@ func (si *ServerImplementation) LookupAccountAssets(ctx echo.Context, accountID } query := idb.AssetBalanceQuery{ - Address: addr, + Address: addr[:], AssetID: params.AssetId, AssetIDGT: assetGreaterThan, IncludeDeleted: boolOrDefault(params.IncludeAll), @@ -387,9 +408,13 @@ func (si *ServerImplementation) SearchForAccounts(ctx echo.Context, params gener return badRequest(ctx, errRewindingAccountNotSupported) } - spendingAddr, decodeErrors := decodeAddress(params.AuthAddr, "account-id", make([]string, 0)) - if len(decodeErrors) != 0 { - return badRequest(ctx, decodeErrors[0]) + var spendingAddrBytes []byte + if params.AuthAddr != nil { + spendingAddr, err := sdk.DecodeAddress(*params.AuthAddr) + if err != nil { + return badRequest(ctx, fmt.Sprintf("unable to parse auth addr: %v", err)) + } + spendingAddrBytes = spendingAddr[:] } options := idb.AccountQueryOptions{ @@ -400,7 +425,7 @@ func (si *ServerImplementation) SearchForAccounts(ctx echo.Context, params gener Limit: min(uintOrDefaultValue(params.Limit, si.opts.DefaultAccountsLimit), si.opts.MaxAccountsLimit), HasAssetID: uintOrDefault(params.AssetId), HasAppID: uintOrDefault(params.ApplicationId), - EqualToAuthAddr: spendingAddr[:], + EqualToAuthAddr: spendingAddrBytes, IncludeDeleted: boolOrDefault(params.IncludeAll), MaxResources: si.opts.MaxAPIResourcesPerAccount, } @@ -465,10 +490,11 @@ func (si *ServerImplementation) LookupAccountTransactions(ctx echo.Context, acco if (params.AssetId != nil && uint64(*params.AssetId) > math.MaxInt64) || (params.Round != nil && uint64(*params.Round) > math.MaxInt64) { return notFound(ctx, errValueExceedingInt64) } + // Check that a valid account was provided - _, errors := decodeAddress(strPtr(accountID), "account-id", make([]string, 0)) - if len(errors) != 0 { - return badRequest(ctx, errors[0]) + _, err := sdk.DecodeAddress(accountID) + if err != nil { + return badRequest(ctx, fmt.Sprintf("%s: %v", errUnableToParseAddress, err)) } searchParams := generated.SearchForTransactionsParams{ @@ -981,6 +1007,79 @@ func (si *ServerImplementation) LookupTransaction(ctx echo.Context, txid string) return ctx.JSON(http.StatusOK, response) } +// SearchForBlockHeaders returns block headers matching the provided parameters +// (GET /v2/blocks) +func (si *ServerImplementation) SearchForBlockHeaders(ctx echo.Context, params generated.SearchForBlockHeadersParams) error { + // Validate query parameters + if err := si.verifyHandler("SearchForBlockHeaders", ctx); err != nil { + return badRequest(ctx, err.Error()) + } + + // Convert query params into a filter + filter, err := si.blockParamsToBlockFilter(params) + if err != nil { + return badRequest(ctx, err.Error()) + } + err = validateBlockFilter(&filter) + if err != nil { + return badRequest(ctx, err.Error()) + } + + // Fetch the block headers + blockHeaders, next, round, err := si.fetchBlockHeaders(ctx.Request().Context(), filter) + if err != nil { + return indexerError(ctx, fmt.Errorf("%s: %w", errBlockHeaderSearch, err)) + } + + // Populate the response model and render it + response := generated.BlockHeadersResponse{ + CurrentRound: round, + NextToken: strPtr(next), + Blocks: blockHeaders, + } + return ctx.JSON(http.StatusOK, response) +} + +// fetchBlockHeaders is used to query the backend for block headers, and compute the next token +func (si *ServerImplementation) fetchBlockHeaders(ctx context.Context, bf idb.BlockHeaderFilter) ([]generated.Block, string, uint64 /*round*/, error) { + + var round uint64 + var nextToken string + results := make([]generated.Block, 0) + err := callWithTimeout(ctx, si.log, si.timeout, func(ctx context.Context) error { + + // Open a channel from which result rows will be received + var rows <-chan idb.BlockRow + rows, round = si.db.BlockHeaders(ctx, bf) + + // Iterate received rows, converting each to a generated.Block + var lastRow idb.BlockRow + for row := range rows { + if row.Error != nil { + return row.Error + } + + results = append(results, hdrRowToBlock(row)) + lastRow = row + } + + // No next token if there were no results. + if len(results) == 0 { + return nil + } + + // Generate the next token and return + var err error + nextToken, err = lastRow.Next() + return err + }) + if err != nil { + return nil, "", 0, err + } + + return results, nextToken, round, nil +} + // SearchForTransactions returns transactions matching the provided parameters // (GET /v2/transactions) func (si *ServerImplementation) SearchForTransactions(ctx echo.Context, params generated.SearchForTransactionsParams) error { diff --git a/api/handlers_test.go b/api/handlers_test.go index a64aa31e0..c18323513 100644 --- a/api/handlers_test.go +++ b/api/handlers_test.go @@ -846,7 +846,7 @@ func TestTimeouts(t *testing.T) { errString: errTransactionSearch, mockCall: transactionFunc, callHandler: func(ctx echo.Context, si ServerImplementation) error { - return si.LookupAccountTransactions(ctx, "", generated.LookupAccountTransactionsParams{}) + return si.LookupAccountTransactions(ctx, "MONEYMBRSMUAM2NGL6PCEQEDVHFWAQB6DU47NUS6P5DJM4OJFN7E7DSVBA", generated.LookupAccountTransactionsParams{}) }, }, { diff --git a/api/indexer.oas2.json b/api/indexer.oas2.json index 76c11d21d..08061df94 100644 --- a/api/indexer.oas2.json +++ b/api/indexer.oas2.json @@ -853,6 +853,61 @@ } } }, + "/v2/block-headers": { + "get": { + "description": "Search for block headers. Block headers are returned in ascending round order. Transactions are not included in the output.", + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "search" + ], + "operationId": "searchForBlockHeaders", + "parameters": [ + { + "$ref": "#/parameters/limit" + }, + { + "$ref": "#/parameters/next" + }, + { + "$ref": "#/parameters/min-round" + }, + { + "$ref": "#/parameters/max-round" + }, + { + "$ref": "#/parameters/before-time" + }, + { + "$ref": "#/parameters/after-time" + }, + { + "$ref": "#/parameters/proposers" + }, + { + "$ref": "#/parameters/expired" + }, + { + "$ref": "#/parameters/absent" + } + ], + "responses": { + "200": { + "$ref": "#/responses/BlockHeadersResponse" + }, + "404": { + "$ref": "#/responses/ErrorResponse" + }, + "500": { + "$ref": "#/responses/ErrorResponse" + } + } + } + }, "/v2/blocks/{round-number}": { "get": { "description": "Lookup block.", @@ -1753,7 +1808,7 @@ "Box": { "description": "Box name and its content.", "required": [ - "name", + "name", "value", "round" ], @@ -2595,10 +2650,10 @@ "StateProofParticipant": { "type": "object", "properties": { - "verifier": { - "description": "\\[p\\]", - "$ref": "#/definitions/StateProofVerifier" - }, + "verifier": { + "description": "\\[p\\]", + "$ref": "#/definitions/StateProofVerifier" + }, "weight": { "description": "\\[w\\]", "type": "integer", @@ -2677,6 +2732,39 @@ } }, "parameters": { + "proposers": { + "type": "array", + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "description": "Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "name": "proposers", + "in": "query", + "required": false + }, + "absent": { + "type": "array", + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "description": "Accounts marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "name": "absent", + "in": "query", + "required": false + }, + "expired": { + "type": "array", + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "description": "Accounts marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "name": "expired", + "in": "query", + "required": false + }, "account-id": { "type": "string", "description": "account string", @@ -3103,7 +3191,7 @@ "schema": { "type": "object", "required": [ - "application-id", + "application-id", "boxes" ], "properties": { @@ -3132,7 +3220,7 @@ }, "ErrorResponse": { "description": "Response for errors", - "schema":{ + "schema": { "type": "object", "required": [ "message" @@ -3179,6 +3267,32 @@ "$ref": "#/definitions/Block" } }, + "BlockHeadersResponse": { + "description": "(empty)", + "schema": { + "type": "object", + "required": [ + "current-round", + "blocks" + ], + "properties": { + "current-round": { + "description": "Round at which the results were computed.", + "type": "integer" + }, + "next-token": { + "description": "Used for pagination, when making another request provide this token with the next parameter.", + "type": "string" + }, + "blocks": { + "type": "array", + "items": { + "$ref": "#/definitions/Block" + } + } + } + } + }, "HealthCheckResponse": { "description": "(empty)", "schema": { @@ -3242,4 +3356,4 @@ "name": "search" } ] -} +} \ No newline at end of file diff --git a/api/indexer.oas3.yml b/api/indexer.oas3.yml index 9a425b354..0e2c96185 100644 --- a/api/indexer.oas3.yml +++ b/api/indexer.oas3.yml @@ -1,6 +1,20 @@ { "components": { "parameters": { + "absent": { + "description": "Accounts marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "absent", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, "account-id": { "description": "account string", "in": "path", @@ -135,6 +149,20 @@ "type": "boolean" } }, + "expired": { + "description": "Accounts marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "expired", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, "header-only": { "description": "Header only flag. When this is set to true, returned block does not contain the transactions", "in": "query", @@ -193,6 +221,20 @@ }, "x-algorand-format": "base64" }, + "proposers": { + "description": "Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "proposers", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, "rekey-to": { "description": "Include results which include the rekey-to field.", "in": "query", @@ -549,6 +591,36 @@ }, "description": "(empty)" }, + "BlockHeadersResponse": { + "content": { + "application/json": { + "schema": { + "properties": { + "blocks": { + "items": { + "$ref": "#/components/schemas/Block" + }, + "type": "array" + }, + "current-round": { + "description": "Round at which the results were computed.", + "type": "integer" + }, + "next-token": { + "description": "Used for pagination, when making another request provide this token with the next parameter.", + "type": "string" + } + }, + "required": [ + "blocks", + "current-round" + ], + "type": "object" + } + } + }, + "description": "(empty)" + }, "BlockResponse": { "content": { "application/json": { @@ -4763,6 +4835,189 @@ ] } }, + "/v2/block-headers": { + "get": { + "description": "Search for block headers. Block headers are returned in ascending round order. Transactions are not included in the output.", + "operationId": "searchForBlockHeaders", + "parameters": [ + { + "description": "Maximum number of results to return. There could be additional pages even if the limit is not reached.", + "in": "query", + "name": "limit", + "schema": { + "type": "integer" + } + }, + { + "description": "The next page of results. Use the next token provided by the previous results.", + "in": "query", + "name": "next", + "schema": { + "type": "string" + } + }, + { + "description": "Include results at or after the specified min-round.", + "in": "query", + "name": "min-round", + "schema": { + "type": "integer" + } + }, + { + "description": "Include results at or before the specified max-round.", + "in": "query", + "name": "max-round", + "schema": { + "type": "integer" + } + }, + { + "description": "Include results before the given time. Must be an RFC 3339 formatted string.", + "in": "query", + "name": "before-time", + "schema": { + "format": "date-time", + "type": "string", + "x-algorand-format": "RFC3339 String" + }, + "x-algorand-format": "RFC3339 String" + }, + { + "description": "Include results after the given time. Must be an RFC 3339 formatted string.", + "in": "query", + "name": "after-time", + "schema": { + "format": "date-time", + "type": "string", + "x-algorand-format": "RFC3339 String" + }, + "x-algorand-format": "RFC3339 String" + }, + { + "description": "Accounts marked as proposer in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "proposers", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, + { + "description": "Accounts marked as expired in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "expired", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + }, + { + "description": "Accounts marked as absent in the block header's participation updates. This parameter accepts a comma separated list of addresses.", + "explode": false, + "in": "query", + "name": "absent", + "schema": { + "items": { + "type": "string", + "x-algorand-format": "Address" + }, + "type": "array" + }, + "style": "form" + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "properties": { + "blocks": { + "items": { + "$ref": "#/components/schemas/Block" + }, + "type": "array" + }, + "current-round": { + "description": "Round at which the results were computed.", + "type": "integer" + }, + "next-token": { + "description": "Used for pagination, when making another request provide this token with the next parameter.", + "type": "string" + } + }, + "required": [ + "blocks", + "current-round" + ], + "type": "object" + } + } + }, + "description": "(empty)" + }, + "404": { + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "properties": {}, + "type": "object" + }, + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + } + }, + "description": "Response for errors" + }, + "500": { + "content": { + "application/json": { + "schema": { + "properties": { + "data": { + "properties": {}, + "type": "object" + }, + "message": { + "type": "string" + } + }, + "required": [ + "message" + ], + "type": "object" + } + } + }, + "description": "Response for errors" + } + }, + "tags": [ + "search" + ] + } + }, "/v2/blocks/{round-number}": { "get": { "description": "Lookup block.", diff --git a/api/server.go b/api/server.go index c8f21531e..aadd58420 100644 --- a/api/server.go +++ b/api/server.go @@ -47,10 +47,20 @@ type ExtraOptions struct { // If an address exceeds this number, a 400 error is returned. Zero means unlimited. MaxAPIResourcesPerAccount uint64 + // MaxAccountListSize is the maximum number of items that can be passed in query parameter account lists. + // (e.g.: GET /v2/block-headers?proposer=A,B,C) + // + // Zero means unlimited. + MaxAccountListSize uint64 + ///////////////////// // Limit Constants // ///////////////////// + // Blocks + MaxBlocksLimit uint64 + DefaultBlocksLimit uint64 + // Transactions MaxTransactionsLimit uint64 DefaultTransactionsLimit uint64 diff --git a/cmd/algorand-indexer/daemon.go b/cmd/algorand-indexer/daemon.go index 421bfd4fb..213f21892 100644 --- a/cmd/algorand-indexer/daemon.go +++ b/cmd/algorand-indexer/daemon.go @@ -33,6 +33,9 @@ type daemonConfig struct { readTimeout time.Duration maxConn uint32 maxAPIResourcesPerAccount uint32 + maxAccountListSize uint32 + maxBlocksLimit uint32 + defaultBlocksLimit uint32 maxTransactionsLimit uint32 defaultTransactionsLimit uint32 maxAccountsLimit uint32 @@ -81,6 +84,9 @@ func DaemonCmd() *cobra.Command { cfg.flags.StringVar(&cfg.suppliedAPIConfigFile, "api-config-file", "", "supply an API config file to enable/disable parameters") cfg.flags.BoolVar(&cfg.enableAllParameters, "enable-all-parameters", false, "override default configuration and enable all parameters. Can't be used with --api-config-file") cfg.flags.Uint32VarP(&cfg.maxAPIResourcesPerAccount, "max-api-resources-per-account", "", 1000, "set the maximum total number of resources (created assets, created apps, asset holdings, and application local state) per account that will be allowed in REST API lookupAccountByID and searchForAccounts responses before returning a 400 Bad Request. Set zero for no limit") + cfg.flags.Uint32VarP(&cfg.maxAccountListSize, "max-account-list-size", "", 50, "set the maximum number of items for query parameters that accept account lists. Set zero for no limit") + cfg.flags.Uint32VarP(&cfg.maxBlocksLimit, "max-blocks-limit", "", 1000, "set the maximum allowed Limit parameter for querying blocks") + cfg.flags.Uint32VarP(&cfg.defaultBlocksLimit, "default-blocks-limit", "", 100, "set the default Limit parameter for querying blocks, if none is provided") cfg.flags.Uint32VarP(&cfg.maxTransactionsLimit, "max-transactions-limit", "", 10000, "set the maximum allowed Limit parameter for querying transactions") cfg.flags.Uint32VarP(&cfg.defaultTransactionsLimit, "default-transactions-limit", "", 1000, "set the default Limit parameter for querying transactions, if none is provided") cfg.flags.Uint32VarP(&cfg.maxAccountsLimit, "max-accounts-limit", "", 1000, "set the maximum allowed Limit parameter for querying accounts") @@ -322,6 +328,9 @@ func makeOptions(daemonConfig *daemonConfig) (options api.ExtraOptions) { options.ReadTimeout = daemonConfig.readTimeout options.MaxAPIResourcesPerAccount = uint64(daemonConfig.maxAPIResourcesPerAccount) + options.MaxAccountListSize = uint64(daemonConfig.maxAccountListSize) + options.MaxBlocksLimit = uint64(daemonConfig.maxBlocksLimit) + options.DefaultBlocksLimit = uint64(daemonConfig.defaultBlocksLimit) options.MaxTransactionsLimit = uint64(daemonConfig.maxTransactionsLimit) options.DefaultTransactionsLimit = uint64(daemonConfig.defaultTransactionsLimit) options.MaxAccountsLimit = uint64(daemonConfig.maxAccountsLimit) diff --git a/idb/dummy/dummy.go b/idb/dummy/dummy.go index 19e276e8b..459e9d8db 100644 --- a/idb/dummy/dummy.go +++ b/idb/dummy/dummy.go @@ -53,6 +53,11 @@ func (db *dummyIndexerDb) GetBlock(ctx context.Context, round uint64, options id return sdk.BlockHeader{}, nil, nil } +// Blocks is part of idb.IndexerDB +func (db *dummyIndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockHeaderFilter) (<-chan idb.BlockRow, uint64) { + return nil, 0 +} + // Transactions is part of idb.IndexerDB func (db *dummyIndexerDb) Transactions(ctx context.Context, tf idb.TransactionFilter) (<-chan idb.TxnRow, uint64) { return nil, 0 diff --git a/idb/idb.go b/idb/idb.go index a4c58c948..3381045ac 100644 --- a/idb/idb.go +++ b/idb/idb.go @@ -15,6 +15,23 @@ import ( sdk "github.com/algorand/go-algorand-sdk/v2/types" ) +// BlockRow is metadata relating to one block in a block query. +type BlockRow struct { + BlockHeader sdk.BlockHeader + + // Error indicates that there was an internal problem processing the expected block. + Error error +} + +// Next returns what should be an opaque string to be used with the next query to resume where a previous limit left off. +func (br BlockRow) Next() (string, error) { + + var b [8]byte + binary.LittleEndian.PutUint64(b[:8], uint64(br.BlockHeader.Round)) + + return base64.URLEncoding.EncodeToString(b[:]), nil +} + // TxnRow is metadata relating to one transaction in a transaction query. type TxnRow struct { // Round is the round where the transaction was committed. @@ -99,6 +116,21 @@ func DecodeTxnRowNext(s string) (uint64 /*round*/, uint32 /*intra*/, error) { return round, intra, nil } +// DecodeBlockRowNext unpacks opaque string returned from BlockRow.Next() +func DecodeBlockRowNext(s string) (uint64 /*round*/, error) { + b, err := base64.URLEncoding.DecodeString(s) + if err != nil { + return 0, fmt.Errorf("DecodeBlockRowNext() decode err: %w", err) + } + + if len(b) != 8 { + return 0, fmt.Errorf("DecodeBlockRowNext() bad next token b: %x", b) + } + + round := binary.LittleEndian.Uint64(b[:8]) + return round, nil +} + // OptionalUint wraps bool and uint. It has a custom marshaller below. type OptionalUint struct { Present bool @@ -173,6 +205,7 @@ type IndexerDb interface { // The next multiple functions return a channel with results as well as the latest round // accounted. + BlockHeaders(ctx context.Context, bf BlockHeaderFilter) (<-chan BlockRow, uint64) Transactions(ctx context.Context, tf TransactionFilter) (<-chan TxnRow, uint64) GetAccounts(ctx context.Context, opts AccountQueryOptions) (<-chan AccountRow, uint64) Assets(ctx context.Context, filter AssetsQuery) (<-chan AssetRow, uint64) @@ -195,6 +228,18 @@ type GetBlockOptions struct { MaxTransactionsLimit uint64 } +// BlockHeaderFilter is a parameter object with all the block filter options. +type BlockHeaderFilter struct { + Limit uint64 + MaxRound *uint64 + MinRound *uint64 + AfterTime time.Time + BeforeTime time.Time + Proposers map[sdk.Address]struct{} + ExpiredParticipationAccounts map[sdk.Address]struct{} + AbsentParticipationAccounts map[sdk.Address]struct{} +} + // TransactionFilter is a parameter object with all the transaction filter options. type TransactionFilter struct { // SkipOptimization is used for testing to ensure the parameters are not modified. diff --git a/idb/mocks/IndexerDb.go b/idb/mocks/IndexerDb.go index 15b508e10..f7b03c408 100644 --- a/idb/mocks/IndexerDb.go +++ b/idb/mocks/IndexerDb.go @@ -186,6 +186,36 @@ func (_m *IndexerDb) Assets(ctx context.Context, filter idb.AssetsQuery) (<-chan return r0, r1 } +// BlockHeaders provides a mock function with given fields: ctx, bf +func (_m *IndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockHeaderFilter) (<-chan idb.BlockRow, uint64) { + ret := _m.Called(ctx, bf) + + if len(ret) == 0 { + panic("no return value specified for BlockHeaders") + } + + var r0 <-chan idb.BlockRow + var r1 uint64 + if rf, ok := ret.Get(0).(func(context.Context, idb.BlockHeaderFilter) (<-chan idb.BlockRow, uint64)); ok { + return rf(ctx, bf) + } + if rf, ok := ret.Get(0).(func(context.Context, idb.BlockHeaderFilter) <-chan idb.BlockRow); ok { + r0 = rf(ctx, bf) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan idb.BlockRow) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, idb.BlockHeaderFilter) uint64); ok { + r1 = rf(ctx, bf) + } else { + r1 = ret.Get(1).(uint64) + } + + return r0, r1 +} + // Close provides a mock function with given fields: func (_m *IndexerDb) Close() { _m.Called() diff --git a/idb/postgres/postgres.go b/idb/postgres/postgres.go index 1a6850ccb..7e41128eb 100644 --- a/idb/postgres/postgres.go +++ b/idb/postgres/postgres.go @@ -949,6 +949,185 @@ finish: } } +func buildBlockHeadersQuery(bf idb.BlockHeaderFilter) (query string, err error) { + + // Build the terms for the WHERE clause based on the input parameters + var whereTerms []string + { + // Round-based filters + if bf.MaxRound != nil { + whereTerms = append( + whereTerms, + fmt.Sprintf("bh.round <= %d", *bf.MaxRound), + ) + } + if bf.MinRound != nil { + whereTerms = append( + whereTerms, + fmt.Sprintf("bh.round >= %d", *bf.MinRound), + ) + } + + // Timestamp-based filters + // + // Converting the timestamp into a round usually results in faster execution plans + // (compared to the execution plans that would result from using the `block_header.realtime` column directly) + if !bf.AfterTime.IsZero() { + tmpl := `bh.round >= ( + SELECT tmp.round + FROM block_header tmp + WHERE tmp.realtime > (to_timestamp(%d) AT TIME ZONE 'UTC') + ORDER BY tmp.realtime ASC, tmp.round ASC + LIMIT 1 + )` + whereTerms = append( + whereTerms, + fmt.Sprintf(tmpl, bf.AfterTime.UTC().Unix()), + ) + } + if !bf.BeforeTime.IsZero() { + tmpl := `bh.round <= ( + SELECT tmp.round + FROM block_header tmp + WHERE tmp.realtime < (to_timestamp(%d) AT TIME ZONE 'UTC') + ORDER BY tmp.realtime DESC, tmp.round DESC + LIMIT 1 + )` + whereTerms = append( + whereTerms, + fmt.Sprintf(tmpl, bf.BeforeTime.UTC().Unix()), + ) + } + + // Participation-based filters + if len(bf.Proposers) > 0 { + var ps []string + for addr := range bf.Proposers { + ps = append(ps, `'"`+addr.String()+`"'`) + } + whereTerms = append( + whereTerms, + fmt.Sprintf("( (bh.header->'prp') IS NOT NULL AND ((bh.header->'prp')::TEXT IN (%s)) )", strings.Join(ps, ",")), + ) + } + if len(bf.ExpiredParticipationAccounts) > 0 { + var es []string + for addr := range bf.ExpiredParticipationAccounts { + es = append(es, `'`+addr.String()+`'`) + } + whereTerms = append( + whereTerms, + fmt.Sprintf("( (bh.header->'partupdrmv') IS NOT NULL AND (bh.header->'partupdrmv') ?| array[%s] )", strings.Join(es, ",")), + ) + } + if len(bf.AbsentParticipationAccounts) > 0 { + var as []string + for addr := range bf.AbsentParticipationAccounts { + as = append(as, `'`+addr.String()+`'`) + } + whereTerms = append( + whereTerms, + fmt.Sprintf("( (bh.header->'partupdabs') IS NOT NULL AND (bh.header->'partupdabs') ?| array[%s] )", strings.Join(as, ",")), + ) + } + + } + + // Build the full SQL query + var whereClause string + if len(whereTerms) > 0 { + whereClause = "WHERE " + strings.Join(whereTerms, " AND ") + } + tmpl := ` + SELECT bh.header + FROM block_header bh + %s + ORDER BY bh.round ASC + LIMIT %d` + query = fmt.Sprintf(tmpl, whereClause, bf.Limit) + + return query, nil +} + +// This function blocks. `tx` must be non-nil. +func (db *IndexerDb) yieldBlockHeaders(ctx context.Context, tx pgx.Tx, bf idb.BlockHeaderFilter, out chan<- idb.BlockRow) { + + query, err := buildBlockHeadersQuery(bf) + if err != nil { + err = fmt.Errorf("block query err %v", err) + out <- idb.BlockRow{Error: err} + return + } + + rows, err := tx.Query(ctx, query) + if err != nil { + err = fmt.Errorf("block query %#v err %v", query, err) + out <- idb.BlockRow{Error: err} + return + } + db.yieldBlocksThreadSimple(rows, out) +} + +// BlockHeaders is part of idb.IndexerDB +func (db *IndexerDb) BlockHeaders(ctx context.Context, bf idb.BlockHeaderFilter) (<-chan idb.BlockRow, uint64) { + out := make(chan idb.BlockRow, 1) + + tx, err := db.db.BeginTx(ctx, readonlyRepeatableRead) + if err != nil { + out <- idb.BlockRow{Error: err} + close(out) + return out, 0 + } + + round, err := db.getMaxRoundAccounted(ctx, tx) + if err != nil { + out <- idb.BlockRow{Error: err} + close(out) + if rerr := tx.Rollback(ctx); rerr != nil { + db.log.Printf("rollback error: %s", rerr) + } + return out, round + } + + go func() { + db.yieldBlockHeaders(ctx, tx, bf, out) + // Because we return a channel into a "callWithTimeout" function, + // We need to make sure that rollback is called before close() + // otherwise we can end up with a situation where "callWithTimeout" + // will cancel our context, resulting in connection pool churn + if rerr := tx.Rollback(ctx); rerr != nil { + db.log.Printf("rollback error: %s", rerr) + } + close(out) + }() + + return out, round +} + +func (db *IndexerDb) yieldBlocksThreadSimple(rows pgx.Rows, results chan<- idb.BlockRow) { + defer rows.Close() + + for rows.Next() { + var row idb.BlockRow + + var blockheaderjson []byte + err := rows.Scan(&blockheaderjson) + if err != nil { + row.Error = err + } else { + row.BlockHeader, err = encoding.DecodeBlockHeader(blockheaderjson) + if err != nil { + row.Error = fmt.Errorf("failed to decode block header: %w", err) + } + } + + results <- row + } + if err := rows.Err(); err != nil { + results <- idb.BlockRow{Error: err} + } +} + var statusStrings = []string{"Offline", "Online", "NotParticipating"} const offlineStatusIdx = 0 From c5c7b4ea0f4e87a86fb1231701d55cfbe7ef75b7 Mon Sep 17 00:00:00 2001 From: Gary Malouf <982483+gmalouf@users.noreply.github.com> Date: Fri, 20 Dec 2024 16:30:55 -0500 Subject: [PATCH 09/13] Incentives: Storing/ serving heartbeat transactions, synthetic transactions for payouts (#1635) * Add support for storing and serving heartbeat transaction types * Support generating synthetic payout transaction based off Payout being set in block header. * Introduce transaction fetch API test case for heartbeats. --- api/README.md | 2 +- api/converter_utils.go | 26 +- api/generate.sh | 18 - api/generated/common/routes.go | 377 +++++++------- api/generated/common/types.go | 49 ++ api/generated/v2/routes.go | 463 +++++++++--------- api/generated/v2/types.go | 52 ++ api/handlers_test.go | 13 +- api/indexer.oas2.json | 80 ++- api/indexer.oas3.yml | 93 +++- api/test_resources/heartbeat.response | 2 + api/test_resources/heartbeat.txn | Bin 0 -> 502 bytes e2e_tests/docker/indexer/Dockerfile | 2 +- go.mod | 2 +- go.sum | 4 +- idb/postgres/internal/writer/write_txn.go | 51 +- .../writer/write_txn_participation.go | 8 + idb/postgres/internal/writer/writer_test.go | 252 +++++++++- idb/postgres/postgres.go | 3 +- idb/txn_type_enum.go | 2 + 20 files changed, 1041 insertions(+), 458 deletions(-) delete mode 100755 api/generate.sh create mode 100644 api/test_resources/heartbeat.response create mode 100644 api/test_resources/heartbeat.txn diff --git a/api/README.md b/api/README.md index 3e2f2f2db..23c35b22f 100644 --- a/api/README.md +++ b/api/README.md @@ -9,7 +9,7 @@ The API is defined using [OpenAPI v2](https://swagger.io/specification/v2/) in * The Makefile will install our fork of **oapi-codegen**, use `make oapi-codegen` to install it directly. 1. Document your changes by editing **indexer.oas2.yml** -2. Regenerate the endpoints by running **generate.sh**. The sources at **generated/** will be updated. +2. Regenerate the endpoints by running **make generate** from the `api` directory. The sources at **generated/** will be updated. 3. Update the implementation in **handlers.go**. It is sometimes useful to consult **generated/routes.go** to make sure the handler properly implements **ServerInterface**. ## What codegen tool is used? diff --git a/api/converter_utils.go b/api/converter_utils.go index 8a854c231..971ec78d7 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -382,6 +382,7 @@ func signedTxnWithAdToTransaction(stxn *sdk.SignedTxnWithAD, extra rowData) (gen var assetTransfer *generated.TransactionAssetTransfer var application *generated.TransactionApplication var stateProof *generated.TransactionStateProof + var heartbeat *generated.TransactionHeartbeat switch stxn.Txn.Type { case sdk.PaymentTx: @@ -585,6 +586,22 @@ func signedTxnWithAdToTransaction(stxn *sdk.SignedTxnWithAD, extra rowData) (gen StateProofType: uint64Ptr(uint64(stxn.Txn.StateProofType)), } stateProof = &proofTxn + case sdk.HeartbeatTx: + hb := stxn.Txn.HeartbeatTxnFields + hbTxn := generated.TransactionHeartbeat{ + HbAddress: hb.HbAddress.String(), + HbKeyDilution: hb.HbKeyDilution, + HbProof: generated.HbProofFields{ + HbPk: byteSliceOmitZeroPtr(hb.HbProof.PK[:]), + HbPk1sig: byteSliceOmitZeroPtr(hb.HbProof.PK1Sig[:]), + HbPk2: byteSliceOmitZeroPtr(hb.HbProof.PK2[:]), + HbPk2sig: byteSliceOmitZeroPtr(hb.HbProof.PK2Sig[:]), + HbSig: byteSliceOmitZeroPtr(hb.HbProof.Sig[:]), + }, + HbSeed: hb.HbSeed[:], + HbVoteId: hb.HbVoteID[:], + } + heartbeat = &hbTxn } var localStateDelta *[]generated.AccountStateDelta @@ -635,9 +652,9 @@ func signedTxnWithAdToTransaction(stxn *sdk.SignedTxnWithAD, extra rowData) (gen for _, t := range stxn.ApplyData.EvalDelta.InnerTxns { extra2 := extra if t.Txn.Type == sdk.ApplicationCallTx { - extra2.AssetID = uint64(t.ApplyData.ApplicationID) + extra2.AssetID = t.ApplyData.ApplicationID } else if t.Txn.Type == sdk.AssetConfigTx { - extra2.AssetID = uint64(t.ApplyData.ConfigAsset) + extra2.AssetID = t.ApplyData.ConfigAsset } else { extra2.AssetID = 0 } @@ -661,6 +678,7 @@ func signedTxnWithAdToTransaction(stxn *sdk.SignedTxnWithAD, extra rowData) (gen PaymentTransaction: payment, KeyregTransaction: keyreg, StateProofTransaction: stateProof, + HeartbeatTransaction: heartbeat, ClosingAmount: uint64Ptr(uint64(stxn.ClosingAmount)), ConfirmedRound: uint64Ptr(extra.Round), IntraRoundOffset: uint64Ptr(uint64(extra.Intra)), @@ -951,9 +969,9 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search func (si *ServerImplementation) maxAccountsErrorToAccountsErrorResponse(maxErr idb.MaxAPIResourcesPerAccountError) generated.ErrorResponse { addr := maxErr.Address.String() - max := uint64(si.opts.MaxAPIResourcesPerAccount) + maxResults := si.opts.MaxAPIResourcesPerAccount extraData := map[string]interface{}{ - "max-results": max, + "max-results": maxResults, "address": addr, "total-assets-opted-in": maxErr.TotalAssets, "total-created-assets": maxErr.TotalAssetParams, diff --git a/api/generate.sh b/api/generate.sh deleted file mode 100755 index 86dae2a06..000000000 --- a/api/generate.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash -set -e - -rootdir=`dirname $0` -pushd $rootdir - -# Convert v2 to v3 -curl -s -X POST "https://converter.swagger.io/api/convert" -H "accept: application/json" -H "Content-Type: application/json" -d @./indexer.oas2.json -o 3.json - -python3 -c "import json; import sys; json.dump(json.load(sys.stdin), sys.stdout, indent=2, sort_keys=True)" < 3.json > indexer.oas3.yml -rm 3.json - -echo "generating code." -oapi-codegen -package generated -type-mappings integer=uint64 -generate types -o generated/v2/types.go -exclude-tags=common indexer.oas3.yml -oapi-codegen -package generated -type-mappings integer=uint64 -generate server,spec -o generated/v2/routes.go -exclude-tags=common indexer.oas3.yml - -oapi-codegen -package common -type-mappings integer=uint64 -generate types -o generated/common/types.go -include-tags=common indexer.oas3.yml -oapi-codegen -package common -type-mappings integer=uint64 -generate server,spec -o generated/common/routes.go -include-tags=common indexer.oas3.yml diff --git a/api/generated/common/routes.go b/api/generated/common/routes.go index e70663e5b..714b8f0b8 100644 --- a/api/generated/common/routes.go +++ b/api/generated/common/routes.go @@ -72,191 +72,198 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "ZUqLlZCOqrd8tQKd9fjO/w8AAP//62VeisflAAA=", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/common/types.go b/api/generated/common/types.go index a7c59f989..4a1826b45 100644 --- a/api/generated/common/types.go +++ b/api/generated/common/types.go @@ -36,6 +36,7 @@ const ( TransactionTxTypeAfrz TransactionTxType = "afrz" TransactionTxTypeAppl TransactionTxType = "appl" TransactionTxTypeAxfer TransactionTxType = "axfer" + TransactionTxTypeHb TransactionTxType = "hb" TransactionTxTypeKeyreg TransactionTxType = "keyreg" TransactionTxTypePay TransactionTxType = "pay" TransactionTxTypeStpf TransactionTxType = "stpf" @@ -61,6 +62,7 @@ const ( TxTypeAfrz TxType = "afrz" TxTypeAppl TxType = "appl" TxTypeAxfer TxType = "axfer" + TxTypeHb TxType = "hb" TxTypeKeyreg TxType = "keyreg" TxTypePay TxType = "pay" TxTypeStpf TxType = "stpf" @@ -561,6 +563,24 @@ type HashFactory struct { // * sha256 type Hashtype string +// HbProofFields \[hbprf\] HbProof is a signature using HeartbeatAddress's partkey, thereby showing it is online. +type HbProofFields struct { + // HbPk \[p\] Public key of the heartbeat message. + HbPk *[]byte `json:"hb-pk,omitempty"` + + // HbPk1sig \[p1s\] Signature of OneTimeSignatureSubkeyOffsetID(PK, Batch, Offset) under the key PK2. + HbPk1sig *[]byte `json:"hb-pk1sig,omitempty"` + + // HbPk2 \[p2\] Key for new-style two-level ephemeral signature. + HbPk2 *[]byte `json:"hb-pk2,omitempty"` + + // HbPk2sig \[p2s\] Signature of OneTimeSignatureSubkeyBatchID(PK2, Batch) under the master key (OneTimeSignatureVerifier). + HbPk2sig *[]byte `json:"hb-pk2sig,omitempty"` + + // HbSig \[s\] Signature of the heartbeat message. + HbSig *[]byte `json:"hb-sig,omitempty"` +} + // HealthCheck A health check response. type HealthCheck struct { Data *map[string]interface{} `json:"data,omitempty"` @@ -827,6 +847,12 @@ type Transaction struct { // Group \[grp\] Base64 encoded byte array of a sha512/256 digest. When present indicates that this transaction is part of a transaction group and the value is the sha512/256 hash of the transactions in that group. Group *[]byte `json:"group,omitempty"` + // HeartbeatTransaction Fields for a heartbeat transaction. + // + // Definition: + // data/transactions/heartbeat.go : HeartbeatTxnFields + HeartbeatTransaction *TransactionHeartbeat `json:"heartbeat-transaction,omitempty"` + // Id Transaction ID Id *string `json:"id,omitempty"` @@ -897,6 +923,7 @@ type Transaction struct { // * \[afrz\] asset-freeze-transaction // * \[appl\] application-transaction // * \[stpf\] state-proof-transaction + // * \[hb\] heartbeat-transaction TxType TransactionTxType `json:"tx-type"` } @@ -910,6 +937,7 @@ type Transaction struct { // * \[afrz\] asset-freeze-transaction // * \[appl\] application-transaction // * \[stpf\] state-proof-transaction +// * \[hb\] heartbeat-transaction type TransactionTxType string // TransactionApplication Fields for application transactions. @@ -1019,6 +1047,27 @@ type TransactionAssetTransfer struct { Sender *string `json:"sender,omitempty"` } +// TransactionHeartbeat Fields for a heartbeat transaction. +// +// Definition: +// data/transactions/heartbeat.go : HeartbeatTxnFields +type TransactionHeartbeat struct { + // HbAddress \[hbad\] HbAddress is the account this txn is proving onlineness for. + HbAddress string `json:"hb-address"` + + // HbKeyDilution \[hbkd\] HbKeyDilution must match HbAddress account's current KeyDilution. + HbKeyDilution uint64 `json:"hb-key-dilution"` + + // HbProof \[hbprf\] HbProof is a signature using HeartbeatAddress's partkey, thereby showing it is online. + HbProof HbProofFields `json:"hb-proof"` + + // HbSeed \[hbsd\] HbSeed must be the block seed for the this transaction's firstValid block. + HbSeed []byte `json:"hb-seed"` + + // HbVoteId \[hbvid\] HbVoteID must match the HbAddress account's current VoteID. + HbVoteId []byte `json:"hb-vote-id"` +} + // TransactionKeyreg Fields for a keyreg transaction. // // Definition: diff --git a/api/generated/v2/routes.go b/api/generated/v2/routes.go index ae2f05591..d90642f3d 100644 --- a/api/generated/v2/routes.go +++ b/api/generated/v2/routes.go @@ -1290,234 +1290,241 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/v2/types.go b/api/generated/v2/types.go index 4916b726c..6b26b2aac 100644 --- a/api/generated/v2/types.go +++ b/api/generated/v2/types.go @@ -36,6 +36,7 @@ const ( TransactionTxTypeAfrz TransactionTxType = "afrz" TransactionTxTypeAppl TransactionTxType = "appl" TransactionTxTypeAxfer TransactionTxType = "axfer" + TransactionTxTypeHb TransactionTxType = "hb" TransactionTxTypeKeyreg TransactionTxType = "keyreg" TransactionTxTypePay TransactionTxType = "pay" TransactionTxTypeStpf TransactionTxType = "stpf" @@ -61,6 +62,7 @@ const ( TxTypeAfrz TxType = "afrz" TxTypeAppl TxType = "appl" TxTypeAxfer TxType = "axfer" + TxTypeHb TxType = "hb" TxTypeKeyreg TxType = "keyreg" TxTypePay TxType = "pay" TxTypeStpf TxType = "stpf" @@ -92,6 +94,7 @@ const ( LookupAccountTransactionsParamsTxTypeAfrz LookupAccountTransactionsParamsTxType = "afrz" LookupAccountTransactionsParamsTxTypeAppl LookupAccountTransactionsParamsTxType = "appl" LookupAccountTransactionsParamsTxTypeAxfer LookupAccountTransactionsParamsTxType = "axfer" + LookupAccountTransactionsParamsTxTypeHb LookupAccountTransactionsParamsTxType = "hb" LookupAccountTransactionsParamsTxTypeKeyreg LookupAccountTransactionsParamsTxType = "keyreg" LookupAccountTransactionsParamsTxTypePay LookupAccountTransactionsParamsTxType = "pay" LookupAccountTransactionsParamsTxTypeStpf LookupAccountTransactionsParamsTxType = "stpf" @@ -110,6 +113,7 @@ const ( LookupAssetTransactionsParamsTxTypeAfrz LookupAssetTransactionsParamsTxType = "afrz" LookupAssetTransactionsParamsTxTypeAppl LookupAssetTransactionsParamsTxType = "appl" LookupAssetTransactionsParamsTxTypeAxfer LookupAssetTransactionsParamsTxType = "axfer" + LookupAssetTransactionsParamsTxTypeHb LookupAssetTransactionsParamsTxType = "hb" LookupAssetTransactionsParamsTxTypeKeyreg LookupAssetTransactionsParamsTxType = "keyreg" LookupAssetTransactionsParamsTxTypePay LookupAssetTransactionsParamsTxType = "pay" LookupAssetTransactionsParamsTxTypeStpf LookupAssetTransactionsParamsTxType = "stpf" @@ -135,6 +139,7 @@ const ( Afrz SearchForTransactionsParamsTxType = "afrz" Appl SearchForTransactionsParamsTxType = "appl" Axfer SearchForTransactionsParamsTxType = "axfer" + Hb SearchForTransactionsParamsTxType = "hb" Keyreg SearchForTransactionsParamsTxType = "keyreg" Pay SearchForTransactionsParamsTxType = "pay" Stpf SearchForTransactionsParamsTxType = "stpf" @@ -649,6 +654,24 @@ type HashFactory struct { // * sha256 type Hashtype string +// HbProofFields \[hbprf\] HbProof is a signature using HeartbeatAddress's partkey, thereby showing it is online. +type HbProofFields struct { + // HbPk \[p\] Public key of the heartbeat message. + HbPk *[]byte `json:"hb-pk,omitempty"` + + // HbPk1sig \[p1s\] Signature of OneTimeSignatureSubkeyOffsetID(PK, Batch, Offset) under the key PK2. + HbPk1sig *[]byte `json:"hb-pk1sig,omitempty"` + + // HbPk2 \[p2\] Key for new-style two-level ephemeral signature. + HbPk2 *[]byte `json:"hb-pk2,omitempty"` + + // HbPk2sig \[p2s\] Signature of OneTimeSignatureSubkeyBatchID(PK2, Batch) under the master key (OneTimeSignatureVerifier). + HbPk2sig *[]byte `json:"hb-pk2sig,omitempty"` + + // HbSig \[s\] Signature of the heartbeat message. + HbSig *[]byte `json:"hb-sig,omitempty"` +} + // HealthCheck A health check response. type HealthCheck struct { Data *map[string]interface{} `json:"data,omitempty"` @@ -915,6 +938,12 @@ type Transaction struct { // Group \[grp\] Base64 encoded byte array of a sha512/256 digest. When present indicates that this transaction is part of a transaction group and the value is the sha512/256 hash of the transactions in that group. Group *[]byte `json:"group,omitempty"` + // HeartbeatTransaction Fields for a heartbeat transaction. + // + // Definition: + // data/transactions/heartbeat.go : HeartbeatTxnFields + HeartbeatTransaction *TransactionHeartbeat `json:"heartbeat-transaction,omitempty"` + // Id Transaction ID Id *string `json:"id,omitempty"` @@ -985,6 +1014,7 @@ type Transaction struct { // * \[afrz\] asset-freeze-transaction // * \[appl\] application-transaction // * \[stpf\] state-proof-transaction + // * \[hb\] heartbeat-transaction TxType TransactionTxType `json:"tx-type"` } @@ -998,6 +1028,7 @@ type Transaction struct { // * \[afrz\] asset-freeze-transaction // * \[appl\] application-transaction // * \[stpf\] state-proof-transaction +// * \[hb\] heartbeat-transaction type TransactionTxType string // TransactionApplication Fields for application transactions. @@ -1107,6 +1138,27 @@ type TransactionAssetTransfer struct { Sender *string `json:"sender,omitempty"` } +// TransactionHeartbeat Fields for a heartbeat transaction. +// +// Definition: +// data/transactions/heartbeat.go : HeartbeatTxnFields +type TransactionHeartbeat struct { + // HbAddress \[hbad\] HbAddress is the account this txn is proving onlineness for. + HbAddress string `json:"hb-address"` + + // HbKeyDilution \[hbkd\] HbKeyDilution must match HbAddress account's current KeyDilution. + HbKeyDilution uint64 `json:"hb-key-dilution"` + + // HbProof \[hbprf\] HbProof is a signature using HeartbeatAddress's partkey, thereby showing it is online. + HbProof HbProofFields `json:"hb-proof"` + + // HbSeed \[hbsd\] HbSeed must be the block seed for the this transaction's firstValid block. + HbSeed []byte `json:"hb-seed"` + + // HbVoteId \[hbvid\] HbVoteID must match the HbAddress account's current VoteID. + HbVoteId []byte `json:"hb-vote-id"` +} + // TransactionKeyreg Fields for a keyreg transaction. // // Definition: diff --git a/api/handlers_test.go b/api/handlers_test.go index c18323513..b290835d4 100644 --- a/api/handlers_test.go +++ b/api/handlers_test.go @@ -643,6 +643,15 @@ func TestFetchTransactions(t *testing.T) { loadTransactionFromFile("test_resources/state_proof_with_index.response"), }, }, + { + name: "Heartbeat Txn", + txnBytes: [][]byte{ + loadResourceFileOrPanic("test_resources/heartbeat.txn"), + }, + response: []generated.Transaction{ + loadTransactionFromFile("test_resources/heartbeat.response"), + }, + }, } // use for the branch below and createTxn helper func to add a new test case @@ -655,8 +664,8 @@ func TestFetchTransactions(t *testing.T) { response []generated.Transaction created uint64 }{ - name: "State Proof Txn", - txnBytes: [][]byte{loadResourceFileOrPanic("test_resources/state_proof.txn")}, + name: "HeartBeat Txn", + txnBytes: [][]byte{loadResourceFileOrPanic("test_resources/heartbeat.txn")}, }) } for _, test := range tests { diff --git a/api/indexer.oas2.json b/api/indexer.oas2.json index 08061df94..17ceb5316 100644 --- a/api/indexer.oas2.json +++ b/api/indexer.oas2.json @@ -2048,7 +2048,8 @@ "asset-transfer-transaction", "keyreg-transaction", "payment-transaction", - "state-proof-transaction" + "state-proof-transaction", + "heartbeat-transaction" ], "properties": { "application-transaction": { @@ -2066,6 +2067,9 @@ "state-proof-transaction": { "$ref": "#/definitions/TransactionStateProof" }, + "heartbeat-transaction": { + "$ref": "#/definitions/TransactionHeartbeat" + }, "auth-addr": { "description": "\\[sgnr\\] this is included with signed transactions when the signing address does not equal the sender. The backend can use this to ensure that auth addr is equal to the accounts auth addr.", "type": "string", @@ -2166,7 +2170,7 @@ "$ref": "#/definitions/TransactionSignature" }, "tx-type": { - "description": "\\[type\\] Indicates what type of transaction this is. Different types have different fields.\n\nValid types, and where their fields are stored:\n* \\[pay\\] payment-transaction\n* \\[keyreg\\] keyreg-transaction\n* \\[acfg\\] asset-config-transaction\n* \\[axfer\\] asset-transfer-transaction\n* \\[afrz\\] asset-freeze-transaction\n* \\[appl\\] application-transaction\n* \\[stpf\\] state-proof-transaction", + "description": "\\[type\\] Indicates what type of transaction this is. Different types have different fields.\n\nValid types, and where their fields are stored:\n* \\[pay\\] payment-transaction\n* \\[keyreg\\] keyreg-transaction\n* \\[acfg\\] asset-config-transaction\n* \\[axfer\\] asset-transfer-transaction\n* \\[afrz\\] asset-freeze-transaction\n* \\[appl\\] application-transaction\n* \\[stpf\\] state-proof-transaction\n* \\[hb\\] heartbeat-transaction", "type": "string", "enum": [ "pay", @@ -2175,7 +2179,8 @@ "axfer", "afrz", "appl", - "stpf" + "stpf", + "hb" ], "x-algorand-format": "tx-type-enum" }, @@ -2333,6 +2338,41 @@ } } }, + "TransactionHeartbeat": { + "description": "Fields for a heartbeat transaction.\n\nDefinition:\ndata/transactions/heartbeat.go : HeartbeatTxnFields", + "type": "object", + "required": [ + "hb-address", + "hb-proof", + "hb-seed", + "hb-vote-id", + "hb-key-dilution" + ], + "properties": { + "hb-address": { + "description": "\\[hbad\\] HbAddress is the account this txn is proving onlineness for.", + "type": "string" + }, + "hb-proof": { + "$ref": "#/definitions/HbProofFields" + }, + "hb-seed": { + "description": "\\[hbsd\\] HbSeed must be the block seed for the this transaction's firstValid block.", + "type": "string", + "format": "byte" + }, + "hb-vote-id": { + "description": "\\[hbvid\\] HbVoteID must match the HbAddress account's current VoteID.", + "type": "string", + "format": "byte" + }, + "hb-key-dilution": { + "description": "\\[hbkd\\] HbKeyDilution must match HbAddress account's current KeyDilution.", + "type": "integer", + "x-algorand-format": "uint64" + } + } + }, "TransactionAssetTransfer": { "description": "Fields for an asset transfer transaction.\n\nDefinition:\ndata/transactions/asset.go : AssetTransferTxnFields", "type": "object", @@ -2564,6 +2604,37 @@ } } }, + "HbProofFields": { + "description": "\\[hbprf\\] HbProof is a signature using HeartbeatAddress's partkey, thereby showing it is online.", + "type": "object", + "properties": { + "hb-sig": { + "description": "\\[s\\] Signature of the heartbeat message.", + "type": "string", + "format": "byte" + }, + "hb-pk": { + "description": "\\[p\\] Public key of the heartbeat message.", + "type": "string", + "format": "byte" + }, + "hb-pk2": { + "description": "\\[p2\\] Key for new-style two-level ephemeral signature.", + "type": "string", + "format": "byte" + }, + "hb-pk1sig": { + "description": "\\[p1s\\] Signature of OneTimeSignatureSubkeyOffsetID(PK, Batch, Offset) under the key PK2.", + "type": "string", + "format": "byte" + }, + "hb-pk2sig": { + "description": "\\[p2s\\] Signature of OneTimeSignatureSubkeyBatchID(PK2, Batch) under the master key (OneTimeSignatureVerifier).", + "type": "string", + "format": "byte" + } + } + }, "IndexerStateProofMessage": { "type": "object", "properties": { @@ -2961,7 +3032,8 @@ "axfer", "afrz", "appl", - "stpf" + "stpf", + "hb" ], "type": "string", "name": "tx-type", diff --git a/api/indexer.oas3.yml b/api/indexer.oas3.yml index 0e2c96185..7a94029d0 100644 --- a/api/indexer.oas3.yml +++ b/api/indexer.oas3.yml @@ -294,7 +294,8 @@ "axfer", "afrz", "appl", - "stpf" + "stpf", + "hb" ], "type": "string" } @@ -1564,6 +1565,42 @@ ], "type": "string" }, + "HbProofFields": { + "description": "\\[hbprf\\] HbProof is a signature using HeartbeatAddress's partkey, thereby showing it is online.", + "properties": { + "hb-pk": { + "description": "\\[p\\] Public key of the heartbeat message.", + "format": "byte", + "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", + "type": "string" + }, + "hb-pk1sig": { + "description": "\\[p1s\\] Signature of OneTimeSignatureSubkeyOffsetID(PK, Batch, Offset) under the key PK2.", + "format": "byte", + "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", + "type": "string" + }, + "hb-pk2": { + "description": "\\[p2\\] Key for new-style two-level ephemeral signature.", + "format": "byte", + "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", + "type": "string" + }, + "hb-pk2sig": { + "description": "\\[p2s\\] Signature of OneTimeSignatureSubkeyBatchID(PK2, Batch) under the master key (OneTimeSignatureVerifier).", + "format": "byte", + "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", + "type": "string" + }, + "hb-sig": { + "description": "\\[s\\] Signature of the heartbeat message.", + "format": "byte", + "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", + "type": "string" + } + }, + "type": "object" + }, "HealthCheck": { "description": "A health check response.", "properties": { @@ -2012,6 +2049,9 @@ "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", "type": "string" }, + "heartbeat-transaction": { + "$ref": "#/components/schemas/TransactionHeartbeat" + }, "id": { "description": "Transaction ID", "type": "string" @@ -2093,7 +2133,7 @@ "$ref": "#/components/schemas/TransactionStateProof" }, "tx-type": { - "description": "\\[type\\] Indicates what type of transaction this is. Different types have different fields.\n\nValid types, and where their fields are stored:\n* \\[pay\\] payment-transaction\n* \\[keyreg\\] keyreg-transaction\n* \\[acfg\\] asset-config-transaction\n* \\[axfer\\] asset-transfer-transaction\n* \\[afrz\\] asset-freeze-transaction\n* \\[appl\\] application-transaction\n* \\[stpf\\] state-proof-transaction", + "description": "\\[type\\] Indicates what type of transaction this is. Different types have different fields.\n\nValid types, and where their fields are stored:\n* \\[pay\\] payment-transaction\n* \\[keyreg\\] keyreg-transaction\n* \\[acfg\\] asset-config-transaction\n* \\[axfer\\] asset-transfer-transaction\n* \\[afrz\\] asset-freeze-transaction\n* \\[appl\\] application-transaction\n* \\[stpf\\] state-proof-transaction\n* \\[hb\\] heartbeat-transaction", "enum": [ "pay", "keyreg", @@ -2101,7 +2141,8 @@ "axfer", "afrz", "appl", - "stpf" + "stpf", + "hb" ], "type": "string", "x-algorand-format": "tx-type-enum" @@ -2259,6 +2300,43 @@ ], "type": "object" }, + "TransactionHeartbeat": { + "description": "Fields for a heartbeat transaction.\n\nDefinition:\ndata/transactions/heartbeat.go : HeartbeatTxnFields", + "properties": { + "hb-address": { + "description": "\\[hbad\\] HbAddress is the account this txn is proving onlineness for.", + "type": "string" + }, + "hb-key-dilution": { + "description": "\\[hbkd\\] HbKeyDilution must match HbAddress account's current KeyDilution.", + "type": "integer", + "x-algorand-format": "uint64" + }, + "hb-proof": { + "$ref": "#/components/schemas/HbProofFields" + }, + "hb-seed": { + "description": "\\[hbsd\\] HbSeed must be the block seed for the this transaction's firstValid block.", + "format": "byte", + "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", + "type": "string" + }, + "hb-vote-id": { + "description": "\\[hbvid\\] HbVoteID must match the HbAddress account's current VoteID.", + "format": "byte", + "pattern": "^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$", + "type": "string" + } + }, + "required": [ + "hb-address", + "hb-key-dilution", + "hb-proof", + "hb-seed", + "hb-vote-id" + ], + "type": "object" + }, "TransactionKeyreg": { "description": "Fields for a keyreg transaction.\n\nDefinition:\ndata/transactions/keyreg.go : KeyregTxnFields", "properties": { @@ -3439,7 +3517,8 @@ "axfer", "afrz", "appl", - "stpf" + "stpf", + "hb" ], "type": "string" } @@ -4618,7 +4697,8 @@ "axfer", "afrz", "appl", - "stpf" + "stpf", + "hb" ], "type": "string" } @@ -5144,7 +5224,8 @@ "axfer", "afrz", "appl", - "stpf" + "stpf", + "hb" ], "type": "string" } diff --git a/api/test_resources/heartbeat.response b/api/test_resources/heartbeat.response new file mode 100644 index 000000000..5e3840863 --- /dev/null +++ b/api/test_resources/heartbeat.response @@ -0,0 +1,2 @@ +{"close-rewards":0,"closing-amount":0,"confirmed-round":1,"fee":0,"first-valid":106,"genesis-hash":"OW4MK52kEQKHteDrbndB7aFjdP9JvNlI9HYefg2WbDg=","heartbeat-transaction":{"hb-address":"RI53WA75QRYLN64GMKBALH35SDFPEJDW5QMTYU3H2F36DBVAHPDN3FF4YA","hb-key-dilution":100,"hb-proof":{"hb-pk":"xcOVoARNqc58zm7KQrbrSunoTMH+56ISf2BLPX4k5DM=","hb-pk1sig":"KwZl8nfA0linTL+quZ1UF3u0ac0y44nKNvjaUOia8sWGedTWiDr3tElqWTdICVVpvCzn2hIweDaWM1QqREV2BA==","hb-pk2":"ORrVitDsfmg/tlsfRIWu35InLVNSLCNWHPf9cxAz4r0=","hb-pk2sig":"gBcItYg/otjdd3kj0cPKkj6JO+CBeEgjBJ+NGLX4j3kU6u1d8+B8f2hytjkNwmja4w04JZaPzQpP5R8kgqgjDA==","hb-sig":"NvPZHly6M+neFgSXwzsYiL3gav4easw+Nmavp1q/GwWwLIOCX3W7jBzilLHypGymkso/M1RNzUq3O8yMdPA8Cw=="},"hb-seed":"mFwjFbENs+K/0c/ebAMSH2LGcn2YMdJ6gTyo6XF9lfQ=","hb-vote-id":"onzbcE5b1QBnQcWrWWC2g/hE3Wea737jMaap7CSx4ss="},"id":"RCV4LKXW34V6767SD4DBNSE4U4PRBDYKR6NVHZ54FFRVYWDNJV7Q","intra-round-offset":2,"last-valid":116,"receiver-rewards":0,"round-time":1734723734,"sender":"GAU5WA6DT2EPFS6LKOA333BQP67NXIHZ7JPOOHMZWJDPZRL4XMHDDDUCKA","sender-rewards":0,"signature":{},"tx-type":"hb"} + diff --git a/api/test_resources/heartbeat.txn b/api/test_resources/heartbeat.txn new file mode 100644 index 0000000000000000000000000000000000000000..c2070003715cfa97b61a6bbe64c0858f1b901f10 GIT binary patch literal 502 zcmVJX2@Ucj1PhJI11GWMrdoa%P30 zaKs?R!=b{pSU`suIB;+%ra4~blKr04i@^`?}Sf@*J;|(|^mXFN}PvsvZ zf~X@5p>xDQHuKpYT)H#q-WCLx!#fy=z2Iv89%{@!HfFD!*?bnrY2qH|=#AedYu6|oJo;=j?)-fROBA7aLGeV8%QdVxHs z>2ZCP^rLoZWW*q%eA{qNTh#z(LB*?CV77z!MBQha?|$Pkrm5^CvEs|3Y<6^`b8ckB sATTN01H+z(^2^IpfxYZ7f4aAl%sVm|Bq`2YX_ literal 0 HcmV?d00001 diff --git a/e2e_tests/docker/indexer/Dockerfile b/e2e_tests/docker/indexer/Dockerfile index 754e1e8b4..50bff4ae1 100644 --- a/e2e_tests/docker/indexer/Dockerfile +++ b/e2e_tests/docker/indexer/Dockerfile @@ -1,4 +1,4 @@ -ARG GO_IMAGE=golang:1.213.3 +ARG GO_IMAGE=golang:1.23.3 FROM $GO_IMAGE ARG CHANNEL=stable diff --git a/go.mod b/go.mod index 6e2af3088..dd5e53b6a 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.23.3 require ( github.com/algorand/avm-abi v0.2.0 - github.com/algorand/go-algorand-sdk/v2 v2.2.1-0.20241114170414-874d2110dae4 + github.com/algorand/go-algorand-sdk/v2 v2.2.1-0.20241220043854-72370807aa70 github.com/algorand/go-codec/codec v1.1.10 github.com/algorand/oapi-codegen v1.12.0-algorand.0 github.com/davecgh/go-spew v1.1.1 diff --git a/go.sum b/go.sum index 107f1976a..fb7e2ce75 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,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/algorand/avm-abi v0.2.0 h1:bkjsG+BOEcxUcnGSALLosmltE0JZdg+ZisXKx0UDX2k= github.com/algorand/avm-abi v0.2.0/go.mod h1:+CgwM46dithy850bpTeHh9MC99zpn2Snirb3QTl2O/g= -github.com/algorand/go-algorand-sdk/v2 v2.2.1-0.20241114170414-874d2110dae4 h1:qQXdtMWlP9ynxeDEhWpUWer3AM51482pnfe7ptTDXm0= -github.com/algorand/go-algorand-sdk/v2 v2.2.1-0.20241114170414-874d2110dae4/go.mod h1:BkHnK2PuCqzdGPNeWUo5yo6lRjyDZ9QoMN8GIjfijrA= +github.com/algorand/go-algorand-sdk/v2 v2.2.1-0.20241220043854-72370807aa70 h1:nCVMHFT4U9VEC9Znsz4JVNsSFuhIpvpZidfnMtIcYJg= +github.com/algorand/go-algorand-sdk/v2 v2.2.1-0.20241220043854-72370807aa70/go.mod h1:BkHnK2PuCqzdGPNeWUo5yo6lRjyDZ9QoMN8GIjfijrA= github.com/algorand/go-codec/codec v1.1.10 h1:zmWYU1cp64jQVTOG8Tw8wa+k0VfwgXIPbnDfiVa+5QA= github.com/algorand/go-codec/codec v1.1.10/go.mod h1:YkEx5nmr/zuCeaDYOIhlDg92Lxju8tj2d2NrYqP7g7k= github.com/algorand/oapi-codegen v1.12.0-algorand.0 h1:W9PvED+wAJc+9EeXPONnA+0zE9UhynEqoDs4OgAxKhk= diff --git a/idb/postgres/internal/writer/write_txn.go b/idb/postgres/internal/writer/write_txn.go index 4a6be5f0b..97f819fbe 100644 --- a/idb/postgres/internal/writer/write_txn.go +++ b/idb/postgres/internal/writer/write_txn.go @@ -28,7 +28,7 @@ func transactionAssetID(stxnad *types.SignedTxnWithAD, intra uint, block *types. case types.ApplicationCallTx: assetid = uint64(stxnad.Txn.ApplicationID) if assetid == 0 { - assetid = uint64(stxnad.ApplyData.ApplicationID) + assetid = stxnad.ApplyData.ApplicationID } if assetid == 0 { if block == nil { @@ -42,7 +42,7 @@ func transactionAssetID(stxnad *types.SignedTxnWithAD, intra uint, block *types. case types.AssetConfigTx: assetid = uint64(stxnad.Txn.ConfigAsset) if assetid == 0 { - assetid = uint64(stxnad.ApplyData.ConfigAsset) + assetid = stxnad.ApplyData.ConfigAsset } if assetid == 0 { if block == nil { @@ -112,6 +112,7 @@ func yieldInnerTransactions(ctx context.Context, stxnad *types.SignedTxnWithAD, // Writes database rows for transactions (including inner transactions) to `outCh`. func yieldTransactions(ctx context.Context, block *types.Block, modifiedTxns []types.SignedTxnInBlock, outCh chan []interface{}) error { intra := uint(0) + for idx, stib := range block.Payset { var stxnad types.SignedTxnWithAD var err error @@ -123,7 +124,7 @@ func yieldTransactions(ctx context.Context, block *types.Block, modifiedTxns []t } txn := &stxnad.Txn - typeenum, ok := idb.GetTypeEnum(types.TxType(txn.Type)) + typeenum, ok := idb.GetTypeEnum(txn.Type) if !ok { return fmt.Errorf("yieldTransactions() get type enum") } @@ -153,9 +154,53 @@ func yieldTransactions(ctx context.Context, block *types.Block, modifiedTxns []t } } + if block.ProposerPayout > 0 { + stxnad := SignedTransactionFromBlockPayout(block) + typeenum, ok := idb.GetTypeEnum(stxnad.Txn.Type) + if !ok { + return fmt.Errorf("yieldTransactions() ProposerPayout get type enum - should NEVER happen") + } + id := crypto.TransactionIDString(stxnad.Txn) + extra := idb.TxnExtra{} + row := []interface{}{ + uint64(block.Round), intra, int(typeenum), 0, id, + encoding.EncodeSignedTxnWithAD(stxnad), + encoding.EncodeTxnExtra(&extra)} + select { + case <-ctx.Done(): + return fmt.Errorf("yieldTransactions() ProposerPayout ctx.Err(): %w", ctx.Err()) + case outCh <- row: + } + } + return nil } +// SignedTransactionFromBlockPayout creates a synthetic transaction for the proposer payout. +func SignedTransactionFromBlockPayout(block *types.Block) types.SignedTxnWithAD { + stxnad := types.SignedTxnWithAD{ + SignedTxn: types.SignedTxn{ + Txn: types.Transaction{ + Type: types.PaymentTx, + Header: types.Header{ + Sender: block.FeeSink, + Note: []byte("ProposerPayout for Round " + fmt.Sprint(block.Round)), + FirstValid: block.Round, + LastValid: block.Round, + GenesisID: block.GenesisID, + GenesisHash: block.GenesisHash, + }, + PaymentTxnFields: types.PaymentTxnFields{ + Receiver: block.Proposer, + Amount: block.ProposerPayout, + }, + }, + }, + } + + return stxnad +} + // AddTransactions adds transactions from `block` to the database. // `modifiedTxns` contains enhanced apply data generated by evaluator. func AddTransactions(block *types.Block, modifiedTxns []types.SignedTxnInBlock, tx pgx.Tx) error { diff --git a/idb/postgres/internal/writer/write_txn_participation.go b/idb/postgres/internal/writer/write_txn_participation.go index 65edf1c1c..d458d8548 100644 --- a/idb/postgres/internal/writer/write_txn_participation.go +++ b/idb/postgres/internal/writer/write_txn_participation.go @@ -125,6 +125,14 @@ func AddTransactionParticipation(block *types.Block, tx pgx.Tx) error { next, rows = addInnerTransactionParticipation(&stxnib.SignedTxnWithAD, uint64(block.Round), next+1, rows) } + if block.ProposerPayout > 0 { + // FeeSink is the sender, Proposer is the receiver. + participants := []types.Address{block.FeeSink, block.Proposer} + for j := range participants { + rows = append(rows, []interface{}{participants[j][:], uint64(block.Round), next}) + } + } + _, err := tx.CopyFrom( context.Background(), pgx.Identifier{"txn_participation"}, diff --git a/idb/postgres/internal/writer/writer_test.go b/idb/postgres/internal/writer/writer_test.go index d793b97a4..e0edcbfb8 100644 --- a/idb/postgres/internal/writer/writer_test.go +++ b/idb/postgres/internal/writer/writer_test.go @@ -168,7 +168,7 @@ func TestWriterSpecialAccounts(t *testing.T) { assert.Equal(t, expected, accounts) } -func TestWriterTxnTableBasic(t *testing.T) { +func TestWriterTxnTableBasicNoPayout(t *testing.T) { db, _, shutdownFunc := pgtest.SetupPostgresWithSchema(t) defer shutdownFunc() @@ -255,6 +255,116 @@ func TestWriterTxnTableBasic(t *testing.T) { assert.NoError(t, rows.Err()) } +func TestWriterTxnTableBasicWithProposalPayout(t *testing.T) { + db, _, shutdownFunc := pgtest.SetupPostgresWithSchema(t) + defer shutdownFunc() + + block := sdk.Block{ + BlockHeader: sdk.BlockHeader{ + Round: sdk.Round(2), + TimeStamp: 333, + GenesisID: test.MakeGenesis().ID(), + GenesisHash: test.MakeGenesis().Hash(), + RewardsState: sdk.RewardsState{ + FeeSink: test.FeeAddr, + RewardsLevel: 111111, + }, + TxnCounter: 9, + UpgradeState: sdk.UpgradeState{ + CurrentProtocol: "future", + }, + Proposer: test.AccountE, + ProposerPayout: 2000000, + }, + Payset: make([]sdk.SignedTxnInBlock, 2), + } + + stxnad0 := test.MakePaymentTxn( + 1000, 1, 0, 0, 0, 0, sdk.Address(test.AccountA), sdk.Address(test.AccountB), sdk.Address{}, + sdk.Address{}) + var err error + block.Payset[0], err = + util.EncodeSignedTxn(block.BlockHeader, stxnad0.SignedTxn, stxnad0.ApplyData) + require.NoError(t, err) + + stxnad1 := test.MakeAssetConfigTxn( + 0, 100, 1, false, "ma", "myasset", "myasset.com", sdk.Address(test.AccountA)) + block.Payset[1], err = + util.EncodeSignedTxn(block.BlockHeader, stxnad1.SignedTxn, stxnad1.ApplyData) + require.NoError(t, err) + + f := func(tx pgx.Tx) error { + return writer.AddTransactions(&block, block.Payset, tx) + } + err = pgutil.TxWithRetry(db, serializable, f, nil) + require.NoError(t, err) + + rows, err := db.Query(context.Background(), "SELECT * FROM txn ORDER BY intra") + require.NoError(t, err) + defer rows.Close() + + var round uint64 + var intra uint64 + var typeenum uint + var asset uint64 + var txid []byte + var txn []byte + var extra []byte + + require.True(t, rows.Next()) + err = rows.Scan(&round, &intra, &typeenum, &asset, &txid, &txn, &extra) + require.NoError(t, err) + assert.Equal(t, block.Round, sdk.Round(round)) + assert.Equal(t, uint64(0), intra) + assert.Equal(t, idb.TypeEnumPay, idb.TxnTypeEnum(typeenum)) + assert.Equal(t, uint64(0), asset) + assert.Equal(t, crypto2.TransactionIDString(stxnad0.Txn), string(txid)) + { + stxn, err := encoding.DecodeSignedTxnWithAD(txn) + require.NoError(t, err) + assert.Equal(t, stxnad0, stxn) + } + assert.Equal(t, "{}", string(extra)) + + require.True(t, rows.Next()) + err = rows.Scan(&round, &intra, &typeenum, &asset, &txid, &txn, &extra) + require.NoError(t, err) + assert.Equal(t, block.Round, sdk.Round(round)) + assert.Equal(t, uint64(1), intra) + assert.Equal(t, idb.TypeEnumAssetConfig, idb.TxnTypeEnum(typeenum)) + assert.Equal(t, uint64(9), asset) + assert.Equal(t, crypto2.TransactionIDString(stxnad1.Txn), string(txid)) + { + stxn, err := encoding.DecodeSignedTxnWithAD(txn) + require.NoError(t, err) + assert.Equal(t, stxnad1, stxn) + } + assert.Equal(t, "{}", string(extra)) + + // Payout should be the last transaction. + require.True(t, rows.Next()) + err = rows.Scan(&round, &intra, &typeenum, &asset, &txid, &txn, &extra) + require.NoError(t, err) + + assert.Equal(t, block.Round, sdk.Round(round)) + assert.Equal(t, uint64(2), intra) + assert.Equal(t, idb.TypeEnumPay, idb.TxnTypeEnum(typeenum)) + assert.Equal(t, uint64(0), asset) + + // Intentionally using synthetic payout transaction logic; we are testing insertion and validity + payoutTxn := writer.SignedTransactionFromBlockPayout(&block) + assert.Equal(t, crypto2.TransactionIDString(payoutTxn.Txn), string(txid)) + { + stxn, err := encoding.DecodeSignedTxnWithAD(txn) + require.NoError(t, err) + assert.Equal(t, payoutTxn, stxn) + } + assert.Equal(t, "{}", string(extra)) + + assert.False(t, rows.Next()) + assert.NoError(t, rows.Err()) +} + // Test that asset close amount is written even if it is missing in the apply data // in the block (it is present in the "modified transactions"). func TestWriterTxnTableAssetCloseAmount(t *testing.T) { @@ -314,7 +424,7 @@ func TestWriterTxnTableAssetCloseAmount(t *testing.T) { assert.NoError(t, rows.Err()) } -func TestWriterTxnParticipationTable(t *testing.T) { +func TestWriterTxnParticipationTableNoPayout(t *testing.T) { type testtype struct { name string payset sdk.Payset @@ -425,6 +535,144 @@ func TestWriterTxnParticipationTable(t *testing.T) { } } +func TestWriterTxnParticipationTableWithPayout(t *testing.T) { + type testtype struct { + name string + payset sdk.Payset + expected []txnParticipationRow + } + + makeBlockFunc := func() sdk.Block { + return sdk.Block{ + BlockHeader: sdk.BlockHeader{ + Round: sdk.Round(2), + GenesisID: test.MakeGenesis().ID(), + GenesisHash: test.MakeGenesis().Hash(), + RewardsState: sdk.RewardsState{ + FeeSink: test.FeeAddr, + }, + UpgradeState: sdk.UpgradeState{ + CurrentProtocol: "future", + }, + Proposer: test.AccountE, + ProposerPayout: 2000000, + }, + } + } + + var tests []testtype + { + stxnad0 := test.MakePaymentTxn( + 1000, 1, 0, 0, 0, 0, sdk.Address(test.AccountA), sdk.Address(test.AccountB), sdk.Address{}, + sdk.Address{}) + stib0, err := util.EncodeSignedTxn(makeBlockFunc().BlockHeader, stxnad0.SignedTxn, stxnad0.ApplyData) + require.NoError(t, err) + + stxnad1 := test.MakeAssetConfigTxn( + 0, 100, 1, false, "ma", "myasset", "myasset.com", sdk.Address(test.AccountC)) + stib1, err := util.EncodeSignedTxn(makeBlockFunc().BlockHeader, stxnad1.SignedTxn, stxnad1.ApplyData) + require.NoError(t, err) + + testcase := testtype{ + name: "basic", + payset: []sdk.SignedTxnInBlock{stib0, stib1}, + expected: []txnParticipationRow{ + { + addr: test.AccountA, + round: 2, + intra: 0, + }, + { + addr: test.AccountB, + round: 2, + intra: 0, + }, + { + addr: test.AccountC, + round: 2, + intra: 1, + }, + // Payout involved accounts + { + addr: test.AccountE, + round: 2, + intra: 2, + }, + { + addr: test.FeeAddr, + round: 2, + intra: 2, + }, + }, + } + tests = append(tests, testcase) + } + { + stxnad := test.MakeCreateAppTxn(sdk.Address(test.AccountA)) + stxnad.Txn.ApplicationCallTxnFields.Accounts = + []sdk.Address{sdk.Address(test.AccountB), sdk.Address(test.AccountC)} + stib, err := util.EncodeSignedTxn(makeBlockFunc().BlockHeader, stxnad.SignedTxn, stxnad.ApplyData) + require.NoError(t, err) + + testcase := testtype{ + name: "app_call_addresses", + payset: []sdk.SignedTxnInBlock{stib}, + expected: []txnParticipationRow{ + { + addr: sdk.Address(test.AccountA), + round: 2, + intra: 0, + }, + { + addr: sdk.Address(test.AccountB), + round: 2, + intra: 0, + }, + { + addr: sdk.Address(test.AccountC), + round: 2, + intra: 0, + }, + // Payout involved accounts + { + addr: test.AccountE, + round: 2, + intra: 1, + }, + { + addr: test.FeeAddr, + round: 2, + intra: 1, + }, + }, + } + tests = append(tests, testcase) + } + + for _, testcase := range tests { + t.Run(testcase.name, func(t *testing.T) { + db, _, shutdownFunc := pgtest.SetupPostgresWithSchema(t) + defer shutdownFunc() + + block := makeBlockFunc() + block.Payset = testcase.payset + + f := func(tx pgx.Tx) error { + return writer.AddTransactionParticipation(&block, tx) + } + err := pgutil.TxWithRetry(db, serializable, f, nil) + require.NoError(t, err) + + results, err := txnParticipationQuery( + db, `SELECT * FROM txn_participation ORDER BY round, intra, addr`) + assert.NoError(t, err) + + // Verify expected participation + assert.Equal(t, testcase.expected, results) + }) + } +} + // Create a new account and then delete it. func TestWriterAccountTableBasic(t *testing.T) { db, _, shutdownFunc := pgtest.SetupPostgresWithSchema(t) diff --git a/idb/postgres/postgres.go b/idb/postgres/postgres.go index 7e41128eb..0b8ff2e7c 100644 --- a/idb/postgres/postgres.go +++ b/idb/postgres/postgres.go @@ -698,8 +698,9 @@ func buildTransactionQuery(tf idb.TransactionFilter) (query string, whereArgs [] whereStr := strings.Join(whereParts, " AND ") query += " WHERE " + whereStr } + if joinParticipation { - // this should match the index on txn_particpation + // this should match the index on txn_participation query += " ORDER BY p.addr, p.round DESC, p.intra DESC" } else { // this should explicitly match the primary key on txn (round,intra) diff --git a/idb/txn_type_enum.go b/idb/txn_type_enum.go index 39f0c6cac..286129dce 100644 --- a/idb/txn_type_enum.go +++ b/idb/txn_type_enum.go @@ -20,6 +20,7 @@ const ( TypeEnumAssetFreeze TypeEnumApplication TypeEnumStateProof + TypeEnumHeartbeat ) var typeEnumMap = map[string]TxnTypeEnum{ @@ -30,6 +31,7 @@ var typeEnumMap = map[string]TxnTypeEnum{ "afrz": TypeEnumAssetFreeze, "appl": TypeEnumApplication, "stpf": TypeEnumStateProof, + "hb": TypeEnumHeartbeat, } func makeTypeEnumString() string { From 1eb228d47ca6bf4bf3cb0cfe0c43e98ce5872932 Mon Sep 17 00:00:00 2001 From: Gary Malouf <982483+gmalouf@users.noreply.github.com> Date: Fri, 20 Dec 2024 21:32:23 -0500 Subject: [PATCH 10/13] Set go-algorand-sdk to v2.7.0. (#1640) --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index dd5e53b6a..678734b30 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ toolchain go1.23.3 require ( github.com/algorand/avm-abi v0.2.0 - github.com/algorand/go-algorand-sdk/v2 v2.2.1-0.20241220043854-72370807aa70 + github.com/algorand/go-algorand-sdk/v2 v2.7.0 github.com/algorand/go-codec/codec v1.1.10 github.com/algorand/oapi-codegen v1.12.0-algorand.0 github.com/davecgh/go-spew v1.1.1 diff --git a/go.sum b/go.sum index fb7e2ce75..a4ec30d38 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,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/algorand/avm-abi v0.2.0 h1:bkjsG+BOEcxUcnGSALLosmltE0JZdg+ZisXKx0UDX2k= github.com/algorand/avm-abi v0.2.0/go.mod h1:+CgwM46dithy850bpTeHh9MC99zpn2Snirb3QTl2O/g= -github.com/algorand/go-algorand-sdk/v2 v2.2.1-0.20241220043854-72370807aa70 h1:nCVMHFT4U9VEC9Znsz4JVNsSFuhIpvpZidfnMtIcYJg= -github.com/algorand/go-algorand-sdk/v2 v2.2.1-0.20241220043854-72370807aa70/go.mod h1:BkHnK2PuCqzdGPNeWUo5yo6lRjyDZ9QoMN8GIjfijrA= +github.com/algorand/go-algorand-sdk/v2 v2.7.0 h1:ntORjVgXnm+1jqpj55Fv2MbYitxwE9A+xNYopsN5uoA= +github.com/algorand/go-algorand-sdk/v2 v2.7.0/go.mod h1:BkHnK2PuCqzdGPNeWUo5yo6lRjyDZ9QoMN8GIjfijrA= github.com/algorand/go-codec/codec v1.1.10 h1:zmWYU1cp64jQVTOG8Tw8wa+k0VfwgXIPbnDfiVa+5QA= github.com/algorand/go-codec/codec v1.1.10/go.mod h1:YkEx5nmr/zuCeaDYOIhlDg92Lxju8tj2d2NrYqP7g7k= github.com/algorand/oapi-codegen v1.12.0-algorand.0 h1:W9PvED+wAJc+9EeXPONnA+0zE9UhynEqoDs4OgAxKhk= From 7e4b04a82f8ff7e17c23f27d85a3bdc0fec2bc89 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Sun, 22 Dec 2024 12:32:52 -0300 Subject: [PATCH 11/13] Fix error in parameter conversion --- api/converter_utils.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/converter_utils.go b/api/converter_utils.go index 505f297cf..b16619662 100644 --- a/api/converter_utils.go +++ b/api/converter_utils.go @@ -1016,7 +1016,7 @@ func (si *ServerImplementation) blockParamsToBlockFilter(params generated.Search } // Participation = proposers || absent || expired - if params.Absent != nil { + if params.Participation != nil { for _, s := range *params.Participation { addr, err := sdk.DecodeAddress(s) if err != nil { From 4c3d2d385f703f14dc0732de7785df080288dd80 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Sun, 22 Dec 2024 13:50:15 -0300 Subject: [PATCH 12/13] Enable account rewinding --- accounting/rewind.go | 177 +++++++++++++++++++++++++++++++++ api/error_messages.go | 3 +- api/generated/v2/routes.go | 91 ++++++++--------- api/generated/v2/types.go | 4 +- api/handlers.go | 51 ++++++++-- api/handlers_test.go | 47 --------- api/indexer.oas2.json | 7 +- api/indexer.oas3.yml | 4 +- api/server.go | 16 +-- cmd/algorand-indexer/daemon.go | 3 +- 10 files changed, 283 insertions(+), 120 deletions(-) create mode 100644 accounting/rewind.go diff --git a/accounting/rewind.go b/accounting/rewind.go new file mode 100644 index 000000000..040b0ee98 --- /dev/null +++ b/accounting/rewind.go @@ -0,0 +1,177 @@ +package accounting + +import ( + "context" + "fmt" + + sdk "github.com/algorand/go-algorand-sdk/v2/types" + models "github.com/algorand/indexer/v3/api/generated/v2" + "github.com/algorand/indexer/v3/idb" + "github.com/algorand/indexer/v3/types" +) + +// ConsistencyError is returned when the database returns inconsistent (stale) results. +type ConsistencyError struct { + msg string +} + +func (e ConsistencyError) Error() string { + return e.msg +} +func assetUpdate(account *models.Account, assetid uint64, add, sub uint64) { + if account.Assets == nil { + account.Assets = new([]models.AssetHolding) + } + assets := *account.Assets + for i, ah := range assets { + if ah.AssetId == assetid { + ah.Amount += add + ah.Amount -= sub + assets[i] = ah + // found and updated asset, done + return + } + } + // add asset to list + assets = append(assets, models.AssetHolding{ + Amount: add - sub, + AssetId: assetid, + //Creator: base32 addr string of asset creator, TODO + //IsFrozen: leave nil? // TODO: on close record frozen state for rewind + }) + *account.Assets = assets +} + +// SpecialAccountRewindError indicates that an attempt was made to rewind one of the special accounts. +type SpecialAccountRewindError struct { + account string +} + +// MakeSpecialAccountRewindError helper to initialize a SpecialAccountRewindError. +func MakeSpecialAccountRewindError(account string) *SpecialAccountRewindError { + return &SpecialAccountRewindError{account: account} +} + +// Error is part of the error interface. +func (sare *SpecialAccountRewindError) Error() string { + return fmt.Sprintf("unable to rewind the %s", sare.account) +} + +var specialAccounts *types.SpecialAddresses + +// AccountAtRound queries the idb.IndexerDb object for transactions and rewinds most fields of the account back to +// their values at the requested round. +// `round` must be <= `account.Round` +func AccountAtRound(ctx context.Context, account models.Account, round uint64, db idb.IndexerDb) (acct models.Account, err error) { + // Make sure special accounts cache has been initialized. + if specialAccounts == nil { + var accounts types.SpecialAddresses + accounts, err = db.GetSpecialAccounts(ctx) + if err != nil { + return models.Account{}, fmt.Errorf("unable to get special accounts: %v", err) + } + specialAccounts = &accounts + } + acct = account + var addr sdk.Address + addr, err = sdk.DecodeAddress(account.Address) + if err != nil { + return + } + // ensure that the don't attempt to rewind a special account. + if specialAccounts.FeeSink == addr { + err = MakeSpecialAccountRewindError("FeeSink") + return + } + if specialAccounts.RewardsPool == addr { + err = MakeSpecialAccountRewindError("RewardsPool") + return + } + // Get transactions and rewind account. + tf := idb.TransactionFilter{ + Address: addr[:], + MinRound: round + 1, + MaxRound: account.Round, + } + ctx2, cf := context.WithCancel(ctx) + // In case of a panic before the next defer, call cf() here. + defer cf() + txns, r := db.Transactions(ctx2, tf) + // In case of an error, make sure the context is cancelled, and the channel is cleaned up. + defer func() { + cf() + for range txns { + } + }() + if r < account.Round { + err = ConsistencyError{fmt.Sprintf("queried round r: %d < account.Round: %d", r, account.Round)} + return + } + txcount := 0 + for txnrow := range txns { + if txnrow.Error != nil { + err = txnrow.Error + return + } + txcount++ + stxn := txnrow.Txn + if stxn == nil { + return models.Account{}, + fmt.Errorf("rewinding past inner transactions is not supported") + } + if addr == stxn.Txn.Sender { + acct.AmountWithoutPendingRewards += uint64(stxn.Txn.Fee) + acct.AmountWithoutPendingRewards -= uint64(stxn.SenderRewards) + } + switch stxn.Txn.Type { + case sdk.PaymentTx: + if addr == stxn.Txn.Sender { + acct.AmountWithoutPendingRewards += uint64(stxn.Txn.Amount) + } + if addr == stxn.Txn.Receiver { + acct.AmountWithoutPendingRewards -= uint64(stxn.Txn.Amount) + acct.AmountWithoutPendingRewards -= uint64(stxn.ReceiverRewards) + } + if addr == stxn.Txn.CloseRemainderTo { + // unwind receiving a close-to + acct.AmountWithoutPendingRewards -= uint64(stxn.ClosingAmount) + acct.AmountWithoutPendingRewards -= uint64(stxn.CloseRewards) + } else if !stxn.Txn.CloseRemainderTo.IsZero() { + // unwind sending a close-to + acct.AmountWithoutPendingRewards += uint64(stxn.ClosingAmount) + } + case sdk.KeyRegistrationTx: + // TODO: keyreg does not rewind. workaround: query for txns on an account with typeenum=2 to find previous values it was set to. + case sdk.AssetConfigTx: + if stxn.Txn.ConfigAsset == 0 { + // create asset, unwind the application of the value + assetUpdate(&acct, txnrow.AssetID, 0, stxn.Txn.AssetParams.Total) + } + case sdk.AssetTransferTx: + if addr == stxn.Txn.AssetSender || addr == stxn.Txn.Sender { + assetUpdate(&acct, uint64(stxn.Txn.XferAsset), stxn.Txn.AssetAmount+txnrow.Extra.AssetCloseAmount, 0) + } + if addr == stxn.Txn.AssetReceiver { + assetUpdate(&acct, uint64(stxn.Txn.XferAsset), 0, stxn.Txn.AssetAmount) + } + if addr == stxn.Txn.AssetCloseTo { + assetUpdate(&acct, uint64(stxn.Txn.XferAsset), 0, txnrow.Extra.AssetCloseAmount) + } + case sdk.AssetFreezeTx: + default: + err = fmt.Errorf("%s[%d,%d]: rewinding past txn type %s is not currently supported", account.Address, txnrow.Round, txnrow.Intra, stxn.Txn.Type) + return + } + } + acct.Round = round + // Due to accounts being closed and re-opened, we cannot always rewind Rewards. So clear it out. + acct.Rewards = 0 + // Computing pending rewards is not supported. + acct.PendingRewards = 0 + acct.Amount = acct.AmountWithoutPendingRewards + // MinBalance is not supported. + acct.MinBalance = 0 + // TODO: Clear out the closed-at field as well. Like Rewards we cannot know this value for all accounts. + //acct.ClosedAt = 0 + return +} diff --git a/api/error_messages.go b/api/error_messages.go index 0bc4fb348..0060e5214 100644 --- a/api/error_messages.go +++ b/api/error_messages.go @@ -38,7 +38,8 @@ const ( errMultipleApplications = "multiple applications found for this id, please contact us, this shouldn't happen" ErrMultipleBoxes = "multiple application boxes found for this app id and box name, please contact us, this shouldn't happen" ErrFailedLookingUpBoxes = "failed while looking up application boxes" - errRewindingAccountNotSupported = "rewinding account is no longer supported, please remove the `round=` query parameter and try again" + errMultiAcctRewind = "multiple accounts rewind is not supported by this server" + errRewindingAccount = "error while rewinding account" errLookingUpBlockForRound = "error while looking up block for round" errBlockHeaderSearch = "error while searching for block headers" errTransactionSearch = "error while searching for transaction" diff --git a/api/generated/v2/routes.go b/api/generated/v2/routes.go index cc1e6c385..4d3984127 100644 --- a/api/generated/v2/routes.go +++ b/api/generated/v2/routes.go @@ -1615,51 +1615,52 @@ var swaggerSpec = []string{ "2eH4tMoWHXqKTdFhRW4h36Zmtl2Vf7n1pDh1nl52WPwcuCKCDxL6kfUt2IWmJDTPY8sMvAvay/x+45ZZ", "Yz+uVpfpEnwS24C2IcMMwi77TRV36PZm6voHfmI+HrzyD6taisYGDuhjt4NtilxmbHI2p7lm8e1huMjG", "1lQSoXfDx71zrnCtSHiNHvg6CfzBJo0ofttCSBHPz9xJg2q2QLot05kceuvg2tzfK2enuNZ98373gVOV", - "kXU6C8j+bC+hyxgX5RpVPo5+arfXm3735zb4L6xUkgKSgnsc1zTP5ZplrhZ6hcxVaSh3ZyvO5ORD59fg", - "QlBPyDv0a9VB2Fg9FvjqKUaEXDsX4P4TqgpQH3AoYc7ofh7ddkzcMcOvVlfFMi5w+Z48fuzFKWduDkY7", - "/adGxagesD+g45Ao0tid9DU8d6b7qCqzox8EHtwaxYhVUZp+Z7GNSYB5d0f+WTu6WdAFF87FEoy4K3qB", - "Mi7GEzsPZ39hfXYXKxFUr3NOhnD4McCWWotpzQ34NSr+NiF/CJ6Oj+wCv77WOfbW7+mvo9Nah284BOx3", - "DgExSgPr/3yaTr753JdgkZouNBSMAzF88uunlnB/+qcPMeDZp15J/7WUF2VRvREEVT27Aj+2dffq2RaI", - "xE6Bv3p58GQYSArUXKkpSgXkJNwjo0p2kPj6r0mUR8l0lExvRzK9EW59AI++QZ4c54MjG5x8/fjrkZPf", - "H06eA3/dw8lPOxRgH2sXgU9gm47KAsltvm2yv9TlA9shADwtCsgSA3ZgfZ9EgaNrMn9VtjyaVq9kWj0y", - "K23d9wM04HqW+qaO+nAQZNna2FEiGCWCz1EiqEK670QO8KrJ/eH/N/LOOPL8keffGs+vbvQwRh9W7B35", - "u+fvlRFlZOojU//cmHoka/xhLN5bK+PGzGux/Oc49NMQtFH/H2WBURa4Gf2/QQAOVf1HgSCSVWkUC0ax", - "4PMWCw7X+SuBoPUWehRRYDQCjIx/ZPx3bgQYmf2o/Y9s/vNn82Es2FDfvWZqrw+NApeKObLNMiLY2l42", - "I4nMLTPaw+HDgfYx+JFvHCcWJ6i6Z2eZ842jzj63latiXtcgFtIwLNLQCwVkOoHBDnaVx5j1Pk/56uuf", - "0Yl9PYFw0iPXQ4htIV9AeOGc5+C890+7cx4byzorR+Xu6atoVOGoUOFC8wVJquQI9pcV/gQBt+/5wv6U", - "408Q6o+BzrF90HzRvxEauq3wHzveoEU6ChAspJnlYLZ1Enz8XOLib/90ryIes81NRJ/ZG3CA9VNSQ6yG", - "MsdYtHDqFRfJzumrBkcBYcbm0gXfBDDQzR4YfINDgzNuVJvxKwvWtOCWCkNRffLGER0qyLuXz8lXX331", - "N4KX32o3iC59C8YhseJQCFxFPDJqqs9DSNG7l88BgPeVX+ugVnsPtcKoY60cRrx/C/8Lh3n+JWPtbtPm", - "0r5UuGofZ4GaJZZg2y2qVIXadlotjqtt/0W05OmkrVpcv+ZqS1tq7mRrwjHW7F9KeR3yOB0mk2i+wPTl", - "kzjgXfnm33pfggKB+kOjOkx16VBiqFKE17ntogQdm11N8B7NzqP5YHxv/iu+N/9LRywH+3T6Z5NY749c", - "DkpE9hky6ybxqOWYSNxmGXvF4r/cq+GNkZ0Dic3tRY5e8ylpfIf5TETZDhE6nclNLyH6LxD/rPbfkEXh", - "Gs7khth7NXXii26lf60aQGtnc3jmfqsLgzsj/0K6YoippSRULbD0+wMYjIvFGQzw4IS8lIpwoCalk0Ow", - "IRfm7MsnX33tmii6JrOtYXrq4AHoyLdfAzS264PZt18/8E8QFNK625/Onn73nRujUFwYOsuZszB05tRG", - "nS1ZnkvXwcnHrNPQfjj77//535OTkwdDSLncWGr+VGQ/0RW7faL+tD47LuBokqOeSLPdbW16VADF/R1u", - "GLouZ9hF/J/JTey62zsTJC8Z3+5HnnE8nqHL1YqqraX1zMC1D1DNucyhEaAljV6Z2TB9KLupOQzUPapY", - "CKRXpU0pUEtlJcycbXgqF4oWS245yvZkkE3mGYB36/R2NA7cL+NAf5H2gmeb8/NfGyjHRcY2cf29QvdB", - "loZncvPCTSmjhYA/B3MA3gZc+BDC9Cy8zs2rP3K6kdPdJKdDtBvA4w6y6pzmcqEPMO0Q236AUvBaLvTd", - "2HhG9nQc17c7dmn6i/oXQa2j6qE+dB2tsx76Ala737ewVVDs8WaS8t5/seZG3zxyuUg8xzg8F9Dihe36", - "WctO1zDF7jIC7o6qCl+yoeUuhWlQRNT4sDsyxwO4VcMXAauk36IXwv7Z7eh7rIhHna8U3PTNZ79Nbj9k", - "cIwBG2PARtX0Nr0H4JBP//TXc7/HAFzzIZnObcPh2mRNHkZfgRv2FQAyN5QW3mJmaZhyJDejMe9+uzq0", - "KebpjOZUpGyvRQ5Fb23ADO2L96yXEgiKS4oPBGYnRfWTjbrRqBuN9evGwKahgU1HE7qOK42ExHOQlvaG", - "Cz6m7IxxvVnNGkaV7a8kgByS76LxPAG2WEefdiW9wFQXlqVi+oudOt+Y8mJMeTGmvBhTXowpL+7wSXpM", - "TjEmpxh1uH/t5BRD3E7cS6YFVAqG/syNxigD9IoiN+2J0lnUc7maccFqLcivoC4baqQ9KGi0pKbiw76h", - "kURXrgZ71pUomffwV/DEAc04ZfwS/jtXjP3BEkOVlbCH8NvGajyAUCQzmD+sknnQ2qxkjFY34pOCaFdQ", - "Va0gIa2pstYSSvxKplZY3sqSrOGy5PwC+rsKm3bTV1CatVWt1UhiVNn7Qu26JwDP3vQj09t4BRozqYyZ", - "VMZMKn8Bk8gsl+lFsmQ0AzPDfgc06EBchxPyLPyzafrglvWnTMDDCaASkSpjKmIuEdJ4IlOp2bI0RWl2", - "eLrB1D84yEdrya1YS0YdcdQR/6I6YquaP0fdJucUaIjdgN8s4ZeaKf1b3XBKuCFsY3/HEEm2oakhmq4Y", - "mZciRQrDzXZoOXc/Sbye+4Eaxu7a7F1PRf/2vqLqAoVjD44n2yF/eAAbZnjKC3zQLosMHrNJazNpmrLC", - "IpOVwlaUaGa/Qayof/X3geSHbpO+J/vENoXl5/dtmxxY92ST6EwzYe7bHiFU9wyPLNu9l7vlprpf2zX1", - "mwUhFPeXaIUT38IOHtkhwe7iARHVtfw+eiJUngi4h9Mx59O/sOt4fVGi2jbQGSayQnJhGoKmHf+/vv9A", - "6kHQkjljS3rJJUilPGPC8JTm+1TnUWkeleZRaR6V5lFpHpXmUWkeleZRaR6V5lFpHpXmUWkeleZ7qzSf", - "/glnm6BOujfmGjr1+dzDXdqnBOOVweniVYxCgK7pfoMXm0iRb8k8p4sT8g97heCOQCYk432JpvU7O9Lh", - "TDLUq52/ettbTfcoDki/EzvlzTrr7KVq4/X8nB1JBkXSBH4kQ6vGtgNovGNp3MGRa3AcbbuXVnr3YfVo", - "K3vZGJgzBuaMgTn3OzAnpCCzLVkoWRbk1QungQBaVKiDp5W4YggYgw8WtDVVmZ76YgnpkiqawtaBq++/", - "T8kptP2uGunnd6/9MD1LBkCSnfE/10S4MVBprM071uYdrfRj+NMY/jSGP43hT//q4U93GbI0vfFCsGNQ", - "1BgUNdqy7tTUHB7t6Z9WJ9qf3JNYdTpvcMg+u3OIdUMyfDql7PbqoN0iCQm266DLOvxyjnkwR/JyX0zl", - "n6YTzdSlv+ulyidnk6UxhT47PWUbuipydpLK1Sm8Mrv+f1Zyv1ytgFFVv7iRg18cKbPdN4lU3PLePNFr", - "ulgwldiZEeYnJ48nn/5fAAAA///7f6MiAcABAA==", + "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", + "jDA/OXk8+fT/AgAA//+iEaM6j8ABAA==", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/api/generated/v2/types.go b/api/generated/v2/types.go index dca1136c3..2b373c4c7 100644 --- a/api/generated/v2/types.go +++ b/api/generated/v2/types.go @@ -1656,7 +1656,7 @@ type SearchForAccountsParams struct { // AuthAddr Include accounts configured to use this spending key. AuthAddr *string `form:"auth-addr,omitempty" json:"auth-addr,omitempty"` - // Round Deprecated and disallowed. This parameter used to include results for a specified round. Requests with this parameter set are now rejected. + // Round Include results for the specified round. For performance reasons, this parameter may be disabled on some configurations. Using application-id or asset-id filters will return both creator and opt-in accounts. Filtering by include-all will return creator and opt-in accounts for deleted assets and accounts. Non-opt-in managers are not included in the results when asset-id is used. Round *uint64 `form:"round,omitempty" json:"round,omitempty"` // ApplicationId Application ID @@ -1668,7 +1668,7 @@ type SearchForAccountsParamsExclude string // LookupAccountByIDParams defines parameters for LookupAccountByID. type LookupAccountByIDParams struct { - // Round Deprecated and disallowed. This parameter used to include results for a specified round. Requests with this parameter set are now rejected. + // Round Include results for the specified round. Round *uint64 `form:"round,omitempty" json:"round,omitempty"` // IncludeAll Include all items including closed accounts, deleted applications, destroyed assets, opted-out asset holdings, and closed-out application localstates. diff --git a/api/handlers.go b/api/handlers.go index 121e99604..f18399121 100644 --- a/api/handlers.go +++ b/api/handlers.go @@ -17,6 +17,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/algorand/avm-abi/apps" + "github.com/algorand/indexer/v3/accounting" "github.com/algorand/indexer/v3/api/generated/common" "github.com/algorand/indexer/v3/api/generated/v2" "github.com/algorand/indexer/v3/idb" @@ -28,6 +29,14 @@ import ( // ServerImplementation implements the handler interface used by the generated route definitions. type ServerImplementation struct { + + // EnableAddressSearchRoundRewind is allows configuring whether or not the + // 'accounts' endpoint allows specifying a round number. This is done for + // performance reasons, because requesting many accounts at a particular + // round could put a lot of strain on the system (especially if the round + // is from long ago). + EnableAddressSearchRoundRewind bool + db idb.IndexerDb dataError func() error @@ -209,9 +218,8 @@ func (si *ServerImplementation) LookupAccountByID(ctx echo.Context, accountID st if err := si.verifyHandler("LookupAccountByID", ctx); err != nil { return badRequest(ctx, err.Error()) } - // The Round parameter is no longer supported (as it was used to request account rewinding) - if params.Round != nil { - return badRequest(ctx, errRewindingAccountNotSupported) + if params.Round != nil && uint64(*params.Round) > math.MaxInt64 { + return notFound(ctx, errValueExceedingInt64) } addr, err := sdk.DecodeAddress(accountID) @@ -241,7 +249,7 @@ func (si *ServerImplementation) LookupAccountByID(ctx echo.Context, accountID st } } - accounts, round, err := si.fetchAccounts(ctx.Request().Context(), options) + accounts, round, err := si.fetchAccounts(ctx.Request().Context(), options, params.Round) if err != nil { var maxErr idb.MaxAPIResourcesPerAccountError if errors.As(err, &maxErr) { @@ -399,13 +407,13 @@ func (si *ServerImplementation) SearchForAccounts(ctx echo.Context, params gener return badRequest(ctx, err.Error()) } if (params.AssetId != nil && uint64(*params.AssetId) > math.MaxInt64) || - (params.ApplicationId != nil && uint64(*params.ApplicationId) > math.MaxInt64) { + (params.ApplicationId != nil && uint64(*params.ApplicationId) > math.MaxInt64) || + (params.Round != nil && uint64(*params.Round) > math.MaxInt64) { return notFound(ctx, errValueExceedingInt64) } - // The Round parameter is no longer supported (as it was used to request account rewinding) - if params.Round != nil { - return badRequest(ctx, errRewindingAccountNotSupported) + if !si.EnableAddressSearchRoundRewind && params.Round != nil { + return badRequest(ctx, errMultiAcctRewind) } var spendingAddrBytes []byte @@ -458,7 +466,7 @@ func (si *ServerImplementation) SearchForAccounts(ctx echo.Context, params gener options.GreaterThanAddress = addr[:] } - accounts, round, err := si.fetchAccounts(ctx.Request().Context(), options) + accounts, round, err := si.fetchAccounts(ctx.Request().Context(), options, params.Round) if err != nil { var maxErr idb.MaxAPIResourcesPerAccountError if errors.As(err, &maxErr) { @@ -1489,7 +1497,7 @@ func (si *ServerImplementation) fetchBlock(ctx context.Context, round uint64, op // fetchAccounts queries for accounts and converts them into generated.Account // objects, optionally rewinding their value back to a particular round. -func (si *ServerImplementation) fetchAccounts(ctx context.Context, options idb.AccountQueryOptions) ([]generated.Account, uint64 /*round*/, error) { +func (si *ServerImplementation) fetchAccounts(ctx context.Context, options idb.AccountQueryOptions, atRound *uint64) ([]generated.Account, uint64 /*round*/, error) { var round uint64 accounts := make([]generated.Account, 0) err := callWithTimeout(ctx, si.log, si.timeout, func(ctx context.Context) error { @@ -1502,12 +1510,33 @@ func (si *ServerImplementation) fetchAccounts(ctx context.Context, options idb.A } }() + if (atRound != nil) && (*atRound > round) { + return fmt.Errorf("%s: the requested round %d > the current round %d", + errRewindingAccount, *atRound, round) + } + for row := range accountchan { if row.Error != nil { return row.Error } - account := row.Account + // Compute for a given round if requested. + var account generated.Account + if atRound != nil { + acct, err := accounting.AccountAtRound(ctx, row.Account, *atRound, si.db) + if err != nil { + // Ignore the error if this is an account search rewind error + _, isSpecialAccountRewindError := err.(*accounting.SpecialAccountRewindError) + if len(options.EqualToAddress) != 0 || !isSpecialAccountRewindError { + return fmt.Errorf("%s: %v", errRewindingAccount, err) + } + // If we didn't return, continue to the next account + continue + } + account = acct + } else { + account = row.Account + } // match the algod equivalent which includes pending rewards account.Rewards += account.PendingRewards diff --git a/api/handlers_test.go b/api/handlers_test.go index b290835d4..6f4134608 100644 --- a/api/handlers_test.go +++ b/api/handlers_test.go @@ -1206,53 +1206,6 @@ func TestBigNumbers(t *testing.T) { } } -func TestRewindRoundParameterRejected(t *testing.T) { - testcases := []struct { - name string - errString string - callHandler func(ctx echo.Context, si ServerImplementation) error - }{ - { - name: "SearchForAccountInvalidRound", - errString: errRewindingAccountNotSupported, - callHandler: func(ctx echo.Context, si ServerImplementation) error { - return si.SearchForAccounts(ctx, generated.SearchForAccountsParams{Round: uint64Ptr(uint64(math.MaxInt64 + 1))}) - }, - }, - { - name: "LookupAccountByID", - errString: errRewindingAccountNotSupported, - callHandler: func(ctx echo.Context, si ServerImplementation) error { - return si.LookupAccountByID(ctx, - "PBH2JQNVP5SBXLTOWNHHPGU6FUMBVS4ZDITPK5RA5FG2YIIFS6UYEMFM2Y", - generated.LookupAccountByIDParams{Round: uint64Ptr(uint64(math.MaxInt64 + 1))}) - }, - }, - } - - for _, tc := range testcases { - t.Run(tc.name, func(t *testing.T) { - - // Make a mock indexer. - mockIndexer := &mocks.IndexerDb{} - - si := testServerImplementation(mockIndexer) - - // Setup context... - e := echo.New() - req := httptest.NewRequest(http.MethodGet, "/", nil) - rec1 := httptest.NewRecorder() - c := e.NewContext(req, rec1) - - // call handler - require.NoError(t, tc.callHandler(c, *si)) - assert.Equal(t, http.StatusBadRequest, rec1.Code) - bodyStr := rec1.Body.String() - require.Contains(t, bodyStr, tc.errString) - }) - } -} - func TestFetchBlock(t *testing.T) { testcases := []struct { name string diff --git a/api/indexer.oas2.json b/api/indexer.oas2.json index 3fbcb603d..fa84254fd 100644 --- a/api/indexer.oas2.json +++ b/api/indexer.oas2.json @@ -80,7 +80,7 @@ }, { "type": "integer", - "description": "Deprecated and disallowed. This parameter used to include results for a specified round. Requests with this parameter set are now rejected.", + "description": "Include results for the specified round. For performance reasons, this parameter may be disabled on some configurations. Using application-id or asset-id filters will return both creator and opt-in accounts. Filtering by include-all will return creator and opt-in accounts for deleted assets and accounts. Non-opt-in managers are not included in the results when asset-id is used.", "name": "round", "in": "query" }, @@ -119,10 +119,7 @@ "$ref": "#/parameters/account-id" }, { - "type": "integer", - "description": "Deprecated and disallowed. This parameter used to include results for a specified round. Requests with this parameter set are now rejected.", - "name": "round", - "in": "query" + "$ref": "#/parameters/round" }, { "$ref": "#/parameters/include-all" diff --git a/api/indexer.oas3.yml b/api/indexer.oas3.yml index b7abcbc28..aec70e739 100644 --- a/api/indexer.oas3.yml +++ b/api/indexer.oas3.yml @@ -2810,7 +2810,7 @@ "x-algorand-format": "Address" }, { - "description": "Deprecated and disallowed. This parameter used to include results for a specified round. Requests with this parameter set are now rejected.", + "description": "Include results for the specified round. For performance reasons, this parameter may be disabled on some configurations. Using application-id or asset-id filters will return both creator and opt-in accounts. Filtering by include-all will return creator and opt-in accounts for deleted assets and accounts. Non-opt-in managers are not included in the results when asset-id is used.", "in": "query", "name": "round", "schema": { @@ -2922,7 +2922,7 @@ } }, { - "description": "Deprecated and disallowed. This parameter used to include results for a specified round. Requests with this parameter set are now rejected.", + "description": "Include results for the specified round.", "in": "query", "name": "round", "schema": { diff --git a/api/server.go b/api/server.go index 0096878df..1e4decbad 100644 --- a/api/server.go +++ b/api/server.go @@ -23,6 +23,9 @@ type ExtraOptions struct { // Tokens are the access tokens which can access the API. Tokens []string + // DeveloperMode turns on features like AddressSearchRoundRewind + DeveloperMode bool + // Respond to Private Network Access preflight requests sent to the indexer. EnablePrivateNetworkAccessHeader bool @@ -146,12 +149,13 @@ func Serve(ctx context.Context, serveAddr string, db idb.IndexerDb, dataError fu } api := ServerImplementation{ - db: db, - dataError: dataError, - timeout: options.handlerTimeout(), - log: log, - disabledParams: disabledMap, - opts: options, + EnableAddressSearchRoundRewind: options.DeveloperMode, + db: db, + dataError: dataError, + timeout: options.handlerTimeout(), + log: log, + disabledParams: disabledMap, + opts: options, } generated.RegisterHandlers(e, &api, middleware...) diff --git a/cmd/algorand-indexer/daemon.go b/cmd/algorand-indexer/daemon.go index 213f21892..faf36608b 100644 --- a/cmd/algorand-indexer/daemon.go +++ b/cmd/algorand-indexer/daemon.go @@ -74,7 +74,7 @@ func DaemonCmd() *cobra.Command { cfg.flags = daemonCmd.Flags() cfg.flags.StringVarP(&cfg.daemonServerAddr, "server", "S", ":8980", "host:port to serve API on (default :8980)") cfg.flags.StringVarP(&cfg.tokenString, "token", "t", "", "an optional auth token, when set REST calls must use this token in a bearer format, or in a 'X-Indexer-API-Token' header") - cfg.flags.BoolVarP(&cfg.developerMode, "dev-mode", "", false, "has no effect currently, reserved for future performance intensive operations") + cfg.flags.BoolVarP(&cfg.developerMode, "dev-mode", "", false, "allow performance intensive operations like searching for accounts at a particular round") cfg.flags.BoolVarP(&cfg.enablePrivateNetworkAccessHeader, "enable-private-network-access-header", "", false, "respond to Private Network Access preflight requests") cfg.flags.StringVarP(&cfg.metricsMode, "metrics-mode", "", "OFF", "configure the /metrics endpoint to [ON, OFF, VERBOSE]") cfg.flags.DurationVarP(&cfg.writeTimeout, "write-timeout", "", 30*time.Second, "set the maximum duration to wait before timing out writes to a http response, breaking connection") @@ -309,6 +309,7 @@ func runDaemon(daemonConfig *daemonConfig) error { // makeOptions converts CLI options to server options func makeOptions(daemonConfig *daemonConfig) (options api.ExtraOptions) { options.EnablePrivateNetworkAccessHeader = daemonConfig.enablePrivateNetworkAccessHeader + options.DeveloperMode = daemonConfig.developerMode if daemonConfig.tokenString != "" { options.Tokens = append(options.Tokens, daemonConfig.tokenString) } From 74edb187164daf98d102ed60e17e08d97a6263f9 Mon Sep 17 00:00:00 2001 From: Agustin Godnic Date: Sun, 22 Dec 2024 13:55:35 -0300 Subject: [PATCH 13/13] Lint --- accounting/rewind.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/accounting/rewind.go b/accounting/rewind.go index 040b0ee98..ea2397a4f 100644 --- a/accounting/rewind.go +++ b/accounting/rewind.go @@ -4,10 +4,11 @@ import ( "context" "fmt" - sdk "github.com/algorand/go-algorand-sdk/v2/types" models "github.com/algorand/indexer/v3/api/generated/v2" "github.com/algorand/indexer/v3/idb" "github.com/algorand/indexer/v3/types" + + sdk "github.com/algorand/go-algorand-sdk/v2/types" ) // ConsistencyError is returned when the database returns inconsistent (stale) results.