From e8fd4cefb1370e7cf58383a2819b290109e04191 Mon Sep 17 00:00:00 2001 From: shawn Date: Mon, 3 Jul 2023 07:17:44 -0700 Subject: [PATCH] merge latest master to soroban-xdr-next-next (#4937) * all: enforce simplified Golang code (#4852) * Update completed sprint on issue/pr closed (#4857) * Bump core image to latest stable release v19.10.0 * Add a simple test for asset case sorting in ascii (#4876) * services/horizon: Suppress Core timeout error (#4860) Suppress Core timeout error when ingestion state machine is in build state. * Update CHANGELOG.md for latest release (#4828) * Bump core image to latest release v19.11.0 (#4885) * services/horizon: Protect 'currentState' variable using Mutex to prevent race condition. (#4889) * services/horizon: Update default for --captive-core-use-db to true (#4877) * 4856: Update default for --captive-core-use-db to true * Update CHANGELOG.md * services/horizon: Improve error handling for when stellar-core crashes (#4893) * Parse LIMIT_TX_QUEUE_SOURCE_ACCOUNT in core config * updated changelog for 2.26.0 release notes * Pinning and updates golang and ubuntu images * services/horizon: Fix ledger endpoint url in HAL (#4928) * Goreplay middleware (#4932) * tools/goreplay-middleware: Add goreplay middleware * Fix linter errors --------- Co-authored-by: Bartek Nowotarski * all: Fix improper use of errors.Wrap (#4926) * all: Fix improper use of errors.Wrap `errors.Wrap` method returns nil if the first argument passed is also nil. If `errors.Wrap` is copied from a condition like `if err != nil` to another one which also returns `errors.Wrap` but does not overwrite `err` before the returned value will always be `nil`. * Update services/horizon/internal/db2/history/claimable_balances.go Co-authored-by: George --------- Co-authored-by: George Co-authored-by: Tsachi Herman <24438559+tsachiherman@users.noreply.github.com> * fix apt repo reference to focal now (#4929) * fixed go fmt on bindata * fixed merge conflict snippet * fixed manual merge commit omition --------- Co-authored-by: Alfonso Acosta Co-authored-by: Paul Bellamy Co-authored-by: Mehmet <119539688+mbsdf@users.noreply.github.com> Co-authored-by: mlo Co-authored-by: urvisavla Co-authored-by: stellarsaur <126507441+stellarsaur@users.noreply.github.com> Co-authored-by: Molly Karcher Co-authored-by: Bartek Nowotarski Co-authored-by: George Co-authored-by: Tsachi Herman <24438559+tsachiherman@users.noreply.github.com> --- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/go.yml | 15 +- .github/workflows/golangci-lint.yml | 2 +- .github/workflows/horizon-master.yml | 2 +- .github/workflows/horizon-release.yml | 4 +- .github/workflows/horizon.yml | 12 +- clients/horizonclient/CHANGELOG.md | 2 + exp/services/recoverysigner/docker/Dockerfile | 4 +- exp/services/webauth/docker/Dockerfile | 4 +- exp/tools/dump-ledger-state/Dockerfile | 2 +- go.mod | 4 +- go.sum | 50 +++++- ingest/ledgerbackend/captive_core_backend.go | 21 +-- .../captive_core_backend_test.go | 45 +++-- services/friendbot/docker/Dockerfile | 4 +- services/horizon/CHANGELOG.md | 26 +++ services/horizon/docker/Dockerfile.dev | 4 +- .../horizon/docker/verify-range/Dockerfile | 4 +- services/horizon/docker/verify-range/start | 4 +- .../db2/history/claimable_balances.go | 2 +- .../horizon/internal/db2/history/orderbook.go | 4 +- .../internal/db2/history/verify_lock.go | 2 +- services/horizon/internal/flags.go | 5 +- .../horizon/internal/resourceadapter/root.go | 2 +- .../scripts/check_release_hash/Dockerfile | 6 +- support/log/main.go | 5 + tools/goreplay-middleware/CHANGELOG.md | 0 tools/goreplay-middleware/README.md | 1 + tools/goreplay-middleware/main.go | 157 ++++++++++++++++++ tools/goreplay-middleware/main_test.go | 49 ++++++ tools/goreplay-middleware/request.go | 99 +++++++++++ tools/goreplay-middleware/request_test.go | 86 ++++++++++ xdr/asset_test.go | 10 ++ 33 files changed, 567 insertions(+), 72 deletions(-) create mode 100644 tools/goreplay-middleware/CHANGELOG.md create mode 100644 tools/goreplay-middleware/README.md create mode 100644 tools/goreplay-middleware/main.go create mode 100644 tools/goreplay-middleware/main_test.go create mode 100644 tools/goreplay-middleware/request.go create mode 100644 tools/goreplay-middleware/request_test.go diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index f0033bba61..9fbf83bbd7 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -15,7 +15,7 @@ on: jobs: analyze: name: Analyze - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 strategy: fail-fast: false diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index fb0bb29b0a..79c6a1daf9 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -9,7 +9,7 @@ jobs: complete: if: always() needs: [check, build, test] - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - if: contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') run: exit 1 @@ -17,9 +17,8 @@ jobs: check: strategy: matrix: - os: [ubuntu-20.04] - # lmao semvers aren't floats never 4get - go: ["1.19.6", "1.20.1"] + os: [ubuntu-22.04] + go: ["1.20"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 @@ -38,8 +37,8 @@ jobs: build: strategy: matrix: - os: [ubuntu-20.04] - go: ["1.19.6", "1.20.1"] + os: [ubuntu-22.04] + go: ["1.19", "1.20"] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 @@ -56,8 +55,8 @@ jobs: test: strategy: matrix: - os: [ubuntu-20.04] - go: ["1.19.6", "1.20.1"] + os: [ubuntu-22.04] + go: ["1.19", "1.20"] pg: [9.6.5, 10] runs-on: ${{ matrix.os }} services: diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 69a61318ad..fe31e4671b 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -12,7 +12,7 @@ permissions: jobs: golangci: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b # version v3.0.2 diff --git a/.github/workflows/horizon-master.yml b/.github/workflows/horizon-master.yml index 556c481b20..e2487a0d64 100644 --- a/.github/workflows/horizon-master.yml +++ b/.github/workflows/horizon-master.yml @@ -8,7 +8,7 @@ jobs: push-state-diff-image: name: Push stellar/ledger-state-diff:{sha,latest} to DockerHub - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v3 diff --git a/.github/workflows/horizon-release.yml b/.github/workflows/horizon-release.yml index 3aee5e49cb..f8dda0ceac 100644 --- a/.github/workflows/horizon-release.yml +++ b/.github/workflows/horizon-release.yml @@ -7,7 +7,7 @@ on: jobs: publish-artifacts: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 name: Upload artifacts to GitHub release steps: - name: Run deprecation tests @@ -22,7 +22,7 @@ jobs: - uses: ./.github/actions/setup-go with: - go-version: "1.20.1" + go-version: "1.20" - name: Check dependencies run: ./gomod.sh diff --git a/.github/workflows/horizon.yml b/.github/workflows/horizon.yml index 5d7493a8b4..b86dc2c360 100644 --- a/.github/workflows/horizon.yml +++ b/.github/workflows/horizon.yml @@ -11,8 +11,8 @@ jobs: name: Integration tests strategy: matrix: - os: [ubuntu-20.04] - go: ["1.19.6", "1.20.1"] + os: [ubuntu-20.04, ubuntu-22.04] + go: ["1.19", "1.20"] pg: [9.6.5] ingestion-backend: [db, captive-core, captive-core-remote-storage] protocol-version: [19, 20] @@ -36,8 +36,8 @@ jobs: HORIZON_INTEGRATION_TESTS_CORE_MAX_SUPPORTED_PROTOCOL: ${{ matrix.protocol-version }} PROTOCOL_20_CORE_DEBIAN_PKG_VERSION: 19.11.1-1357.e38ee728d.focal~sorobanP10 PROTOCOL_20_CORE_DOCKER_IMG: chowbao/stellar-core:19.11.1-1357.e38ee728d.focal-sorobanP10 - PROTOCOL_19_CORE_DEBIAN_PKG_VERSION: 19.5.0-1108.ca2fb0605.focal - PROTOCOL_19_CORE_DOCKER_IMG: stellar/stellar-core:19.5.0-1108.ca2fb0605.focal + PROTOCOL_19_CORE_DEBIAN_PKG_VERSION: 19.11.0-1323.7fb6d5e88.focal + PROTOCOL_19_CORE_DOCKER_IMG: stellar/stellar-core:19.11.0-1323.7fb6d5e88.focal PGHOST: localhost PGPORT: 5432 PGUSER: postgres @@ -108,9 +108,9 @@ jobs: verify-range: name: Test (and push) verify-range image - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: - STELLAR_CORE_VERSION: 19.10.0-1275.bff2c2b37.focal + STELLAR_CORE_VERSION: 19.11.0-1323.7fb6d5e88.focal CAPTIVE_CORE_STORAGE_PATH: /tmp steps: - uses: actions/checkout@v3 diff --git a/clients/horizonclient/CHANGELOG.md b/clients/horizonclient/CHANGELOG.md index ee5cacce2a..aecb94bb9e 100644 --- a/clients/horizonclient/CHANGELOG.md +++ b/clients/horizonclient/CHANGELOG.md @@ -5,6 +5,8 @@ file. This project adheres to [Semantic Versioning](http://semver.org/). ## Unreleased +## [v11.0.0](https://github.com/stellar/go/releases/tag/horizonclient-v11.0.0) - 2023-03-29 + * Type of `AccountSequence` field in `protocols/horizon.Account` was changed to `int64`. ## [v10.0.0](https://github.com/stellar/go/releases/tag/horizonclient-v10.0.0) - 2022-04-18 diff --git a/exp/services/recoverysigner/docker/Dockerfile b/exp/services/recoverysigner/docker/Dockerfile index fed1d7c190..8cd9a72ae6 100644 --- a/exp/services/recoverysigner/docker/Dockerfile +++ b/exp/services/recoverysigner/docker/Dockerfile @@ -1,11 +1,11 @@ -FROM golang:1.19 as build +FROM golang:1.20-bullseye as build ADD . /src/recoverysigner WORKDIR /src/recoverysigner RUN go build -o /bin/recoverysigner ./exp/services/recoverysigner -FROM ubuntu:20.04 +FROM ubuntu:22.04 RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates COPY --from=build /bin/recoverysigner /app/ diff --git a/exp/services/webauth/docker/Dockerfile b/exp/services/webauth/docker/Dockerfile index 4acd1ebf2b..c6bc287d5b 100644 --- a/exp/services/webauth/docker/Dockerfile +++ b/exp/services/webauth/docker/Dockerfile @@ -1,11 +1,11 @@ -FROM golang:1.19 as build +FROM golang:1.20-bullseye as build ADD . /src/webauth WORKDIR /src/webauth RUN go build -o /bin/webauth ./exp/services/webauth -FROM ubuntu:20.04 +FROM ubuntu:22.04 RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates COPY --from=build /bin/webauth /app/ diff --git a/exp/tools/dump-ledger-state/Dockerfile b/exp/tools/dump-ledger-state/Dockerfile index b4405a5ff8..5b53ae2309 100644 --- a/exp/tools/dump-ledger-state/Dockerfile +++ b/exp/tools/dump-ledger-state/Dockerfile @@ -1,6 +1,6 @@ FROM ubuntu:20.04 -ENV STELLAR_CORE_VERSION=19.10.0-1275.bff2c2b37.focal +ENV STELLAR_CORE_VERSION=19.11.0-1323.7fb6d5e88.focal ENV DEBIAN_FRONTEND=noninteractive RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl wget gnupg apt-utils diff --git a/go.mod b/go.mod index fc1da1a0dc..a86b185392 100644 --- a/go.mod +++ b/go.mod @@ -65,6 +65,7 @@ require ( cloud.google.com/go/storage v1.10.0 // indirect github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f // indirect github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 // indirect + github.com/buger/goreplay v1.3.2 github.com/davecgh/go-spew v1.1.1 // indirect github.com/fatih/structs v1.0.0 // indirect github.com/gavv/monotime v0.0.0-20161010190848-47d58efa6955 // indirect @@ -82,7 +83,7 @@ require ( github.com/jstemmer/go-junit-report v0.9.1 // indirect github.com/klauspost/compress v1.15.0 // indirect github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect - github.com/kr/pretty v0.1.0 // indirect + github.com/kr/pretty v0.2.0 // indirect github.com/kr/text v0.1.0 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect @@ -97,7 +98,6 @@ require ( github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 // indirect github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521 // indirect github.com/sergi/go-diff v0.0.0-20161205080420-83532ca1c1ca // indirect - github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 // indirect github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94 // indirect github.com/spf13/jwalterweatherman v0.0.0-20141219030609-3d60171a6431 // indirect github.com/stretchr/objx v0.3.0 // indirect diff --git a/go.sum b/go.sum index b0bd9e3f99..3205cd3894 100644 --- a/go.sum +++ b/go.sum @@ -54,6 +54,8 @@ github.com/Masterminds/squirrel v1.5.0 h1:JukIZisrUXadA9pl3rMkjhiamxiB0cXiu+HGp/ github.com/Masterminds/squirrel v1.5.0/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= github.com/Microsoft/go-winio v0.4.14 h1:+hMXMk01us9KgxGb7ftKQt2Xpf5hH/yky+TDA+qxleU= github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Shopify/sarama v1.26.4/go.mod h1:NbSGBSSndYaIhRcBtY9V0U7AyH+x71bG668AuWys/yU= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/adjust/goautoneg v0.0.0-20150426214442-d788f35a0315 h1:zje9aPr1kQ5nKwjO5MC0S/jehRtNrjfYuLfFRWZH6kY= github.com/adjust/goautoneg v0.0.0-20150426214442-d788f35a0315/go.mod h1:4U522XvlkqOY2AVBUM7ISHODDb6tdB+KAXfGaBDsWts= github.com/ajg/form v0.0.0-20160822230020-523a5da1a92f h1:zvClvFQwU++UpIUBGC8YmDlfhUrweEy1R1Fj1gu5iIM= @@ -62,12 +64,18 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andybalholm/brotli v1.0.4 h1:V7DdXeJtZscaqfNuAdSRuRFzuiKlHSC/Zh3zl9qY3JY= github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= +github.com/araddon/gou v0.0.0-20190110011759-c797efecbb61/go.mod h1:ikc1XA58M+Rx7SEbf0bLJCfBkwayZ8T5jBo5FXK8Uz8= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ= github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go v1.33.2/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go v1.39.5 h1:yoJEE1NJxbpZ3CtPxvOSFJ9ByxiXmBTKk8J+XU5ldtg= github.com/aws/aws-sdk-go v1.39.5/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/bitly/go-hostpool v0.1.0/go.mod h1:4gOCgp6+NZnVqlKyZ/iBZFTAJKembaVENUpMkpg42fw= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= +github.com/buger/goreplay v1.3.2 h1:MFAStZZCsHMPeN5xJ11rhUtV4ZctFRgzSHTfWSWOJsg= +github.com/buger/goreplay v1.3.2/go.mod h1:EyAKHxJR6K6phd0NaoPETSDbJRB/ogIw3Y15UlSbVBM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= @@ -81,6 +89,9 @@ github.com/creachadair/jrpc2 v0.41.1/go.mod h1:k2mGfjsgE2h2Vo12C9NzZguUzzl3gnfGC 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/eapache/go-resiliency v1.2.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/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk= github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -94,6 +105,7 @@ github.com/fatih/structs v1.0.0 h1:BrX964Rv5uQ3wwS+KRUAJCBBw5PQmgJfJ6v4yly5QwU= github.com/fatih/structs v1.0.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.7.2/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/gavv/monotime v0.0.0-20161010190848-47d58efa6955 h1:gmtGRvSexPU4B1T/yYo0sLOKzER1YT+b4kPxPpm0Ty4= @@ -109,8 +121,9 @@ 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-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gobuffalo/packr v1.12.1 h1:+5u3rqgdhswdYXhrX6DHaO7BM4P8oxrbvgZm9H1cRI4= github.com/gobuffalo/packr v1.12.1/go.mod h1:H2dZhQFqHeZwr/5A/uGQkBp7xYuMGuzXFeKhYdcz5No= @@ -148,6 +161,7 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.1/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= @@ -168,6 +182,7 @@ 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-querystring v0.0.0-20160401233042-9235644dd9e5 h1:oERTZ1buOUYlpmKaqlO5fYmz8cZ1rYu5DieJzF4ZVmU= github.com/google/go-querystring v0.0.0-20160401233042-9235644dd9e5/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/gopacket v1.1.20-0.20210429153827-3eaba0894325/go.mod h1:riddUzxTSBpJXk3qBHtYr4qOhFhT6k/1c0E3qkQjQpA= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= 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= @@ -202,6 +217,7 @@ github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY4 github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/guregu/null v2.1.3-0.20151024101046-79c5bd36b615+incompatible h1:SZmF1M6CdAm4MmTPYYTG+x9EC8D3FOxUq9S4D37irQg= github.com/guregu/null v2.1.3-0.20151024101046-79c5bd36b615+incompatible/go.mod h1:ePGpQaN9cw0tj45IR5E5ehMvsFlLlQZAkkOXZurJ3NM= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -219,6 +235,8 @@ github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NH github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jarcoal/httpmock v0.0.0-20161210151336-4442edb3db31 h1:Aw95BEvxJ3K6o9GGv5ppCd1P8hkeIeEJ30FO+OhOJpM= github.com/jarcoal/httpmock v0.0.0-20161210151336-4442edb3db31/go.mod h1:ks+b9deReOc7jgqp+e7LuFiCBH6Rm5hL32cLcEAArb4= +github.com/jcmturner/gofork v1.0.0/go.mod h1:MK8+TM0La+2rjBD4jE12Kj1pCCxK7d2LK/UM3ncEo0o= +github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= @@ -232,13 +250,16 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.10.10/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.15.0 h1:xqfchp4whNFxn5A4XFyyYtitiWI8Hy5EW59jEwcyL6U= github.com/klauspost/compress v1.15.0/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= -github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -253,6 +274,7 @@ github.com/magiconair/properties v1.5.4 h1:5Y3GEEL4cWijFkb6jtcVs3lX2EWA1ZKq64qu9 github.com/magiconair/properties v1.5.4/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/manucorporat/sse v0.0.0-20160126180136-ee05b128a739 h1:ykXz+pRRTibcSjG1yRhpdSHInF8yZY/mfn+Rz2Nd1rE= github.com/manucorporat/sse v0.0.0-20160126180136-ee05b128a739/go.mod h1:zUx1mhth20V3VKgL5jbd1BSQcW4Fy6Qs4PZvQwRFwzM= +github.com/mattbaird/elastigo v0.0.0-20170123220020-2fe47fd29e4b/go.mod h1:5MWrJXKRQyhQdUCF+vu6U5c4nQpg70vW3eHaU0/AYbU= github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= @@ -277,6 +299,8 @@ github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsq github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pelletier/go-toml v1.9.0 h1:NOd0BRdOKpPf0SxkL3HxSQOG7rNh+4kl6PHcBPFs7Q0= github.com/pelletier/go-toml v1.9.0/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pierrec/lz4 v2.4.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= 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= @@ -295,6 +319,8 @@ github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1 h1:/K3IL0Z1quvmJ7X0A1AwNEK7CRkVK3YwfOU/QAL4WGg= github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= @@ -315,8 +341,8 @@ github.com/sirupsen/logrus v1.4.1 h1:GL2rEmy6nsikmW0r8opw9JIRScdMF5hA8cOYLH7In1k github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337 h1:WN9BUFbdyOsSH/XohnWpXOlq9NBD5sGAB2FciQMUEe8= -github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94 h1:JmfC365KywYwHB946TTiQWEb8kqPY+pybPLoGE9GgVk= github.com/spf13/cast v0.0.0-20150508191742-4d07383ffe94/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= github.com/spf13/cobra v0.0.0-20160830174925-9c28e4bbd74e h1:YdP6GKJS0Ls++kXc85WCCX2ArKToqixBwpBrWP/5J/k= @@ -349,6 +375,11 @@ github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyC github.com/valyala/fasthttp v1.34.0 h1:d3AAQJ2DRcxJYHm7OXNXtXt2as1vMDfxeIcFvhmGGm4= github.com/valyala/fasthttp v1.34.0/go.mod h1:epZA5N+7pY6ZaEKRmstzOuYJx9HI8DI1oaCGZpdH4h0= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c/go.mod h1:lB8K/P019DLNhemzwFU4jHLhdvlE6uDZjXFejJXr49I= +github.com/xdg/stringprep v1.0.0/go.mod h1:Jhud4/sHMO4oL310DaZAKk9ZaJ08SJfe+sJh0HrGL1Y= github.com/xdrpp/goxdr v0.1.1 h1:E1B2c6E8eYhOVyd7yEpOyopzTPirUeF6mVOfXfGyJyc= github.com/xdrpp/goxdr v0.1.1/go.mod h1:dXo1scL/l6s7iME1gxHWo2XCppbHEKZS7m/KyYWkNzA= github.com/xeipuuv/gojsonpointer v0.0.0-20151027082146-e0fe6f683076 h1:KM4T3G70MiR+JtqplcYkNVoNz7pDwYaBxWBXQK804So= @@ -385,6 +416,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk 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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE= golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= @@ -510,6 +542,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 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-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -519,6 +552,7 @@ golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -743,8 +777,9 @@ google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/l google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= 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 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= @@ -752,6 +787,11 @@ gopkg.in/gavv/httpexpect.v1 v1.0.0-20170111145843-40724cf1e4a0 h1:r5ptJ1tBxVAeqw gopkg.in/gavv/httpexpect.v1 v1.0.0-20170111145843-40724cf1e4a0/go.mod h1:WtiW9ZA1LdaWqtQRo1VbIL/v4XZ8NDta+O/kSpGgVek= gopkg.in/gorp.v1 v1.7.1 h1:GBB9KrWRATQZh95HJyVGUZrWwOPswitEYEyqlK8JbAA= gopkg.in/gorp.v1 v1.7.1/go.mod h1:Wo3h+DBQZIxATwftsglhdD/62zRFPhGhTiu5jUJmCaw= +gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= +gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= +gopkg.in/jcmturner/goidentity.v3 v3.0.0/go.mod h1:oG2kH0IvSYNIu80dVAyu/yoefjq1mNfM5bm88whjWx4= +gopkg.in/jcmturner/gokrb5.v7 v7.5.0/go.mod h1:l8VISx+WGYp+Fp7KRbsiUuXTTOnxIc3Tuvyavf11/WM= +gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLvuNnlv8= gopkg.in/square/go-jose.v2 v2.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y= gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= diff --git a/ingest/ledgerbackend/captive_core_backend.go b/ingest/ledgerbackend/captive_core_backend.go index a0f7c99821..aa9414b5d1 100644 --- a/ingest/ledgerbackend/captive_core_backend.go +++ b/ingest/ledgerbackend/captive_core_backend.go @@ -683,25 +683,26 @@ func (c *CaptiveStellarCore) handleMetaPipeResult(sequence uint32, result metaRe } func (c *CaptiveStellarCore) checkMetaPipeResult(result metaResult, ok bool) error { - // There are 3 types of errors we check for: + // There are 4 error scenarios we check for: // 1. User initiated shutdown by canceling the parent context or calling Close(). - // 2. The stellar core process exited unexpectedly. + // 2. The stellar core process exited unexpectedly with an error message. // 3. Some error was encountered while consuming the ledgers emitted by captive core (e.g. parsing invalid xdr) + // 4. The stellar core process exited unexpectedly without an error message if err := c.stellarCoreRunner.context().Err(); err != nil { // Case 1 - User initiated shutdown by canceling the parent context or calling Close() return err } if !ok || result.err != nil { - if result.err != nil { + exited, err := c.stellarCoreRunner.getProcessExitError() + if exited && err != nil { + // Case 2 - The stellar core process exited unexpectedly with an error message + return errors.Wrap(err, "stellar core exited unexpectedly") + } else if result.err != nil { // Case 3 - Some error was encountered while consuming the ledger stream emitted by captive core. return result.err - } else if exited, err := c.stellarCoreRunner.getProcessExitError(); exited { - // Case 2 - The stellar core process exited unexpectedly - if err == nil { - return errors.Errorf("stellar core exited unexpectedly") - } else { - return errors.Wrap(err, "stellar core exited unexpectedly") - } + } else if exited { + // case 4 - The stellar core process exited unexpectedly without an error message + return errors.Errorf("stellar core exited unexpectedly") } else if !ok { // This case should never happen because the ledger buffer channel can only be closed // if and only if the process exits or the context is canceled. diff --git a/ingest/ledgerbackend/captive_core_backend_test.go b/ingest/ledgerbackend/captive_core_backend_test.go index df8ad1ce59..78772a41ea 100644 --- a/ingest/ledgerbackend/captive_core_backend_test.go +++ b/ingest/ledgerbackend/captive_core_backend_test.go @@ -1032,6 +1032,7 @@ func TestCaptiveGetLedger_ErrReadingMetaResult(t *testing.T) { mockRunner.On("close").Return(nil).Run(func(args mock.Arguments) { cancel() }).Once() + mockRunner.On("getProcessExitError").Return(false, nil) // even if the request to fetch the latest checkpoint succeeds, we should fail at creating the subprocess mockArchive := &historyarchive.MockArchive{} @@ -1217,17 +1218,19 @@ func TestGetLedgerBoundsCheck(t *testing.T) { mockRunner.AssertExpectations(t) } -func TestCaptiveGetLedgerTerminatedUnexpectedly(t *testing.T) { +type GetLedgerTerminatedTestCase struct { + name string + ctx context.Context + ledgers []metaResult + processExited bool + processExitedError error + expectedError string +} + +func CaptiveGetLedgerTerminatedUnexpectedlyTestCases() []GetLedgerTerminatedTestCase { ledger64 := buildLedgerCloseMeta(testLedgerHeader{sequence: uint32(64)}) - for _, testCase := range []struct { - name string - ctx context.Context - ledgers []metaResult - processExited bool - processExitedError error - expectedError string - }{ + return []GetLedgerTerminatedTestCase{ { "stellar core exited unexpectedly without error", context.Background(), @@ -1268,7 +1271,29 @@ func TestCaptiveGetLedgerTerminatedUnexpectedly(t *testing.T) { nil, "meta pipe closed unexpectedly", }, - } { + { + "Parser error while reading from the pipe resulting in stellar-core exit", + context.Background(), + []metaResult{{LedgerCloseMeta: &ledger64}, + {LedgerCloseMeta: nil, err: errors.New("Parser error")}}, + true, + nil, + "Parser error", + }, + { + "stellar core exited unexpectedly with an error resulting in meta pipe closed", + context.Background(), + []metaResult{{LedgerCloseMeta: &ledger64}, + {LedgerCloseMeta: &ledger64, err: errors.New("EOF while decoding")}}, + true, + fmt.Errorf("signal kill"), + "stellar core exited unexpectedly: signal kill", + }, + } +} + +func TestCaptiveGetLedgerTerminatedUnexpectedly(t *testing.T) { + for _, testCase := range CaptiveGetLedgerTerminatedUnexpectedlyTestCases() { t.Run(testCase.name, func(t *testing.T) { metaChan := make(chan metaResult, 100) diff --git a/services/friendbot/docker/Dockerfile b/services/friendbot/docker/Dockerfile index 24c0ca3120..dc1c74b93f 100644 --- a/services/friendbot/docker/Dockerfile +++ b/services/friendbot/docker/Dockerfile @@ -1,10 +1,10 @@ -FROM golang:1.19.1 as build +FROM golang:1.20-bullseye as build ADD . /src/friendbot WORKDIR /src/friendbot RUN go build -o /bin/friendbot ./services/friendbot -FROM ubuntu:20.04 +FROM ubuntu:22.04 RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ca-certificates COPY --from=build /bin/friendbot /app/ diff --git a/services/horizon/CHANGELOG.md b/services/horizon/CHANGELOG.md index 6e2cd9046b..dda43c7d6d 100644 --- a/services/horizon/CHANGELOG.md +++ b/services/horizon/CHANGELOG.md @@ -10,6 +10,32 @@ file. This project adheres to [Semantic Versioning](http://semver.org/). - Update XDR definitions for soroban usage ([4576](https://github.com/stellar/go/pull/4576)) - Include InvokeHostFunction Details on Operation API resources ([4608](https://github.com/stellar/go/pull/4608)) + +## 2.26.0 +### Changes +- Improve error handling for when stellar-core crashes ([4893](https://github.com/stellar/go/pull/4893)) +- Suppress Core timeout error in log output such as `error ticking app: context deadline exceeded` when ingestion state machine is in build state. ([4860](https://github.com/stellar/go/pull/4860)) + + +### Breaking Changes +- Modify the default value of `--captive-core-use-db` to true ([4856](https://github.com/stellar/go/issues/4856)) + - This updates the default behavior of captive core to start in on-disk mode. + - To continue using the previous in-memory mode, explicitly set the `--captive-core-use-db` flag to false + +## 2.25.0 + +### Changes + +- Running Horizon with remote captive core is now deprecated ([4826](https://github.com/stellar/go/pull/4826)). +- Add two new configuration variables to control the behavior of state verification ([4821](https://github.com/stellar/go/pull/4821)): + - `--ingest-state-verification-frequency` which specifies the frequency in checkpoints for how often state verification is run + - `--ingest-state-verification-timeout` which specifies a timeout on how long state verification can run + +### Fixes + +* Fix crash in horizon ingestion when running horizon with a remote captive core ([4824](https://github.com/stellar/go/pull/4824)). + + ## 2.24.1 ### Changes diff --git a/services/horizon/docker/Dockerfile.dev b/services/horizon/docker/Dockerfile.dev index ab0b9cd301..1d1be8d688 100644 --- a/services/horizon/docker/Dockerfile.dev +++ b/services/horizon/docker/Dockerfile.dev @@ -1,4 +1,4 @@ -FROM golang:1.20 AS builder +FROM golang:1.20-bullseye AS builder ARG VERSION="devel" WORKDIR /go/src/github.com/stellar/go @@ -8,7 +8,7 @@ COPY . ./ ENV GOFLAGS="-ldflags=-X=github.com/stellar/go/support/app.version=${VERSION}-(built-from-source)" RUN go install github.com/stellar/go/services/horizon -FROM ubuntu:20.04 +FROM ubuntu:22.04 ARG STELLAR_CORE_VERSION ENV STELLAR_CORE_VERSION=${STELLAR_CORE_VERSION:-*} ENV STELLAR_CORE_BINARY_PATH /usr/bin/stellar-core diff --git a/services/horizon/docker/verify-range/Dockerfile b/services/horizon/docker/verify-range/Dockerfile index 499f86881e..56f8c84796 100644 --- a/services/horizon/docker/verify-range/Dockerfile +++ b/services/horizon/docker/verify-range/Dockerfile @@ -1,6 +1,4 @@ -FROM ubuntu:20.04 - -MAINTAINER Bartek Nowotarski +FROM ubuntu:22.04 ARG STELLAR_CORE_VERSION ENV STELLAR_CORE_VERSION=${STELLAR_CORE_VERSION:-*} diff --git a/services/horizon/docker/verify-range/start b/services/horizon/docker/verify-range/start index 3402670ac2..7d29ab886b 100644 --- a/services/horizon/docker/verify-range/start +++ b/services/horizon/docker/verify-range/start @@ -8,8 +8,8 @@ fi rm -rf "$PGDATA"/* sudo chown -R postgres "$PGDATA" sudo chmod -R 775 "$PGDATA" -sudo -u postgres --preserve-env=PGDATA /usr/lib/postgresql/12/bin/initdb -sudo -u postgres --preserve-env=PGDATA /usr/lib/postgresql/12/bin/pg_ctl start +sudo -u postgres --preserve-env=PGDATA /usr/lib/postgresql/14/bin/initdb +sudo -u postgres --preserve-env=PGDATA /usr/lib/postgresql/14/bin/pg_ctl start sudo -u postgres createdb horizon sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';" diff --git a/services/horizon/internal/db2/history/claimable_balances.go b/services/horizon/internal/db2/history/claimable_balances.go index 3fe4029dc3..ece94c390b 100644 --- a/services/horizon/internal/db2/history/claimable_balances.go +++ b/services/horizon/internal/db2/history/claimable_balances.go @@ -47,7 +47,7 @@ func (cbq ClaimableBalancesQuery) Cursor() (int64, string, error) { } r = parts[1] if l < 0 { - return l, r, errors.Wrap(err, "Invalid cursor - first value should be higher than 0") + return l, r, errors.New("invalid cursor - first value should be higher than 0") } } diff --git a/services/horizon/internal/db2/history/orderbook.go b/services/horizon/internal/db2/history/orderbook.go index 3de321a4ac..ab3237795f 100644 --- a/services/horizon/internal/db2/history/orderbook.go +++ b/services/horizon/internal/db2/history/orderbook.go @@ -117,7 +117,7 @@ func (q *Q) GetOrderBookSummary(ctx context.Context, sellingAsset, buyingAsset x // we don't expect there to be any inconsistency between levels and offers because // this function should only be invoked in a repeatable read transaction if len(levels) != len(offers) { - return result, errors.Wrap(err, "price levels length does not match summaries length") + return result, errors.New("price levels length does not match summaries length") } for i, level := range levels { sum := offers[i] @@ -151,7 +151,7 @@ func (q *Q) GetOrderBookSummary(ctx context.Context, sellingAsset, buyingAsset x } else if sum.Type == "bid" { result.Bids = append(result.Bids, entry) } else { - return result, errors.Wrap(err, "invalid offer type") + return result, errors.New("invalid offer type") } } diff --git a/services/horizon/internal/db2/history/verify_lock.go b/services/horizon/internal/db2/history/verify_lock.go index 6b7d5910e8..f56045e9b1 100644 --- a/services/horizon/internal/db2/history/verify_lock.go +++ b/services/horizon/internal/db2/history/verify_lock.go @@ -32,7 +32,7 @@ func (q *Q) TryStateVerificationLock(ctx context.Context) (bool, error) { return false, errors.Wrap(err, "error acquiring advisory lock for state verification") } if len(acquired) != 1 { - return false, errors.Wrap(err, "invalid response from advisory lock") + return false, errors.New("invalid response from advisory lock") } return acquired[0], nil } diff --git a/services/horizon/internal/flags.go b/services/horizon/internal/flags.go index e13ff923e6..c2e6cbff4c 100644 --- a/services/horizon/internal/flags.go +++ b/services/horizon/internal/flags.go @@ -177,7 +177,7 @@ func Flags() (*Config, support.ConfigOptions) { &support.ConfigOption{ Name: CaptiveCoreConfigUseDB, OptType: types.Bool, - FlagDefault: false, + FlagDefault: true, Required: false, Usage: `when enabled, Horizon ingestion will instruct the captive core invocation to use an external db url for ledger states rather than in memory(RAM).\n @@ -736,9 +736,6 @@ func ApplyFlags(config *Config, flags support.ConfigOptions, options ApplyOption if config.StellarCoreDatabaseURL != "" { return fmt.Errorf("Invalid config: --%s passed but --ingest not set. ", StellarCoreDBURLFlagName) } - if config.CaptiveCoreConfigUseDB { - return fmt.Errorf("Invalid config: --%s has been set, but --ingest not set. ", CaptiveCoreConfigUseDB) - } } // Configure log file diff --git a/services/horizon/internal/resourceadapter/root.go b/services/horizon/internal/resourceadapter/root.go index eb2656605d..91a72616ea 100644 --- a/services/horizon/internal/resourceadapter/root.go +++ b/services/horizon/internal/resourceadapter/root.go @@ -46,7 +46,7 @@ func PopulateRoot( dest.Links.AccountTransactions = lb.PagedLink("/accounts/{account_id}/transactions") dest.Links.Assets = lb.Link("/assets{?asset_code,asset_issuer,cursor,limit,order}") dest.Links.Effects = lb.Link("/effects{?cursor,limit,order}") - dest.Links.Ledger = lb.Link("/ledger/{sequence}") + dest.Links.Ledger = lb.Link("/ledgers/{sequence}") dest.Links.Ledgers = lb.Link("/ledgers{?cursor,limit,order}") dest.Links.FeeStats = lb.Link("/fee_stats") dest.Links.Operation = lb.Link("/operations/{id}") diff --git a/services/horizon/internal/scripts/check_release_hash/Dockerfile b/services/horizon/internal/scripts/check_release_hash/Dockerfile index a323a4eb6d..6a054aab34 100644 --- a/services/horizon/internal/scripts/check_release_hash/Dockerfile +++ b/services/horizon/internal/scripts/check_release_hash/Dockerfile @@ -1,5 +1,5 @@ # Change to Go version used in CI or rebuild with --build-arg. -ARG GO_IMAGE=golang:1.19.1 +ARG GO_IMAGE=golang:1.20-bullseye FROM $GO_IMAGE WORKDIR /go/src/github.com/stellar/go @@ -8,8 +8,8 @@ ENV DEBIAN_FRONTEND=noninteractive # ca-certificates are required to make tls connections RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl wget gnupg apt-utils git zip unzip apt-transport-https ca-certificates RUN wget -qO - https://apt.stellar.org/SDF.asc | APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE=true apt-key add - -RUN echo "deb https://apt.stellar.org xenial stable" >/etc/apt/sources.list.d/SDF.list -RUN echo "deb https://apt.stellar.org xenial testing" >/etc/apt/sources.list.d/SDF-testing.list +RUN echo "deb https://apt.stellar.org focal stable" >/etc/apt/sources.list.d/SDF.list +RUN echo "deb https://apt.stellar.org focal testing" >/etc/apt/sources.list.d/SDF-testing.list RUN git clone https://github.com/stellar/go.git /go/src/github.com/stellar/go # Fetch dependencies and prebuild binaries. Not necessary but will make check faster. diff --git a/support/log/main.go b/support/log/main.go index b27472246c..ce5f80cc04 100644 --- a/support/log/main.go +++ b/support/log/main.go @@ -2,6 +2,7 @@ package log import ( "context" + "io" "os" "github.com/segmentio/go-loggly" @@ -80,6 +81,10 @@ func SetLevel(level logrus.Level) { DefaultLogger.SetLevel(level) } +func SetOut(out io.Writer) { + DefaultLogger.entry.Logger.Out = out +} + func WithField(key string, value interface{}) *Entry { result := DefaultLogger.WithField(key, value) return result diff --git a/tools/goreplay-middleware/CHANGELOG.md b/tools/goreplay-middleware/CHANGELOG.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tools/goreplay-middleware/README.md b/tools/goreplay-middleware/README.md new file mode 100644 index 0000000000..87ebde01f4 --- /dev/null +++ b/tools/goreplay-middleware/README.md @@ -0,0 +1 @@ +# goreplay-middleware \ No newline at end of file diff --git a/tools/goreplay-middleware/main.go b/tools/goreplay-middleware/main.go new file mode 100644 index 0000000000..89e1e23a73 --- /dev/null +++ b/tools/goreplay-middleware/main.go @@ -0,0 +1,157 @@ +// The code below is a goreplay middleware used for regression testing current +// vs next Horizon version. The middleware system of goreplay is rather simple: +// it streams one of 3 message types to stdin: request (HTTP headers), +// original response and replayed response. On request we can modify the request +// and send it to stdout but we don't use this feature here: we send request +// to mirroring target as is. Finally, everything printed to stderr is the +// middleware log, this is where we put the information about the request if the +// diff is found. +// +// More information and diagrams about the middlewares can be found here: +// https://github.com/buger/goreplay/wiki/Middleware +package main + +import ( + "bufio" + "bytes" + "encoding/hex" + "fmt" + "io" + "os" + "time" + + "github.com/buger/goreplay/proto" + "github.com/stellar/go/support/log" +) + +// maxPerSecond defines how many requests should be checked at max per second +const maxPerSecond = 100 + +const ( + requestType byte = '1' + originalResponseType byte = '2' + replayedResponseType byte = '3' +) + +var lastCheck = time.Now() +var reqsCheckedPerSeq = 0 +var pendingRequestsAdded, ignoredCount, diffsCount, okCount int64 +var pendingRequests = make(map[string]*Request) + +func main() { + processAll(os.Stdin, os.Stderr, os.Stdout) +} + +func processAll(stdin io.Reader, stderr, stdout io.Writer) { + log.SetOut(stderr) + log.SetLevel(log.InfoLevel) + + bufSize := 20 * 1024 * 1024 // 20MB + scanner := bufio.NewScanner(stdin) + buf := make([]byte, bufSize) + scanner.Buffer(buf, bufSize) + var maxPendingRequests = 2000 + + for scanner.Scan() { + encoded := scanner.Bytes() + buf := make([]byte, len(encoded)/2) + _, err := hex.Decode(buf, encoded) + if err != nil { + os.Stderr.WriteString(fmt.Sprintf("hex.Decode error: %v", err)) + continue + } + + if err := scanner.Err(); err != nil { + os.Stderr.WriteString(fmt.Sprintf("scanner.Err(): %v\n", err)) + } + + process(stderr, stdout, buf) + + if len(pendingRequests) > maxPendingRequests { + // Around 3-4% of responses is lost (not sure why) so pendingRequests can grow + // indefinitely. Let's just truncate it when it becomes too big. + // There is one gotcha here. Goreplay will still send requests + // (`1` type payloads) even if traffic is rate limited. So if rate + // limit is applied even more requests can be lost. So we should + // use rate limiting implemented here when using middleware rather than + // Goreplay's rate limit. + pendingRequests = make(map[string]*Request) + } + } +} + +func process(stderr, stdout io.Writer, buf []byte) { + // First byte indicate payload type: + payloadType := buf[0] + headerSize := bytes.IndexByte(buf, '\n') + 1 + header := buf[:headerSize-1] + + // Header contains space separated values of: request type, request id, and request start time (or round-trip time for responses) + meta := bytes.Split(header, []byte(" ")) + // For each request you should receive 3 payloads (request, response, replayed response) with same request id + reqID := string(meta[1]) + payload := buf[headerSize:] + + switch payloadType { + case requestType: + if time.Since(lastCheck) > time.Second { + reqsCheckedPerSeq = 0 + lastCheck = time.Now() + + // Print stats every second + _, _ = os.Stderr.WriteString(fmt.Sprintf( + "middleware stats: pendingRequests=%d requestsAdded=%d ok=%d diffs=%d ignored=%d\n", + len(pendingRequests), + pendingRequestsAdded, + okCount, + diffsCount, + ignoredCount, + )) + } + + if reqsCheckedPerSeq < maxPerSecond { + pendingRequests[reqID] = &Request{ + Headers: payload, + } + pendingRequestsAdded++ + reqsCheckedPerSeq++ + } + + // Emitting data back, without modification + _, err := io.WriteString(stdout, hex.EncodeToString(buf)+"\n") + if err != nil { + _, _ = io.WriteString(stderr, fmt.Sprintf("stdout.WriteString error: %v", err)) + } + case originalResponseType: + if req, ok := pendingRequests[reqID]; ok { + // Original response can arrive after mirrored so this should be improved + // instead of ignoring this case. + req.OriginalResponse = payload + } + case replayedResponseType: + if req, ok := pendingRequests[reqID]; ok { + req.MirroredResponse = payload + + if req.IsIgnored() { + ignoredCount++ + } else { + if !req.ResponseEquals() { + // TODO in the future publish the results to S3 for easier processing + log.WithFields(log.F{ + "expected": req.OriginalBody(), + "actual": req.MirroredBody(), + "headers": string(req.Headers), + "path": string(proto.Path(req.Headers)), + }).Info("Mismatch found") + diffsCount++ + } else { + okCount++ + } + } + + delete(pendingRequests, reqID) + } + default: + _, _ = io.WriteString(stderr, "Unknown message type\n") + } +} diff --git a/tools/goreplay-middleware/main_test.go b/tools/goreplay-middleware/main_test.go new file mode 100644 index 0000000000..42cbcafd13 --- /dev/null +++ b/tools/goreplay-middleware/main_test.go @@ -0,0 +1,49 @@ +package main + +import ( + "bytes" + "encoding/hex" + "strings" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestProcess(t *testing.T) { + // For 1 type, it returns the same msg to stdout + payload := "1 ID\nGET /ledgers HTTP/1.1\r\nHost: horizon.stellar.org\r\n\r\n" + stdin := strings.NewReader(hex.EncodeToString([]byte(payload))) + + stdout := bytes.Buffer{} + stderr := bytes.Buffer{} + processAll(stdin, &stderr, &stdout) + + decodedOut, err := hex.DecodeString(strings.TrimRight(stdout.String(), "\n")) + assert.NoError(t, err) + assert.Equal(t, payload, string(decodedOut)) + assert.Equal(t, "", stderr.String()) + + // For 2 type, save the original response + payload = "2 ID\nHeader: true\r\n\r\nBody" + stdin = strings.NewReader(hex.EncodeToString([]byte(payload))) + + stdout = bytes.Buffer{} + stderr = bytes.Buffer{} + processAll(stdin, &stderr, &stdout) + + assert.Len(t, pendingRequests, 1) + assert.Equal(t, "", stdout.String()) + assert.Equal(t, "", stderr.String()) + + // For 2 type, save the original response + payload = "3 ID\nHeader: true\r\n\r\nBody" + stdin = strings.NewReader(hex.EncodeToString([]byte(payload))) + + stdout = bytes.Buffer{} + stderr = bytes.Buffer{} + processAll(stdin, &stderr, &stdout) + + assert.Len(t, pendingRequests, 0) + assert.Equal(t, "", stdout.String()) + assert.Equal(t, "", stderr.String()) +} diff --git a/tools/goreplay-middleware/request.go b/tools/goreplay-middleware/request.go new file mode 100644 index 0000000000..165971f725 --- /dev/null +++ b/tools/goreplay-middleware/request.go @@ -0,0 +1,99 @@ +package main + +import ( + "bytes" + "regexp" + "strings" + + "github.com/buger/goreplay/proto" +) + +var horizonURLs = regexp.MustCompile(`https:\/\/.*?(stellar\.org|127.0.0.1:8000)`) +var findResultMetaXDR = regexp.MustCompile(`"result_meta_xdr":[ ]?"([^"]*)",`) + +// removeRegexps contains a list of regular expressions that, when matched, +// will be changed to an empty string. This is done to exclude known +// differences in responses between two Horizon version. +// +// Let's say that next Horizon version adds a new bool field: +// `is_authorized` on account balances list. You want to remove this +// field so it's not reported for each `/accounts/{id}` response. +var removeRegexps = []*regexp.Regexp{} + +type replace struct { + regexp *regexp.Regexp + repl string +} + +// replaceRegexps works like removeRegexps but replaces data +var replaceRegexps = []replace{} + +type Request struct { + Headers []byte + OriginalResponse []byte + MirroredResponse []byte +} + +func (r *Request) OriginalBody() string { + return string(proto.Body(r.OriginalResponse)) +} + +func (r *Request) MirroredBody() string { + return string(proto.Body(r.MirroredResponse)) +} + +func (r *Request) IsIgnored() bool { + if len(r.OriginalResponse) == 0 { + return true + } + + originalLatestLedgerHeader := proto.Header(r.OriginalResponse, []byte("Latest-Ledger")) + mirroredLatestLedgerHeader := proto.Header(r.MirroredResponse, []byte("Latest-Ledger")) + + if !bytes.Equal(originalLatestLedgerHeader, mirroredLatestLedgerHeader) { + return true + } + + // Responses below are not supported but support can be added with some effort + originalTransferEncodingHeader := proto.Header(r.OriginalResponse, []byte("Transfer-Encoding")) + mirroredTransferEncodingHeader := proto.Header(r.MirroredResponse, []byte("Transfer-Encoding")) + if len(originalTransferEncodingHeader) > 0 || + len(mirroredTransferEncodingHeader) > 0 { + return true + } + + acceptEncodingHeader := proto.Header(r.Headers, []byte("Accept-Encoding")) + if strings.Contains(string(acceptEncodingHeader), "gzip") { + return true + } + + acceptHeader := proto.Header(r.Headers, []byte("Accept")) + return strings.Contains(string(acceptHeader), "event-stream") +} + +func (r *Request) ResponseEquals() bool { + originalBody := proto.Body(r.OriginalResponse) + mirroredBody := proto.Body(r.MirroredResponse) + + return normalizeResponseBody(originalBody) == normalizeResponseBody(mirroredBody) +} + +// normalizeResponseBody normalizes body to allow byte-byte comparison like removing +// URLs from _links or tx meta. May require updating on new releases. +func normalizeResponseBody(body []byte) string { + normalizedBody := string(body) + // `result_meta_xdr` can differ between core instances (confirmed this with core team) + normalizedBody = findResultMetaXDR.ReplaceAllString(normalizedBody, "") + // Remove Horizon URL from the _links + normalizedBody = horizonURLs.ReplaceAllString(normalizedBody, "") + + for _, reg := range removeRegexps { + normalizedBody = reg.ReplaceAllString(normalizedBody, "") + } + + for _, reg := range replaceRegexps { + normalizedBody = reg.regexp.ReplaceAllString(normalizedBody, reg.repl) + } + + return normalizedBody +} diff --git a/tools/goreplay-middleware/request_test.go b/tools/goreplay-middleware/request_test.go new file mode 100644 index 0000000000..3ba2072096 --- /dev/null +++ b/tools/goreplay-middleware/request_test.go @@ -0,0 +1,86 @@ +package main + +import ( + "testing" +) + +func TestNormalizeResponseBody(t *testing.T) { + //nolint:all + resp := `{ + "_links": { + "self": { + "href": "https://horizon-testnet.stellar.org/transactions?cursor=\u0026limit=1\u0026order=desc" + }, + "next": { + "href": "https://horizon-testnet.stellar.org/transactions?cursor=2892102128111616\u0026limit=1\u0026order=desc" + }, + "prev": { + "href": "https://horizon-testnet.stellar.org/transactions?cursor=2892102128111616\u0026limit=1\u0026order=asc" + } + }, + "_embedded": { + "records": [ + { + "_links": { + "self": { + "href": "https://horizon-testnet.stellar.org/transactions/cfc6395b98ed0c5ad63bd808e6b5ec994c3ccc67814945d3c652659b5077da18" + }, + "account": { + "href": "https://horizon-testnet.stellar.org/accounts/GBW7BTQDKVMB62NXB3Z55NZCENRBD4O4OE7YBKBOG4K4DM4QK76L2DJD" + }, + "ledger": { + "href": "https://horizon-testnet.stellar.org/ledgers/673370" + }, + "operations": { + "href": "https://horizon-testnet.stellar.org/transactions/cfc6395b98ed0c5ad63bd808e6b5ec994c3ccc67814945d3c652659b5077da18/operations{?cursor,limit,order}", + "templated": true + }, + "effects": { + "href": "https://horizon-testnet.stellar.org/transactions/cfc6395b98ed0c5ad63bd808e6b5ec994c3ccc67814945d3c652659b5077da18/effects{?cursor,limit,order}", + "templated": true + }, + "precedes": { + "href": "https://horizon-testnet.stellar.org/transactions?order=asc\u0026cursor=2892102128111616" + }, + "succeeds": { + "href": "https://horizon-testnet.stellar.org/transactions?order=desc\u0026cursor=2892102128111616" + }, + "transaction": { + "href": "https://horizon-testnet.stellar.org/transactions/cfc6395b98ed0c5ad63bd808e6b5ec994c3ccc67814945d3c652659b5077da18" + } + }, + "id": "cfc6395b98ed0c5ad63bd808e6b5ec994c3ccc67814945d3c652659b5077da18", + "paging_token": "2892102128111616", + "successful": true, + "hash": "cfc6395b98ed0c5ad63bd808e6b5ec994c3ccc67814945d3c652659b5077da18", + "ledger": 673370, + "created_at": "2022-08-02T12:34:28Z", + "source_account": "GBW7BTQDKVMB62NXB3Z55NZCENRBD4O4OE7YBKBOG4K4DM4QK76L2DJD", + "source_account_sequence": "2892097833140225", + "fee_account": "GBW7BTQDKVMB62NXB3Z55NZCENRBD4O4OE7YBKBOG4K4DM4QK76L2DJD", + "fee_charged": "10000000", + "max_fee": "10000000", + "operation_count": 1, + "envelope_xdr": "AAAAAgAAAABt8M4DVVgfabcO8963IiNiEfHccT+AqC43FcGzkFf8vQCYloAACkZZAAAAAQAAAAEAAAAAAAAAAAAAAABi6RnwAAAAAAAAAAEAAAAAAAAACAAAAABKBB+2UBMP/abwcm/M1TXO+/JQWhPwkalgqizKmXyRIQAAAAAAAAABkFf8vQAAAEDmHHsYzqrzruPqKTFS0mcBPkpVkiF4ykNCJdAf/meM9NDYk+Eg/LD2B2epHdQZDC8TvecyiMQACjrb+Bdb+2YD", + "result_xdr": "AAAAAACYloAAAAAAAAAAAQAAAAAAAAAIAAAAAAAAABdH3lGAAAAAAA==", + "result_meta_xdr": "AAAAAgAAAAIAAAADAApGWgAAAAAAAAAAbfDOA1VYH2m3DvPetyIjYhHx3HE/gKguNxXBs5BX/L0AAAAXR95RgAAKRlkAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABAApGWgAAAAAAAAAAbfDOA1VYH2m3DvPetyIjYhHx3HE/gKguNxXBs5BX/L0AAAAXR95RgAAKRlkAAAABAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAAACkZaAAAAAGLpGdQAAAAAAAAAAQAAAAQAAAADAApGWgAAAAAAAAAAbfDOA1VYH2m3DvPetyIjYhHx3HE/gKguNxXBs5BX/L0AAAAXR95RgAAKRlkAAAABAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAAACkZaAAAAAGLpGdQAAAAAAAAAAgAAAAAAAAAAbfDOA1VYH2m3DvPetyIjYhHx3HE/gKguNxXBs5BX/L0AAAADAApGTwAAAAAAAAAASgQftlATD/2m8HJvzNU1zvvyUFoT8JGpYKosypl8kSEMj1jFrrjxTQAAAM4AAAABAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAwAAAAAAAAhlAAAAAGKzGdkAAAAAAAAAAQAKRloAAAAAAAAAAEoEH7ZQEw/9pvByb8zVNc778lBaE/CRqWCqLMqZfJEhDI9Y3PaXQs0AAADOAAAAAQAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAMAAAAAAAAIZQAAAABisxnZAAAAAAAAAAA=", + "fee_meta_xdr": "AAAAAgAAAAMACkZZAAAAAAAAAABt8M4DVVgfabcO8963IiNiEfHccT+AqC43FcGzkFf8vQAAABdIdugAAApGWQAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAEACkZaAAAAAAAAAABt8M4DVVgfabcO8963IiNiEfHccT+AqC43FcGzkFf8vQAAABdH3lGAAApGWQAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA==", + "memo_type": "none", + "signatures": [ + "5hx7GM6q867j6ikxUtJnAT5KVZIheMpDQiXQH/5njPTQ2JPhIPyw9gdnqR3UGQwvE73nMojEAAo62/gXW/tmAw==" + ], + "valid_after": "1970-01-01T00:00:00Z", + "valid_before": "2022-08-02T12:34:56Z", + "preconditions": { + "timebounds": { + "min_time": "0", + "max_time": "1659443696" + } + } + } + ] + } + }` + normalizedResp := normalizeResponseBody([]byte(resp)) + t.Log(normalizedResp) +} diff --git a/xdr/asset_test.go b/xdr/asset_test.go index e1d99d9454..12ecee0875 100644 --- a/xdr/asset_test.go +++ b/xdr/asset_test.go @@ -473,6 +473,16 @@ func TestAssetLessThan(t *testing.T) { assert.False(t, assetIssuerB.LessThan(assetIssuerA)) assert.False(t, assetIssuerB.LessThan(assetIssuerB)) }) + + t.Run("test if codes with upper-case letters are sorted before lower-case letters", func(t *testing.T) { + // All upper-case letters should come before any lower-case ones + assetA, err := NewCreditAsset("B", "GA7NLOF4EHWMJF6DBXXV2H6AYI7IHYWNFZR6R52BYBLY7TE5Q74AIDRA") + require.NoError(t, err) + assetB, err := NewCreditAsset("a", "GA7NLOF4EHWMJF6DBXXV2H6AYI7IHYWNFZR6R52BYBLY7TE5Q74AIDRA") + require.NoError(t, err) + + assert.True(t, assetA.LessThan(assetB)) + }) } func BenchmarkAssetString(b *testing.B) {