diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a96c7d02b..a8605720a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -35,7 +35,7 @@ jobs: id: login-ecr uses: aws-actions/amazon-ecr-login@v2 - name: Log in to the Container registry - uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 + uses: docker/login-action@5f4866a30a54f16a52d2ecb4a3898e9e424939cf with: registry: ghcr.io username: ${{ github.actor }} diff --git a/Makefile b/Makefile index 20ee2cded..84db83002 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,8 @@ GENESIS ?= $(HOMEDIR)/config/genesis.json GENESIS_TMP ?= $(HOMEDIR)/config/genesis_tmp.json COVER_FILE ?= cover.out BENCHMARK_ITERS ?= 10 +DEFI_PROVIDERS_ENABLED ?= false +SOLANA_NODE_ENDPOINT ?= https://api.devnet.solana.com LEVANT_VAR_FILE:=$(shell mktemp -d)/levant.yaml NOMAD_FILE_SLINKY:=contrib/nomad/slinky.nomad @@ -43,7 +45,8 @@ run-prom-client: update-local-configs: build @echo "Updating local config..." - @./build/slinky-config --oracle-config-path ${ORACLE_CONFIG_FILE} --market-config-path ${MARKET_CONFIG_FILE} + @./build/slinky-config --oracle-config-path ${ORACLE_CONFIG_FILE} --market-config-path ${MARKET_CONFIG_FILE} --raydium-enabled ${DEFI_ORACLE_ENABLED} \ + --solana-node-endpoint ${SOLANA_NODE_ENDPOINT} start-oracle: @echo "Starting oracle side-car, blockchain, and prometheus dashboard..." diff --git a/README.md b/README.md index 2bfe9ed76..74905b414 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,3 @@ To test these numbers yourself, spin up the the oracle server following the inst * [Data Provider Queries](./providers/base/metrics/README.md#usage): Provides general insight into how often price feeds are updated by status (success/failure), provider (binance, coinbase, etc.), price feed (BTC/USD, ETH/USD), and provider type (api/websocket). * [Websocket Performance Queries](./providers/base/websocket/metrics/README.md#usage): Provides insight into how often websocket providers are successfully updating their data. This is a combination of metrics related to the underlying connection as well as the data handler which is responsible for processing the data received from the Websocket connection. * [API Performance Queries](./providers/base/api/metrics/README.md#usage): Provides insight into how often API providers are successfully updating their data. - -## Future Work - -The oracle side car is a combination of the oracle and provider packages. This is being moved to a [separate repository](https://github.com/skip-mev/slinky-sidecar). diff --git a/abci/preblock/oracle/mocks/mock_oracle_keeper.go b/abci/preblock/oracle/mocks/mock_oracle_keeper.go index ac2144500..45a465faf 100644 --- a/abci/preblock/oracle/mocks/mock_oracle_keeper.go +++ b/abci/preblock/oracle/mocks/mock_oracle_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/abci/preblock/sla/mocks/mock_oracle_keeper.go b/abci/preblock/sla/mocks/mock_oracle_keeper.go index da07df54e..62edbb551 100644 --- a/abci/preblock/sla/mocks/mock_oracle_keeper.go +++ b/abci/preblock/sla/mocks/mock_oracle_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/abci/preblock/sla/mocks/mock_sla_keeper.go b/abci/preblock/sla/mocks/mock_sla_keeper.go index b0c643a4d..a5858d152 100644 --- a/abci/preblock/sla/mocks/mock_sla_keeper.go +++ b/abci/preblock/sla/mocks/mock_sla_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/abci/preblock/sla/mocks/mock_staking_keeper.go b/abci/preblock/sla/mocks/mock_staking_keeper.go index 5605b39a1..f8e3604ea 100644 --- a/abci/preblock/sla/mocks/mock_staking_keeper.go +++ b/abci/preblock/sla/mocks/mock_staking_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/abci/strategies/aggregator/mocks/mock_vote_aggregator.go b/abci/strategies/aggregator/mocks/mock_vote_aggregator.go index adb2e6827..b4aeb75d6 100644 --- a/abci/strategies/aggregator/mocks/mock_vote_aggregator.go +++ b/abci/strategies/aggregator/mocks/mock_vote_aggregator.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/abci/strategies/codec/mocks/extended_commit_codec.go b/abci/strategies/codec/mocks/extended_commit_codec.go index 63f7548e7..5b4ace711 100644 --- a/abci/strategies/codec/mocks/extended_commit_codec.go +++ b/abci/strategies/codec/mocks/extended_commit_codec.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/abci/strategies/codec/mocks/vote_extension_codec.go b/abci/strategies/codec/mocks/vote_extension_codec.go index de1598e31..8c71993b5 100644 --- a/abci/strategies/codec/mocks/vote_extension_codec.go +++ b/abci/strategies/codec/mocks/vote_extension_codec.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/abci/strategies/currencypair/mocks/mock_currency_pair_strategy.go b/abci/strategies/currencypair/mocks/mock_currency_pair_strategy.go index 830c48537..fb0c295c9 100644 --- a/abci/strategies/currencypair/mocks/mock_currency_pair_strategy.go +++ b/abci/strategies/currencypair/mocks/mock_currency_pair_strategy.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.30.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/abci/strategies/currencypair/mocks/mock_oracle_keeper.go b/abci/strategies/currencypair/mocks/mock_oracle_keeper.go index 920ae1beb..9a7b456e9 100644 --- a/abci/strategies/currencypair/mocks/mock_oracle_keeper.go +++ b/abci/strategies/currencypair/mocks/mock_oracle_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.30.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/cmd/client/main.go b/cmd/client/main.go index 3406bdcfa..dc51877fa 100644 --- a/cmd/client/main.go +++ b/cmd/client/main.go @@ -31,7 +31,7 @@ var ( // Set up a connection to the server. url := fmt.Sprintf("%s:%s", host, port) - conn, err := grpc.Dial(url, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock()) + conn, err := grpc.NewClient(url, grpc.WithTransportCredentials(insecure.NewCredentials()), grpc.WithBlock()) if err != nil { log.Fatalf("did not connect: %v", err) } diff --git a/cmd/slinky-config/fixtures/raydium_pairs.json b/cmd/slinky-config/fixtures/raydium_pairs.json new file mode 100644 index 000000000..0916fe203 --- /dev/null +++ b/cmd/slinky-config/fixtures/raydium_pairs.json @@ -0,0 +1,770 @@ +[ + { + "currency_pair": { + "Base": "SOL", + "Quote": "HOBBES" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "4J3cZy8G2qm6MBVGfeXhYETZvbRThv9TPPeY3p83QYLb", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "7DejqJN5iRcuUhR7C1Vif3SbjTXKCzkpyS3AxC28tiaF", + "token_decimals": 6 + } + } + }, + { + "currency_pair": { + "Base": "$WIF", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "7UYZ4vX13mmGiopayLZAduo8aie77yZ3o8FMzTeAX8uJ", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "7e9ExBAvDvuJP3GE6eKL5aSMi4RfXv3LkQaiNZBPmffR", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "MEW", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "4HqAjFKuQX7tnXEkxsjGQha3G4bcgER8qPXRahn9gj8F", + "token_decimals": 5 + }, + "quote_token_vault": { + "token_vault_address": "BhNdEGJef9jSqT1iCEkFZ2bYZCdpC1vuiWtqDt87vBVp", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "SOL", + "Quote": "EPIK" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "9aGBQqKRyC5bbrZsnZJJtp59EqJj7vBkgV3HehgKEu5y", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "ANpMJb9ToMGNivLEdmBNBC2Qcf5ASaZkEdmUddV1FUZB", + "token_decimals": 6 + } + } + }, + { + "currency_pair": { + "Base": "BODEN", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "54zedUwxuSnmHHYg9oY1AfykeBDaCF6ZFZDW3ym2Nea4", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "DzpiXKsTUCacKyahLBUC5sfjj2fiWbwCpiCPEgyS3zDC", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "SLERF", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "9A2ZsPz5Zg6jKN4o4KRMjTVPmkH51wYWFLmt4KBRy1Rq", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "5Zumc1SYPmQ89nqwXqzogeuhdJ85iEMpSk35A4P87pmD", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "NUB", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "9uNqUwneLXbQ6YKndciL5aBXTLJhwpyDXkZmaBbWfwWz", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "75DrZt3zmGSFfKaYDm7yHLKMrr35Wy8ffBNN1143PWbj", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "BOME", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "FBba2XsQVhkoQDMfbNLVmo7dsvssdT39BMzVc2eFfE21", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "GuXKCb9ibwSeRSdSYqaCL3dcxBZ7jJcj6Y7rDwzmUBu9", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "POPCAT", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "4Vc6N76UBu26c3jJDKBAbvSD7zPLuQWStBk7QgVEoeoS", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "n6CwMY77wdEftf2VF6uPvbusYoraYUci3nYBPqH1DJ5", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "$RETIRE", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "2NJXbbLxfygPGusgTyxbFngLaodRRRCpXxeo1pv7M5XQ", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "8PcfqMPandh18bYZJKEvjuQRH5bcH4Y6TZzGUSWEPeYG", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "TREMP", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "G2XNC6Rt2G7JZQWhqpJriYwZyxd2L52KSDbDNBCYCpvx", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "9DfnSR9h3hrmgy5pjqBP3SrVQRWPfjSqZZBrNNYGoyaN", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "BAG", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "7eLwyCqfhxKLsKeFwcN4JdfspKK22rSC4uQHNy3zWNPB", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "Cr7Yo8Uf5f8pzMsY3ZwgDFNx85nb3UDvPfQxuWG4acxc", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "TOOKER", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "Cki9WdL3sCoNY3cLmfG4iqSbvB8g1Fr9tw8qa5tP1m3Y", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "2vTTh5pGbzc6guAJmt78XnTcXVBEZEWmGBkXkSNZwN59", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "LIGMA", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "6aefaP7C6eKbW2taLqmyHinYH4ZMyY2G6MdqNu6PvfbL", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "G3kKDmmxwpjt4NVdQgdvgiuFxFsAsC1hSv4PVg63cKwM", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "CHEEMS", + "Quote": "USDC" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "HRi4eJ8xWFG4hsv7FA9L7YnPLSxhQR4U7CCXKyZvcLXe", + "token_decimals": 4 + }, + "quote_token_vault": { + "token_vault_address": "4gnEBvHQEx4nLcf9qWk1Wsxh9V1GFFDf4MfwEYmFo8hm", + "token_decimals": 6 + } + } + }, + { + "currency_pair": { + "Base": "USDC", + "Quote": "$MYRO" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "AMtPGYQS873njs35mD9MAAMKoospEuzNHPy7LQuuKo4A", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "BUvMbqP311JDU4ZGnf1rSZJLjutTU9VpNLEos393TYyW", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "MPLX", + "Quote": "USDC" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "5zdZza5N2TzV7cPtLeqCZQQRYCCHFVdXWLMeJo75DK24", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "7mwk7ZBiTtrKkKC5o34gpFBSCabEvLkp2fLjGNz43PyM", + "token_decimals": 6 + } + } + }, + { + "currency_pair": { + "Base": "KHAI", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "6g4rhxVTrN6SrtNvimq4QiU8yA5XScvwL6wxaMkegrtJ", + "token_decimals": 8 + }, + "quote_token_vault": { + "token_vault_address": "7p2PrGMyeetNRqTKFraL7eYo2TbU3apWz6vfqrZFiPcG", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "MUMU", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "2Re1H89emr8hNacyDTrm1NU8VEhuwaJX7JwcdDqy5Q6g", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "4VPXFMpndqZhME27vMqtkuGtBo7hVTA9kEvo87zbjXsA", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "CHAT", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "FKCCPsYDgEoVpEhyE2XMFAXq5zWFrWHgpQjVEKQk1C54", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "9APPnbdEXbJpktfKSGbbdgYvj6K3ZFRDFwQUabFw6CHP", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "HARAMBE", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "5f9Fgcp2C9vdrp75GspNKBjzdaxq5uiqpLVkgtWKpDZZ", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "Apgp3SzNB5VpVWbK5q2ucBvCJEsf1gqXL4iUAqvD9pgB", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "POPCAT", + "Quote": "USDC" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "Ej1CZHUcHYcqAx3pJXUvqCTs3diVmEWSfozvQQLsQkyU", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "pTJo5c4ynoxxRAgDyWgQKasR8dgqQHP3CSeoXzDgZvZ", + "token_decimals": 6 + } + } + }, + { + "currency_pair": { + "Base": "ANDY", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "pVCniSexvGFdDTjYuzoSKXDkoTqFjRhqJpmzzYMs7tY", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "2tt4w3C9hKjtzVgPqqa9Apbxz5qEKEAWodJEbbmfpwEm", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "RAY", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "Em6rHi68trYgBFyJ5261A2nhwuQWfLcirgzZZYoRcrkX", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "3mEFzHsJyu2Cpjrz6zPmTzP7uoLFj9SbbecGVzzkL1mJ", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "VCAT", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "8gNjWm2wGubUiAXT9cXBeoY2NqAFkrnvKkh9J3gHZ7Wn", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "7G9HpLoYVhcBsg7ZEy928iUuzetJFK4AWBcfaCQTMp72", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "PENG", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "2g5q7fBGKZm2CXix8JjK4ZFdBTHQ1LerxkseBTqWuDdD", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "GmLJXUzjQAAU86a91hKesg5P9pKb6p9AZaGBEZLaDySD", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "RAY", + "Quote": "USDC" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "FdmKUE4UMiJYFK5ogCngHzShuVKrFXBamPWcewDr31th", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "Eqrhxd7bDUCH3MepKmdVkgwazXRzY6iHhEoBpY7yAohk", + "token_decimals": 6 + } + } + }, + { + "currency_pair": { + "Base": "DUKO", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "HD7aZ6YrqAxVbGNAMEKxozcW1ZDU7pbKfd7XMmZtxyzk", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "A9J2mXPXfRZ7Sh2ymUgCJM4p9iUjZBcyAfrz49PoBBN4", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "LIKE", + "Quote": "USDC" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "8LoHX6f6bMdQVs4mThoH2KwX2dQDSkqVFADi4ZjDQv9T", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "2Fwm8M8vuPXEXxvKz98VdawDxsK9W8uRuJyJhvtRdhid", + "token_decimals": 6 + } + } + }, + { + "currency_pair": { + "Base": "MOUTAI", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "4VkmzH14ETcNhSQLTK6AtL1ZP8UmvWpbNCgokDVfiCcD", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "HSQPdDCxtGo4fTHeZuBGWtQUqHgRsgdz4BVhTCCAtsTv", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "ATR", + "Quote": "USDC" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "4rm2qWHwGZGj9rWoRvU7m3FDdsZJV11wuHmczw27C3Wc", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "Ahy4NhTyBaXZfsGjq4DDxGaMosBkAjaanGYdfeZjuDzP", + "token_decimals": 6 + } + } + }, + { + "currency_pair": { + "Base": "CHONKY", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "9rJqiGuRG971HCpapVNJtN4ho2fKMhkPiZRhQCAohonU", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "6Fbs4sCBH5jZp1v2Rr6zVdU44Fn4Vv9iPhY6eihjfdbz", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "SOL", + "Quote": "MAIL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "BtJXP2iWPGW2x3EsscHtCuFLBECRCfrxsJ2SDi9jh96C", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "GmHpq7Wgri9TFitGj89quvwRc1ALhe7dePM6VBAiqxrC", + "token_decimals": 6 + } + } + }, + { + "currency_pair": { + "Base": "WHALES", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "P9uSMnNEGHDP7Dhu7fKWfRViAGGHjEMv6urC8c2qG4k", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "CktEbT37HFRtwXVjwPEVfXHdcTAnqnmCvkgAw9SEN7zf", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "GMEOW", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "9crtLiYfxYVYQ9sCfWix9vAMPJyBXCcMzCPXZ5isPFxB", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "ANLamVN6Df4HqC6YevQskovddsjhkqBqHsyLzhDibFEj", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "NICK", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "FDvQiwbJVHdSZE3ngZ6WCkJfciFTdg958W7bxyKU2PJ9", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "z6ZCZESyof3ZgCJ23hY31f1SSD33gQgyVRfMB8wP9iM", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "ANSEM", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "5cM8YfCvkALkout2h9WxmYrc5e61YmvLgLLWsrZgumgK", + "token_decimals": 1 + }, + "quote_token_vault": { + "token_vault_address": "B86KHBLhVVQQnsgbn6SDJR43NSKbqmpxZsrTai45yrMy", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "MONK", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "CeLZLhC2nScSpsKqRL1eRr3L3LLfjDzakZLCUKcUHW1m", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "Be6DM12uTWtxHMSRJeah3J5PRP4CumR28Yy2qpLQFTE7", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "RETARDIO", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "HXzTvbuKKPyNMmLKJb8vaSUaRZsVS2J2AAsDuDm36rNC", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "HNcAAdLKHSRnwdmmWCYnP5Zcd11sfGpAoCuWFtugt2ma", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "PONKE", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "D7rw7fyEzo9EQcozjqAHJwbdbywGcSLw1at5MioZtMZ4", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "8DcvfWidQ53a3SCBrWxBWL2UU5zEBAKEypApiiCCFu2Y", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "VONSPEED", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "89CwpgTSsCc9u187kKvQQo6VAL5gKZViVub4eaNXfrtu", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "2fEchHP5r5wks9PPN1C2S39wPCe6Ni4247oMMTausc2a", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "TRUMP", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "GwUn3JYQ5PC6P9cB9HsatJN7y7aw3BXrNqHPpoHtWyKF", + "token_decimals": 8 + }, + "quote_token_vault": { + "token_vault_address": "5DNPt6WYgj3x7EmU4Fyqe3jDYPk2HMAB21H5N4Ggbev9", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "NINJA", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "5Mmie9Drh6RGMy8X8UQ3egyBi4Hvva1TR778bf77ViCV", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "HxVbv76N8EoRGEPJsKdtWCu3mz7ZXJi8dbZy8kM3QL3i", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "SMOLE", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "VDZ9kwvKRbqhNdsoRZyLVzAAQMbGY9akHbtM6YugViS", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "HiLcngHP5y1Jno53tuuNeFHKWhyyZp3XuxtKPszD6rG2", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "NOS", + "Quote": "USDC" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "9Gs4LvFZw18EBLrSmZbQBw4G2SpTu4bJRCWH1Dz33cUZ", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "FqKU4BxbabPd1tcZAVVv8JkdUWmdz32CocRM856gA3Lw", + "token_decimals": 6 + } + } + }, + { + "currency_pair": { + "Base": "MARVIN", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "3vLTpZneGAzceAXKu2HuesT4rt6ksRJ3Q9WvjUmwksqA", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "3rWa7PstXZk4ZaEhLamfoqMVozwq7hfXEDqyNbHcL4uK", + "token_decimals": 9 + } + } + }, + { + "currency_pair": { + "Base": "RAY", + "Quote": "USDT" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "3wqhzSB9avepM9xMteiZnbJw75zmTBDVmPFLTQAGcSMN", + "token_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "5GtSbKJEPaoumrDzNj4kGkgZtfDyUceKaHrPziazALC1", + "token_decimals": 6 + } + } + }, + { + "currency_pair": { + "Base": "FKETH", + "Quote": "SOL" + }, + "ticker_metadata": { + "base_token_vault": { + "token_vault_address": "DNh9pRMiRX6zwWuzsXtmxmXLdbAGNuYg4dmmnzrpL871", + "token_decimals": 9 + }, + "quote_token_vault": { + "token_vault_address": "47fCbQKnJYaMbPaPSyUrPXPUahizhYwAbwXnEcKN1vwD", + "token_decimals": 9 + } + } + } +] \ No newline at end of file diff --git a/cmd/slinky-config/main.go b/cmd/slinky-config/main.go index 29787db3a..81e27e3a5 100644 --- a/cmd/slinky-config/main.go +++ b/cmd/slinky-config/main.go @@ -3,6 +3,7 @@ package main import ( "encoding/json" "fmt" + "io" "os" "strings" "time" @@ -12,9 +13,11 @@ import ( "github.com/skip-mev/slinky/oracle/config" "github.com/skip-mev/slinky/oracle/constants" "github.com/skip-mev/slinky/oracle/types" + slinkytypes "github.com/skip-mev/slinky/pkg/types" "github.com/skip-mev/slinky/providers/apis/binance" coinbaseapi "github.com/skip-mev/slinky/providers/apis/coinbase" "github.com/skip-mev/slinky/providers/apis/coingecko" + raydium "github.com/skip-mev/slinky/providers/apis/defi/raydium" "github.com/skip-mev/slinky/providers/apis/dydx" "github.com/skip-mev/slinky/providers/apis/geckoterminal" krakenapi "github.com/skip-mev/slinky/providers/apis/kraken" @@ -34,6 +37,11 @@ import ( mmtypes "github.com/skip-mev/slinky/x/marketmap/types" ) +const ( + // raydiumPairsFixture is the path to the fixture file containing all raydium markets. + raydiumPairsFixture = "./cmd/slinky-config/fixtures/raydium_pairs.json" +) + var ( rootCmd = &cobra.Command{ Use: "slinky-config", @@ -79,6 +87,12 @@ var ( // maxPriceAge is the maximum age of a price that the oracle will accept. maxPriceAge time.Duration + // raydium-enabled determine whether or not the raydium defi provider will be configured. + raydiumEnabled bool + + // solana node url is the solana node that the raydium provider will connect to. + solanaNodeURLs []string + // ProviderToMarkets defines a map of provider names to their respective market // configurations. This is used to generate the local market config file. ProviderToMarkets = map[string]types.TickerToProviderConfig{ @@ -301,6 +315,20 @@ func init() { 2*time.Minute, "Maximum age of a price that the oracle will accept. This should be set to the maximum age desired by the chain.", ) + rootCmd.Flags().BoolVarP( + &raydiumEnabled, + "raydium-enabled", + "", + false, + "whether or not to enable raydium support", + ) + rootCmd.Flags().StringSliceVarP( + &solanaNodeURLs, + "solana-node-endpoint", + "", + nil, + "The HTTP endpoints of the solana node endpoint the raydium provider will be configured to use. If multiple are given they must be comma delimited", + ) } // main executes a simple script that encodes the local config file to the local @@ -344,6 +372,22 @@ func createOracleConfig() error { LocalOracleConfig.Providers = ps } + // add raydium provider to the list of providers if enabled + if raydiumEnabled { + cfg := raydium.DefaultAPIConfig + for _, node := range solanaNodeURLs { + cfg.Endpoints = append(cfg.Endpoints, config.Endpoint{ + URL: node, + }) + } + + LocalOracleConfig.Providers = append(LocalOracleConfig.Providers, config.ProviderConfig{ + Name: raydium.Name, + API: cfg, + Type: types.ConfigType, + }) + } + // Set the host and port for the oracle. LocalOracleConfig.Host = host LocalOracleConfig.Port = pricesPort @@ -407,6 +451,11 @@ func createMarketMap() error { tickersToPaths = make(map[string]mmtypes.Paths) ) + // if raydium is enabled, configure the raydium markets based on the local raydium_pairs fixture + if raydiumEnabled { + ProviderToMarkets = addRaydiumMarkets(ProviderToMarkets) + } + // Iterate through all of the provider ticker configurations and update the // tickers and tickers to providers maps. for name, providerConfig := range ProviderToMarkets { @@ -483,3 +532,60 @@ func createMarketMap() error { fmt.Fprintf(os.Stdout, "successfully created market config file at %s\n", marketCfgPath) return nil } + +type TickerMetaData struct { + Cp slinkytypes.CurrencyPair `json:"currency_pair"` + TickerMetaData raydium.TickerMetadata `json:"ticker_metadata"` +} + +func addRaydiumMarkets(providerToMarkets map[string]map[mmtypes.Ticker]mmtypes.ProviderConfig) map[string]map[mmtypes.Ticker]mmtypes.ProviderConfig { + // read the raydium_pairs fixture + if !raydiumEnabled { + return providerToMarkets + } + + // read the raydium_pairs fixture + file, err := os.Open(raydiumPairsFixture) + if err != nil { + fmt.Fprintf(os.Stderr, "error reading raydium_pairs fixture: %v\n", err) + return providerToMarkets + } + defer file.Close() + + bz, err := io.ReadAll(file) + if err != nil { + fmt.Fprintf(os.Stderr, "error reading raydium_pairs fixture: %v\n", err) + return providerToMarkets + } + + var raydiumPairs []TickerMetaData + if err := json.Unmarshal(bz, &raydiumPairs); err != nil { + fmt.Fprintf(os.Stderr, "error unmarshalling raydium_pairs fixture: %v\n", err) + return providerToMarkets + } + + // add the raydium markets to the provider to markets map + providerToMarkets[raydium.Name] = make(map[mmtypes.Ticker]mmtypes.ProviderConfig) + for _, pair := range raydiumPairs { + providerToMarkets[raydium.Name][mmtypes.Ticker{ + CurrencyPair: pair.Cp, + Decimals: 18, + MinProviderCount: 1, + Enabled: true, + Metadata_JSON: marshalToJSONString(pair.TickerMetaData), + }] = mmtypes.ProviderConfig{ + Name: raydium.Name, + OffChainTicker: pair.Cp.String(), + } + } + + return providerToMarkets +} + +func marshalToJSONString(obj interface{}) string { + bz, err := json.Marshal(obj) + if err != nil { + panic(err) + } + return string(bz) +} diff --git a/contrib/nomad/slinky.nomad b/contrib/nomad/slinky.nomad index bf001f527..1934abee7 100644 --- a/contrib/nomad/slinky.nomad +++ b/contrib/nomad/slinky.nomad @@ -10,6 +10,10 @@ job "slinky-dev" { network { mode = "bridge" + + port "sidecar_metrics" { + to = -1 + } } service { @@ -30,15 +34,31 @@ job "slinky-dev" { service { name = "slinky-sidecar-dev-metrics-service" + port = "sidecar_metrics" + + tags = ["metrics", "logs.promtail=true"] + } + + service { + name = "slinky-sidecar-dev-metrics-internal-service" port = "8002" connect { - sidecar_service {} + sidecar_service { + proxy { + expose { + path { + path = "/metrics" + local_path_port = 8002 + protocol = "http" + listener_port = "sidecar_metrics" + } + } + } + } } tags = [ - "metrics", - "logs.promtail=true", "traefik.enable=true", "traefik.consulcatalog.connect=true", "traefik.http.routers.slinky-sidecar-dev-metrics-service.rule=Host(`slinky-sidecar-dev-metrics.skip.money`)", @@ -66,7 +86,7 @@ job "slinky-dev" { driver = "docker" config { - image = "[[ .sidecar_image ]]" + image = "[[ .sidecar_image ]]" force_pull = true entrypoint = ["slinky", "--oracle-config-path", "/etc/slinky/default_config/oracle.json", "--market-config-path", "/etc/slinky/default_config/market.json"] } @@ -84,6 +104,14 @@ job "slinky-dev" { network { mode = "bridge" + + port "chain_metrics" { + to = -1 + } + + port "app_metrics" { + to = -1 + } } service { @@ -114,7 +142,7 @@ job "slinky-dev" { port = "1317" connect { - sidecar_service {} + sidecar_service {} } tags = [ @@ -127,15 +155,31 @@ job "slinky-dev" { service { name = "slinky-simapp-dev-chain-metrics-service" + port = "chain_metrics" + + tags = ["metrics", "logs.promtail=true"] + } + + service { + name = "slinky-simapp-dev-chain-metrics-internal-service" port = "26660" connect { - sidecar_service {} + sidecar_service { + proxy { + expose { + path { + path = "/metrics" + local_path_port = 26660 + protocol = "http" + listener_port = "chain_metrics" + } + } + } + } } tags = [ - "metrics", - "logs.promtail=true", "traefik.enable=true", "traefik.consulcatalog.connect=true", "traefik.http.routers.slinky-simapp-dev-chain-metrics-service.rule=Host(`slinky-simapp-dev-chain-metrics.skip.money`)", @@ -145,15 +189,31 @@ job "slinky-dev" { service { name = "slinky-simapp-dev-app-metrics-service" + port = "app_metrics" + + tags = ["metrics", "logs.promtail=true"] + } + + service { + name = "slinky-simapp-dev-app-metrics-internal-service" port = "8001" connect { - sidecar_service {} + sidecar_service { + proxy { + expose { + path { + path = "/metrics" + local_path_port = 8001 + protocol = "http" + listener_port = "app_metrics" + } + } + } + } } tags = [ - "metrics", - "logs.promtail=true", "traefik.enable=true", "traefik.consulcatalog.connect=true", "traefik.http.routers.slinky-simapp-dev-app-metrics-service.rule=Host(`slinky-simapp-dev-app-metrics.skip.money`)", diff --git a/go.mod b/go.mod index f6fd54098..5c340af7a 100644 --- a/go.mod +++ b/go.mod @@ -25,10 +25,13 @@ require ( github.com/cosmos/cosmos-sdk v0.50.5 github.com/cosmos/gogogateway v1.2.0 github.com/cosmos/gogoproto v1.4.12 + github.com/ethereum/go-ethereum v1.13.14 + github.com/gagliardetto/binary v0.8.0 + github.com/gagliardetto/solana-go v1.10.0 github.com/gogo/protobuf v1.3.2 github.com/golang/mock v1.6.0 github.com/golang/protobuf v1.5.4 - github.com/golangci/golangci-lint v1.57.1 + github.com/golangci/golangci-lint v1.57.2 github.com/gorilla/websocket v1.5.1 github.com/grpc-ecosystem/grpc-gateway v1.16.0 github.com/klauspost/compress v1.17.7 @@ -39,14 +42,14 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.9.0 - github.com/vektra/mockery/v2 v2.42.1 + github.com/vektra/mockery/v2 v2.42.2 go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 - golang.org/x/net v0.23.0 - golang.org/x/sync v0.6.0 + golang.org/x/net v0.24.0 + golang.org/x/sync v0.7.0 golang.org/x/vuln v1.0.4 google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8 - google.golang.org/grpc v1.62.1 + google.golang.org/grpc v1.63.0 google.golang.org/protobuf v1.33.0 mvdan.cc/gofumpt v0.6.0 ) @@ -74,12 +77,15 @@ require ( github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect + github.com/StackExchange/wmi v1.2.1 // indirect github.com/alecthomas/assert/v2 v2.6.0 // indirect github.com/alecthomas/go-check-sumtype v0.1.4 // indirect github.com/alexkohler/nakedret/v2 v2.0.4 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect + github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect github.com/ashanbrown/forbidigo v1.6.0 // indirect github.com/ashanbrown/makezero v1.1.1 // indirect github.com/aws/aws-sdk-go v1.44.224 // indirect @@ -87,6 +93,7 @@ require ( github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/bgentry/speakeasy v0.1.1-0.20220910012023-760eaf8b6816 // indirect github.com/bkielbasa/cyclop v1.2.1 // indirect + github.com/blendle/zapdriver v1.3.1 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect github.com/bombsimon/wsl/v4 v4.2.1 // indirect github.com/breml/bidichk v0.2.7 // indirect @@ -103,7 +110,7 @@ require ( github.com/chavacava/garif v0.1.0 // indirect github.com/chigopher/pathlib v0.19.1 // indirect github.com/chzyer/readline v1.5.1 // indirect - github.com/ckaznocha/intrange v0.1.0 // indirect + github.com/ckaznocha/intrange v0.1.1 // indirect github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect @@ -111,17 +118,21 @@ require ( github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/cometbft/cometbft-db v0.9.1 // indirect + github.com/consensys/bavard v0.1.13 // indirect + github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/cosmos/btcutil v1.0.5 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/iavl v1.0.1 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect + github.com/crate-crypto/go-kzg-4844 v0.7.0 // indirect github.com/creachadair/atomicfile v0.3.1 // indirect github.com/creachadair/tomledit v0.0.24 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect github.com/daixiang0/gci v0.12.3 // indirect github.com/danieljoos/wincred v1.1.2 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/deckarep/golang-set/v2 v2.1.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect github.com/denis-tingaikin/go-header v0.5.0 // indirect github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f // indirect @@ -131,6 +142,7 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/emicklei/dot v1.6.1 // indirect + github.com/ethereum/c-kzg-4844 v0.4.0 // indirect github.com/ettle/strcase v0.2.0 // indirect github.com/fatih/color v1.16.0 // indirect github.com/fatih/structtag v1.2.0 // indirect @@ -138,6 +150,7 @@ require ( github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect + github.com/gagliardetto/treeout v0.1.4 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/ghostiam/protogetter v0.3.5 // indirect github.com/go-critic/go-critic v0.11.2 // indirect @@ -146,6 +159,7 @@ require ( github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.1 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-toolsmith/astcast v1.1.0 // indirect github.com/go-toolsmith/astcopy v1.1.0 // indirect github.com/go-toolsmith/astequal v1.2.0 // indirect @@ -161,7 +175,7 @@ require ( github.com/gogo/googleapis v1.4.1 // indirect github.com/golang/glog v1.2.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/snappy v0.0.4 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e // indirect github.com/golangci/misspell v0.4.1 // indirect @@ -197,33 +211,36 @@ require ( github.com/hashicorp/yamux v0.1.1 // indirect github.com/hdevalence/ed25519consensus v0.1.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect + github.com/holiman/uint256 v1.2.4 // indirect github.com/huandu/skiplist v1.2.0 // indirect github.com/huandu/xstrings v1.4.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/improbable-eng/grpc-web v0.15.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/jgautheron/goconst v1.7.0 // indirect + github.com/jgautheron/goconst v1.7.1 // indirect github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jinzhu/copier v0.3.5 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect github.com/jjti/go-spancheck v0.5.3 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect github.com/julz/importas v0.1.0 // indirect - github.com/karamaru-alpha/copyloopvar v1.0.8 // indirect + github.com/karamaru-alpha/copyloopvar v1.0.10 // indirect github.com/kisielk/errcheck v1.7.0 // indirect - github.com/kkHAIKE/contextcheck v1.1.4 // indirect + github.com/kkHAIKE/contextcheck v1.1.5 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.10 // indirect github.com/kyoh86/exportloopref v0.1.11 // indirect - github.com/ldez/gomoddirectives v0.2.3 // indirect + github.com/ldez/gomoddirectives v0.2.4 // indirect github.com/ldez/tagliatelle v0.5.0 // indirect github.com/leonklingele/grouper v1.1.1 // indirect github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/linxGnu/grocksdb v1.8.12 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/macabu/inamedparam v0.1.3 // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -233,18 +250,23 @@ require ( github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mattn/go-runewidth v0.0.13 // indirect github.com/mgechev/revive v1.3.7 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/moricho/tparallel v0.3.1 // indirect + github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect github.com/mtibben/percent v0.2.1 // indirect github.com/nakabonne/nestif v0.3.1 // indirect github.com/nishanths/exhaustive v0.12.0 // indirect github.com/nishanths/predeclared v0.2.2 // indirect - github.com/nunnatsa/ginkgolinter v0.16.1 // indirect + github.com/nunnatsa/ginkgolinter v0.16.2 // indirect github.com/oasisprotocol/curve25519-voi v0.0.0-20230904125328-1f23a7beb09a // indirect github.com/oklog/run v1.1.0 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect @@ -261,6 +283,7 @@ require ( github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.8.3 // indirect github.com/rs/zerolog v1.32.0 // indirect @@ -275,6 +298,7 @@ require ( github.com/sashamelentyev/usestdlibvars v1.25.0 // indirect github.com/securego/gosec/v2 v2.19.0 // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect github.com/sirupsen/logrus v1.9.3 // indirect github.com/sivchari/containedctx v1.0.3 // indirect github.com/sivchari/tenv v1.7.1 // indirect @@ -284,8 +308,10 @@ require ( github.com/spf13/afero v1.11.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect + github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/subosito/gotenv v1.6.0 // indirect + github.com/supranational/blst v0.3.11 // indirect github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d // indirect github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect github.com/tdakkota/asciicheck v0.2.0 // indirect @@ -294,6 +320,8 @@ require ( github.com/tidwall/btree v1.7.0 // indirect github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect github.com/timonwong/loggercheck v0.9.4 // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect github.com/tomarrell/wrapcheck/v2 v2.8.3 // indirect github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect github.com/ulikunitz/xz v0.5.11 // indirect @@ -310,6 +338,7 @@ require ( go-simpler.org/musttag v0.9.0 // indirect go-simpler.org/sloglint v0.5.0 // indirect go.etcd.io/bbolt v1.3.8 // indirect + go.mongodb.org/mongo-driver v1.11.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect @@ -318,18 +347,19 @@ require ( go.opentelemetry.io/otel/trace v1.22.0 // indirect go.uber.org/automaxprocs v1.5.3 // indirect go.uber.org/multierr v1.10.0 // indirect - golang.org/x/crypto v0.21.0 // indirect + go.uber.org/ratelimit v0.2.0 // indirect + golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect golang.org/x/mod v0.16.0 // indirect - golang.org/x/oauth2 v0.16.0 // indirect - golang.org/x/sys v0.18.0 // indirect - golang.org/x/term v0.18.0 // indirect + golang.org/x/oauth2 v0.17.0 // indirect + golang.org/x/sys v0.19.0 // indirect + golang.org/x/term v0.19.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.19.0 // indirect google.golang.org/api v0.162.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect @@ -339,6 +369,7 @@ require ( mvdan.cc/unparam v0.0.0-20240104100049-c549a3470d14 // indirect nhooyr.io/websocket v1.8.6 // indirect pgregory.net/rapid v1.1.0 // indirect + rsc.io/tmplfunc v0.0.3 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/go.sum b/go.sum index 1ed0e7cfe..d34fd8e36 100644 --- a/go.sum +++ b/go.sum @@ -223,6 +223,8 @@ github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMb github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/Abirdcfly/dupword v0.0.14 h1:3U4ulkc8EUo+CaT105/GJ1BQwtgyj6+VaBVbAX11Ba8= github.com/Abirdcfly/dupword v0.0.14/go.mod h1:VKDAbxdY8YbKUByLGg8EETzYSuC4crm9WwI6Y3S0cLI= +github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= +github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= github.com/Antonboom/errname v0.1.12 h1:oh9ak2zUtsLp5oaEd/erjB4GPu9w19NyoIskZClDcQY= github.com/Antonboom/errname v0.1.12/go.mod h1:bK7todrzvlaZoQagP1orKzWXv59X/x0W0Io2XT1Ssro= github.com/Antonboom/nilnil v0.1.7 h1:ofgL+BA7vlA1K2wNQOsHzLJ2Pw5B5DpWRLdDAVvvTow= @@ -256,6 +258,10 @@ github.com/OpenPeeDeeP/depguard/v2 v2.2.0 h1:vDfG60vDtIuf0MEOhmLlLLSzqaRM8EMcgJP github.com/OpenPeeDeeP/depguard/v2 v2.2.0/go.mod h1:CIzddKRvLBC4Au5aYP/i3nyaWQ+ClszLIuVocRiCYFQ= 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/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VictoriaMetrics/fastcache v1.12.1 h1:i0mICQuojGDL3KblA7wUNlY5lOK6a4bwt3uRKnkZU40= +github.com/VictoriaMetrics/fastcache v1.12.1/go.mod h1:tX04vaqcNoQeGLD+ra5pU5sWkuxnzWhEzLwhP9w653o= github.com/VividCortex/gohistogram v1.0.0 h1:6+hBz+qvs0JOrrNhhmR7lFxo5sINxBCGXrdtl/UvroE= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= @@ -278,6 +284,8 @@ github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pO github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= +github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI= +github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= 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= @@ -310,6 +318,8 @@ github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJR github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bkielbasa/cyclop v1.2.1 h1:AeF71HZDob1P2/pRm1so9cd1alZnrpyc4q2uP2l0gJY= github.com/bkielbasa/cyclop v1.2.1/go.mod h1:K/dT/M0FPAiYjBgQGau7tz+3TMh4FWAEqlMhzFWCrgM= +github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= +github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= github.com/bombsimon/wsl/v4 v4.2.1 h1:Cxg6u+XDWff75SIFFmNsqnIOgob+Q9hG6y/ioKbRFiM= @@ -341,6 +351,8 @@ github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInq github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4= github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= +github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -365,8 +377,8 @@ github.com/chzyer/test v1.0.0 h1:p3BQDXSxOhOG0P9z6/hGnII4LGiEPOYBhs8asl/fC04= github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= 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/ckaznocha/intrange v0.1.0 h1:ZiGBhvrdsKpoEfzh9CjBfDSZof6QB0ORY5tXasUtiew= -github.com/ckaznocha/intrange v0.1.0/go.mod h1:Vwa9Ekex2BrEQMg6zlrWwbs/FtYw7eS5838Q7UjK7TQ= +github.com/ckaznocha/intrange v0.1.1 h1:gHe4LfqCspWkh8KpJFs20fJz3XRHFBFUV9yI7Itu83Q= +github.com/ckaznocha/intrange v0.1.1/go.mod h1:RWffCw/vKBwHeOEwWdCikAtY0q4gGt8VhJZEEA5n+RE= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -401,6 +413,10 @@ github.com/cometbft/cometbft v0.38.6 h1:QSgpCzrGWJ2KUq1qpw+FCfASRpE27T6LQbfEHscd github.com/cometbft/cometbft v0.38.6/go.mod h1:8rSPxzUJYquCN8uuBgbUHOMg2KAwvr7CyUw+6ukO4nw= github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= +github.com/consensys/bavard v0.1.13 h1:oLhMLOFGTLdlda/kma4VOJazblc7IM5y5QPd2A/YjhQ= +github.com/consensys/bavard v0.1.13/go.mod h1:9ItSMtA/dXMAiL7BG6bqW2m3NdSEObYWoH223nGHukI= +github.com/consensys/gnark-crypto v0.12.1 h1:lHH39WuuFgVHONRl3J0LRBtuYdQTumFSDtJF7HpyG8M= +github.com/consensys/gnark-crypto v0.12.1/go.mod h1:v2Gy7L/4ZRosZ7Ivs+9SfUDr0f5UlG+EM5t7MPHiLuY= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= @@ -432,9 +448,15 @@ github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= github.com/cosmos/keyring v1.2.0/go.mod h1:fc+wB5KTk9wQ9sDx0kFXB3A0MaeGHM9AwRStKOQ5vOA= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= github.com/cosmos/ledger-cosmos-go v0.13.3/go.mod h1:HENcEP+VtahZFw38HZ3+LS3Iv5XV6svsnkk9vdJtLr8= +github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233 h1:d28BXYi+wUpz1KBmiF9bWrjEMacUEREV6MBi2ODnrfQ= +github.com/crate-crypto/go-ipa v0.0.0-20231025140028-3c0104f4b233/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= +github.com/crate-crypto/go-kzg-4844 v0.7.0 h1:C0vgZRk4q4EZ/JgPfzuSoxdCq3C3mOZMBShovmncxvA= +github.com/crate-crypto/go-kzg-4844 v0.7.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= github.com/creachadair/atomicfile v0.3.1 h1:yQORkHjSYySh/tv5th1dkKcn02NEW5JleB84sjt+W4Q= github.com/creachadair/atomicfile v0.3.1/go.mod h1:mwfrkRxFKwpNAflYZzytbSwxvbK6fdGRRlp0KEQc0qU= github.com/creachadair/tomledit v0.0.24 h1:5Xjr25R2esu1rKCbQEmjZYlrhFkDspoAbAKb6QKQDhQ= @@ -451,6 +473,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.1.0 h1:g47V4Or+DUdzbs8FxCCmgb6VYd+ptPAngjM6dtGktsI= +github.com/deckarep/golang-set/v2 v2.1.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.1 h1:7PltbUIQB7u/FfZ39+DGa/ShuMyJ5ilcvdfma9wOH6Y= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= @@ -497,6 +521,10 @@ github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go. github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= +github.com/ethereum/c-kzg-4844 v0.4.0 h1:3MS1s4JtA868KpJxroZoepdV0ZKBp3u/O5HcZ7R3nlY= +github.com/ethereum/c-kzg-4844 v0.4.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= +github.com/ethereum/go-ethereum v1.13.14 h1:EwiY3FZP94derMCIam1iW4HFVrSgIcpsu0HwTQtm6CQ= +github.com/ethereum/go-ethereum v1.13.14/go.mod h1:TN8ZiHrdJwSe8Cb6x+p0hs5CxhJZPbqB7hHkaUXcmIU= github.com/ettle/strcase v0.2.0 h1:fGNiVF21fHXpX1niBgk0aROov1LagYsOwV/xqKDKR/Q= github.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= @@ -510,6 +538,8 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= +github.com/fjl/memsize v0.0.2 h1:27txuSD9or+NZlnOWdKUxeBzTAUkWCVh+4Gf2dWFOzA= +github.com/fjl/memsize v0.0.2/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -522,6 +552,18 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= +github.com/gagliardetto/binary v0.8.0 h1:U9ahc45v9HW0d15LoN++vIXSJyqR/pWw8DDlhd7zvxg= +github.com/gagliardetto/binary v0.8.0/go.mod h1:2tfj51g5o9dnvsc+fL3Jxr22MuWzYXwx9wEoN0XQ7/c= +github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= +github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY= +github.com/gagliardetto/solana-go v1.10.0 h1:lDuHGC+XLxw9j8fCHBZM9tv4trI0PVhev1m9NAMaIdM= +github.com/gagliardetto/solana-go v1.10.0/go.mod h1:afBEcIRrDLJst3lvAahTr63m6W2Ns6dajZxe2irF7Jg= +github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= +github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= +github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46 h1:BAIP2GihuqhwdILrV+7GJel5lyPV3u1+PgzrWLc0TkE= +github.com/gballet/go-verkle v0.1.1-0.20231031103413-a67434b50f46/go.mod h1:QNpY22eby74jVhqH4WhDLDwxc/vqsern6pW+u2kbkpc= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -557,6 +599,9 @@ github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= @@ -602,8 +647,8 @@ github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= -github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= +github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -619,6 +664,8 @@ github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zV github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v1.2.0 h1:uCdmnmatrKCgMBlM4rMuJZWOkPDqdbZPnrMXDY4gI68= github.com/golang/glog v1.2.0/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= @@ -659,15 +706,17 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu 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.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e h1:ULcKCDV1LOZPFxGZaA6TlQbiM3J2GCPnkx/bGF6sX/g= github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e/go.mod h1:Pm5KhLPA8gSnQwrQ6ukebRcapGb/BG9iUkdaiCcGHJM= -github.com/golangci/golangci-lint v1.57.1 h1:cqhpzkzjDwdN12rfMf1SUyyKyp88a1SltNqEYGS0nJw= -github.com/golangci/golangci-lint v1.57.1/go.mod h1:zLcHhz3NHc88T5zV2j75lyc0zH3LdOPOybblYa4p0oI= +github.com/golangci/golangci-lint v1.57.2 h1:NNhxfZyL5He1WWDrIvl1a4n5bvWZBcgAqBwlJAAgLTw= +github.com/golangci/golangci-lint v1.57.2/go.mod h1:ApiG3S3Ca23QyfGp5BmsorTiVxJpr5jGiNS0BkdSidg= github.com/golangci/misspell v0.4.1 h1:+y73iSicVy2PqyX7kmUefHusENlrP9YwuHZHPLGQj/g= github.com/golangci/misspell v0.4.1/go.mod h1:9mAN1quEo3DlpbaIKKyEvRxK1pwqR9s/Sea1bJCtlNI= github.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c= @@ -732,6 +781,7 @@ github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= +github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -793,6 +843,8 @@ github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NM github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= @@ -840,6 +892,12 @@ github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7H github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= +github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.2.4 h1:jUc4Nk8fm9jZabQuqr2JzednajVmBpC+oiTiXZJEApU= +github.com/holiman/uint256 v1.2.4/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= @@ -848,6 +906,8 @@ github.com/huandu/skiplist v1.2.0/go.mod h1:7v3iFjLcSAzO4fN5B8dvebvo/qsfumiLiDXM github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSASxEI= github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= @@ -858,8 +918,10 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/jgautheron/goconst v1.7.0 h1:cEqH+YBKLsECnRSd4F4TK5ri8t/aXtt/qoL0Ft252B0= -github.com/jgautheron/goconst v1.7.0/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jgautheron/goconst v1.7.1 h1:VpdAG7Ca7yvvJk5n8dMwQhfEZJh95kl/Hl9S1OI5Jkk= +github.com/jgautheron/goconst v1.7.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jhump/protoreflect v1.15.3 h1:6SFRuqU45u9hIZPJAoZ8c28T3nK64BNdp9w6jFonzls= github.com/jhump/protoreflect v1.15.3/go.mod h1:4ORHmSBmlCW8fh3xHmJMGyul1zNqZK4Elxc8qKP+p1k= github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= @@ -894,19 +956,21 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= -github.com/karamaru-alpha/copyloopvar v1.0.8 h1:gieLARwuByhEMxRwM3GRS/juJqFbLraftXIKDDNJ50Q= -github.com/karamaru-alpha/copyloopvar v1.0.8/go.mod h1:u7CIfztblY0jZLOQZgH3oYsJzpC2A7S6u/lfgSXHy0k= +github.com/karamaru-alpha/copyloopvar v1.0.10 h1:8HYDy6KQYqTmD7JuhZMWS1nwPru9889XI24ROd/+WXI= +github.com/karamaru-alpha/copyloopvar v1.0.10/go.mod h1:u7CIfztblY0jZLOQZgH3oYsJzpC2A7S6u/lfgSXHy0k= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/errcheck v1.7.0 h1:+SbscKmWJ5mOK/bO1zS60F5I9WwZDWOfRsC4RwfwRV0= github.com/kisielk/errcheck v1.7.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkHAIKE/contextcheck v1.1.4 h1:B6zAaLhOEEcjvUgIYEqystmnFk1Oemn8bvJhbt0GMb8= -github.com/kkHAIKE/contextcheck v1.1.4/go.mod h1:1+i/gWqokIa+dm31mqGLZhZJ7Uh44DJGZVmr6QRBNJg= +github.com/kkHAIKE/contextcheck v1.1.5 h1:CdnJh63tcDe53vG+RebdpdXJTc9atMgGqdx8LXxiilg= +github.com/kkHAIKE/contextcheck v1.1.5/go.mod h1:O930cpht4xb1YQpK+1+AgoM3mFsvxr7uyFptcnWTYUA= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= @@ -914,6 +978,7 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.3/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/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= 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= @@ -924,12 +989,16 @@ github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= github.com/kunwardeep/paralleltest v1.0.10 h1:wrodoaKYzS2mdNVnc4/w31YaXFtsc21PCTdvWJ/lDDs= github.com/kunwardeep/paralleltest v1.0.10/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ= github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= -github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA= -github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= +github.com/ldez/gomoddirectives v0.2.4 h1:j3YjBIjEBbqZ0NKtBNzr8rtMHTOrLPeiwTkfUJZ3alg= +github.com/ldez/gomoddirectives v0.2.4/go.mod h1:oWu9i62VcQDYp9EQ0ONTfqLNh+mDLWWDO+SO0qSQw5g= github.com/ldez/tagliatelle v0.5.0 h1:epgfuYt9v0CG3fms0pEgIMNPuFf/LpPIfjk4kyqSioo= github.com/ldez/tagliatelle v0.5.0/go.mod h1:rj1HmWiL1MiKQuOONhd09iySTEkUuE/8+5jtPYz9xa4= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= @@ -943,6 +1012,8 @@ github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-b github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/linxGnu/grocksdb v1.8.12 h1:1/pCztQUOa3BX/1gR3jSZDoaKFpeHFvQ1XrqZpSvZVo= github.com/linxGnu/grocksdb v1.8.12/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= @@ -976,8 +1047,9 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mgechev/revive v1.3.7 h1:502QY0vQGe9KtYJ9FpxMz9rL+Fc/P13CI5POL4uHCcE= github.com/mgechev/revive v1.3.7/go.mod h1:RJ16jUbF0OWC3co/+XTxmFNgEpUPwnnA0BRllX2aDNA= @@ -997,6 +1069,11 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= +github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= +github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -1004,8 +1081,13 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/moricho/tparallel v0.3.1 h1:fQKD4U1wRMAYNngDonW5XupoB/ZGJHdpzrWqgyg9krA= github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= @@ -1026,8 +1108,8 @@ github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhK github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= -github.com/nunnatsa/ginkgolinter v0.16.1 h1:uDIPSxgVHZ7PgbJElRDGzymkXH+JaF7mjew+Thjnt6Q= -github.com/nunnatsa/ginkgolinter v0.16.1/go.mod h1:4tWRinDN1FeJgU+iJANW/kz7xKN5nYRAOfJDQUS9dOQ= +github.com/nunnatsa/ginkgolinter v0.16.2 h1:8iLqHIZvN4fTLDC0Ke9tbSZVcyVHoBs0HIbnVSxfHJk= +github.com/nunnatsa/ginkgolinter v0.16.2/go.mod h1:4tWRinDN1FeJgU+iJANW/kz7xKN5nYRAOfJDQUS9dOQ= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= @@ -1155,6 +1237,8 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8 github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= 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= @@ -1167,8 +1251,10 @@ github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.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/ryancurrah/gomodguard v1.3.1 h1:fH+fUg+ngsQO0ruZXXHnA/2aNllWA1whly4a6UvyzGE= github.com/ryancurrah/gomodguard v1.3.1/go.mod h1:DGFHzEhi6iJ0oIDfMuo3TgrS+L9gZvrEfmjjuelnRU0= @@ -1195,6 +1281,10 @@ github.com/securego/gosec/v2 v2.19.0 h1:gl5xMkOI0/E6Hxx0XCY2XujA3V7SNSefA8sC+3f1 github.com/securego/gosec/v2 v2.19.0/go.mod h1:hOkDcHz9J/XIgIlPDXalxjeVYsHxoWUc5zJSHxcB8YM= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= @@ -1243,11 +1333,15 @@ github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ= github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk= github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobtDnDzA= +github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= 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/streamingfast/logging v0.0.0-20230608130331-f22c91403091 h1:RN5mrigyirb8anBEtdjtHFIufXdacyTi6i4KBfeNXeo= +github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= 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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= @@ -1269,6 +1363,8 @@ 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.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= +github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= +github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= @@ -1281,20 +1377,31 @@ github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= +github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= +github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= github.com/tetafro/godot v1.4.16 h1:4ChfhveiNLk4NveAZ9Pu2AN8QZ2nkUGFuadM9lrr5D0= github.com/tetafro/godot v1.4.16/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio= github.com/tidwall/btree v1.7.0 h1:L1fkJH/AuEh5zBnnBbmTwQ5Lt+bRJ5A8EWecslvo9iI= github.com/tidwall/btree v1.7.0/go.mod h1:twD9XRA5jj9VUQGELzDO4HPQTNJsoWWfYEL+EUQ2cKY= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 h1:quvGphlmUVU+nhpFa4gg4yJyTRJ13reZMDHrKwYw53M= github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tomarrell/wrapcheck/v2 v2.8.3 h1:5ov+Cbhlgi7s/a42BprYoxsr73CbdMUTzE3bRDFASUs= github.com/tomarrell/wrapcheck/v2 v2.8.3/go.mod h1:g9vNIyhb5/9TQgumxQyOEqDHsmGYcGsVMOx/xGkqdMo= github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= @@ -1309,21 +1416,30 @@ github.com/ultraware/funlen v0.1.0/go.mod h1:XJqmOQja6DpxarLj6Jj1U7JuoS8PvL4nEqD github.com/ultraware/whitespace v0.1.0 h1:O1HKYoh0kIeqE8sFqZf1o0qbORXUCOQFrlaQyZsczZw= github.com/ultraware/whitespace v0.1.0/go.mod h1:/se4r3beMFNmewJ4Xmz0nMQ941GJt+qmSHGP9emHYe0= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs= +github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ= github.com/uudashr/gocognit v1.1.2 h1:l6BAEKJqQH2UpKAPKdMfZf5kE4W/2xk8pfU1OVLvniI= github.com/uudashr/gocognit v1.1.2/go.mod h1:aAVdLURqcanke8h3vg35BC++eseDm66Z7KmchI5et4k= -github.com/vektra/mockery/v2 v2.42.1 h1:z7l3O4jCzRZat3rm9jpHc8lzpR8bs1VBii7bYtl3KQs= -github.com/vektra/mockery/v2 v2.42.1/go.mod h1:XNTE9RIu3deGAGQRVjP1VZxGpQNm0YedZx4oDs3prr8= +github.com/vektra/mockery/v2 v2.42.2 h1:SSIvwnXBl9EynibBZhQ/hBXuV5TYPdZFIqkm4UkQHU4= +github.com/vektra/mockery/v2 v2.42.2/go.mod h1:XNTE9RIu3deGAGQRVjP1VZxGpQNm0YedZx4oDs3prr8= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= +github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU= github.com/xen0n/gosmopolitan v1.2.2/go.mod h1:7XX7Mj61uLYrj0qmeN0zi7XDon9JRAEhYQqAPLVNTeg= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= +github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y3o= github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= github.com/ykadowak/zerologlint v0.1.5 h1:Gy/fMz1dFQN9JZTPjv1hxEk+sRWm05row04Yoolgdiw= github.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= 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= @@ -1347,6 +1463,8 @@ go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA= go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.mongodb.org/mongo-driver v1.11.0 h1:FZKhBSTydeuffHj9CBjXlR8vQLee1cQyTWYPA6/tqiE= +go.mongodb.org/mongo-driver v1.11.0/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8= 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= @@ -1375,9 +1493,12 @@ 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= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= +go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11/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= @@ -1385,10 +1506,13 @@ go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+ go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= 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/ratelimit v0.2.0 h1:UQE2Bgi7p2B85uP5dC2bbRtig0C+OeNRnNEafLjsLPA= +go.uber.org/ratelimit v0.2.0/go.mod h1:YYBV4e4naJvhpitQrWJu1vCpgB7CboMe0qhltKt6mUg= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= 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.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= 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= @@ -1402,9 +1526,11 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= -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.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= +golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1504,6 +1630,7 @@ golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -1519,8 +1646,8 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -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.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= +golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= 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= @@ -1546,8 +1673,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= -golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/oauth2 v0.17.0 h1:6m3ZPmLEFdVxKKWnKq4VqZ60gutO35zm+zrAHVmHyDQ= +golang.org/x/oauth2 v0.17.0/go.mod h1:OzPDGQiuQMguemayvdylqddI7qcD9lnSDb+1FiwQ5HA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1563,8 +1690,8 @@ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +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= @@ -1587,6 +1714,7 @@ golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1671,17 +1799,19 @@ golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= -golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= +golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1961,8 +2091,8 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= +google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8 h1:8eadJkXbwDEMNwcB5O0s5Y5eCfyuCLdvaiOIaGTrWmQ= google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641 h1:DKU1r6Tj5s1vlU/moGhuGz7E3xRfwjdAfDzbsaQJtEY= @@ -2008,8 +2138,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= -google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= +google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8= +google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= 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= @@ -2042,6 +2172,8 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -2083,6 +2215,8 @@ pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= +rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/oracle/config/api.go b/oracle/config/api.go index e0524a3c9..8bd5c1e79 100644 --- a/oracle/config/api.go +++ b/oracle/config/api.go @@ -33,10 +33,20 @@ type APIConfig struct { // URL is the URL that is used to fetch data from the API. URL string `json:"url"` + // Endpoints is a list of endpoints that the provider can query. + Endpoints []Endpoint `json:"endpoints"` + // Name is the name of the provider that corresponds to this config. Name string `json:"name"` } +// Endpoint holds all data necessary for an API provider to connect to a given endpoint +// i.e URL, headers, authentication, etc. +type Endpoint struct { + // URL is the URL that is used to fetch data from the API. + URL string `json:"url"` +} + // ValidateBasic performs basic validation of the API config. func (c *APIConfig) ValidateBasic() error { if !c.Enabled { @@ -51,8 +61,8 @@ func (c *APIConfig) ValidateBasic() error { return fmt.Errorf("provider interval, timeout and reconnect timeout must be strictly positive") } - if len(c.URL) == 0 { - return fmt.Errorf("provider url cannot be empty") + if len(c.URL) == 0 && len(c.Endpoints) == 0 { + return fmt.Errorf("provider url and endpoints cannot be empty") } if len(c.Name) == 0 { diff --git a/oracle/config/api_test.go b/oracle/config/api_test.go index a532645b6..45a47d6ae 100644 --- a/oracle/config/api_test.go +++ b/oracle/config/api_test.go @@ -83,7 +83,7 @@ func TestAPIConfig(t *testing.T) { expectedErr: true, }, { - name: "bad config with no url", + name: "bad config with no url / endpoint", config: config.APIConfig{ Enabled: true, Timeout: time.Second, @@ -106,6 +106,19 @@ func TestAPIConfig(t *testing.T) { }, expectedErr: true, }, + { + name: "good config with endpoints instead of url", + config: config.APIConfig{ + Enabled: true, + Timeout: time.Second, + Interval: time.Second, + ReconnectTimeout: time.Second, + MaxQueries: 1, + Name: "test", + Endpoints: []config.Endpoint{{URL: "http://test.com"}}, + }, + expectedErr: false, + }, } for _, tc := range testCases { diff --git a/oracle/metrics/mocks/mock_metrics.go b/oracle/metrics/mocks/mock_metrics.go index 4ecdd2958..d677ead93 100644 --- a/oracle/metrics/mocks/mock_metrics.go +++ b/oracle/metrics/mocks/mock_metrics.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.30.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/oracle/mocks/mock_oracle.go b/oracle/mocks/mock_oracle.go index 5379bf641..918a00ef7 100644 --- a/oracle/mocks/mock_oracle.go +++ b/oracle/mocks/mock_oracle.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/oracle/types/oracle.go b/oracle/types/oracle.go index f156c2cab..5631dfb73 100644 --- a/oracle/types/oracle.go +++ b/oracle/types/oracle.go @@ -127,6 +127,9 @@ var ( // used by the price providers. NewPriceAPIQueryHandler = apihandlers.NewAPIQueryHandler[mmtypes.Ticker, *big.Int] + // NewPriceAPIQueryHandlerWithFetcher is a function alias for the new API query handler with fetcher. + NewPriceAPIQueryHandlerWithFetcher = apihandlers.NewAPIQueryHandlerWithFetcher[mmtypes.Ticker, *big.Int] + // NewPriceWebSocketQueryHandler is a function alias for the new web socket query handler meant to be // used by the price providers. NewPriceWebSocketQueryHandler = wshandlers.NewWebSocketQueryHandler[mmtypes.Ticker, *big.Int] diff --git a/pkg/math/math.go b/pkg/math/math.go index e2b11ad35..3dd1d0c93 100644 --- a/pkg/math/math.go +++ b/pkg/math/math.go @@ -2,6 +2,8 @@ package math import ( "math/big" + + "golang.org/x/exp/constraints" ) // Min returns the minimum of two values. @@ -19,6 +21,14 @@ func Min[V int | int64 | uint64 | int32 | uint32](vals ...V) V { return minimum } +// Abs returns the absolute value of a given number. +func Abs[V constraints.Signed](val V) V { + if val < 0 { + return -val + } + return val +} + // Float64StringToBigInt converts a float64 string to a big.Int. func Float64StringToBigInt(s string, decimals uint64) (*big.Int, error) { bigFloat := new(big.Float) diff --git a/pkg/math/math_test.go b/pkg/math/math_test.go index ed4e3bd46..02543859b 100644 --- a/pkg/math/math_test.go +++ b/pkg/math/math_test.go @@ -54,6 +54,39 @@ func TestMin(t *testing.T) { } } +func TestAbs(t *testing.T) { + testCases := []struct { + name string + val int + expected int + }{ + { + name: "positive", + val: 1, + expected: 1, + }, + { + name: "negative", + val: -1, + expected: 1, + }, + { + name: "zero", + val: 0, + expected: 0, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + got := math.Abs(tc.val) + if got != tc.expected { + t.Errorf("expected %d, got %d", tc.expected, got) + } + }) + } +} + func TestFloat64StringToBigInt(t *testing.T) { testCases := []struct { name string diff --git a/pkg/math/oracle/helper_test.go b/pkg/math/oracle/helper_test.go index 370f82ba7..2f5fb662c 100644 --- a/pkg/math/oracle/helper_test.go +++ b/pkg/math/oracle/helper_test.go @@ -2,9 +2,7 @@ package oracle_test import ( "math/big" - "testing" - "github.com/stretchr/testify/require" "go.uber.org/zap" "github.com/skip-mev/slinky/oracle/constants" @@ -270,44 +268,6 @@ var ( } ) -// verifyPrice verifies that the expected price matches the actual price within an acceptable delta. -func verifyPrice(t *testing.T, expected, actual *big.Int) { - t.Helper() - - zero := big.NewInt(0) - if expected.Cmp(zero) == 0 { - require.Equal(t, zero, actual) - return - } - - var diff *big.Float - if expected.Cmp(actual) > 0 { - diff = new(big.Float).Sub(new(big.Float).SetInt(expected), new(big.Float).SetInt(actual)) - } else { - diff = new(big.Float).Sub(new(big.Float).SetInt(actual), new(big.Float).SetInt(expected)) - } - - scaledDiff := new(big.Float).Quo(diff, new(big.Float).SetInt(expected)) - delta, _ := scaledDiff.Float64() - t.Logf("expected price: %s; actual price: %s; diff %s", expected.String(), actual.String(), diff.String()) - t.Logf("acceptable delta: %.25f; actual delta: %.25f", acceptableDelta, delta) - - switch { - case delta == 0: - // If the difference between the expected and actual price is 0, the prices match. - // No need for a delta comparison. - return - case delta <= acceptableDelta: - // If the difference between the expected and actual price is within the acceptable delta, - // the prices match. - return - default: - // If the difference between the expected and actual price is greater than the acceptable delta, - // the prices do not match. - require.Fail(t, "expected price does not match the actual price; delta is too large") - } -} - // createPrice creates a price with the given number of decimals. func createPrice(price float64, decimals uint64) *big.Int { // Convert the price to a big float so we can perform the multiplication. diff --git a/pkg/math/oracle/median_test.go b/pkg/math/oracle/median_test.go index 7b472c3c9..1e6bd2eda 100644 --- a/pkg/math/oracle/median_test.go +++ b/pkg/math/oracle/median_test.go @@ -8,6 +8,7 @@ import ( "github.com/skip-mev/slinky/oracle/metrics" "github.com/skip-mev/slinky/oracle/types" + "github.com/skip-mev/slinky/pkg/math" "github.com/skip-mev/slinky/pkg/math/oracle" "github.com/skip-mev/slinky/providers/apis/binance" "github.com/skip-mev/slinky/providers/apis/coinbase" @@ -149,7 +150,7 @@ func TestAggregateData(t *testing.T) { result := m.DataAggregator.GetAggregatedData() require.Equal(t, len(tc.expectedPrices), len(result)) for ticker, price := range result { - verifyPrice(t, tc.expectedPrices[ticker], price) + math.VerifyPrice(t, tc.expectedPrices[ticker], price, acceptableDelta) } }) } @@ -445,7 +446,7 @@ func TestCalculateConvertedPrices(t *testing.T) { // Ensure that the prices are as expected. for i, price := range prices { - verifyPrice(t, tc.expectedPrices[i], price) + math.VerifyPrice(t, tc.expectedPrices[i], price, acceptableDelta) } }) } @@ -922,7 +923,7 @@ func TestCalculateAdjustedPrice(t *testing.T) { } require.NoError(t, err) - verifyPrice(t, tc.expectedPrice, price) + math.VerifyPrice(t, tc.expectedPrice, price, acceptableDelta) }) } } diff --git a/pkg/math/oracle/utils_test.go b/pkg/math/oracle/utils_test.go index 29d0e26d6..f7ee4487d 100644 --- a/pkg/math/oracle/utils_test.go +++ b/pkg/math/oracle/utils_test.go @@ -8,6 +8,7 @@ import ( "github.com/skip-mev/slinky/oracle/constants" "github.com/skip-mev/slinky/oracle/metrics" "github.com/skip-mev/slinky/oracle/types" + "github.com/skip-mev/slinky/pkg/math" "github.com/skip-mev/slinky/pkg/math/oracle" "github.com/skip-mev/slinky/providers/apis/coinbase" mmtypes "github.com/skip-mev/slinky/x/marketmap/types" @@ -171,6 +172,6 @@ func TestGetProviderPrice(t *testing.T) { price, err := m.GetProviderPrice(operation) require.NoError(t, err) expectedPrice := createPrice(0.000025, oracle.ScaledDecimals) - verifyPrice(t, expectedPrice, price) + math.VerifyPrice(t, expectedPrice, price, acceptableDelta) }) } diff --git a/pkg/math/testutils.go b/pkg/math/testutils.go new file mode 100644 index 000000000..738247632 --- /dev/null +++ b/pkg/math/testutils.go @@ -0,0 +1,51 @@ +package math + +import ( + "math/big" + "testing" + + "github.com/stretchr/testify/require" +) + +// VerifyPrice verifies that the expected price matches the actual price within an acceptable delta. +func VerifyPrice( + t *testing.T, + expected, + actual *big.Int, + acceptableDelta float64, +) { + t.Helper() + + zero := big.NewInt(0) + if expected.Cmp(zero) == 0 { + require.Equal(t, zero, actual) + return + } + + var diff *big.Float + if expected.Cmp(actual) > 0 { + diff = new(big.Float).Sub(new(big.Float).SetInt(expected), new(big.Float).SetInt(actual)) + } else { + diff = new(big.Float).Sub(new(big.Float).SetInt(actual), new(big.Float).SetInt(expected)) + } + + scaledDiff := new(big.Float).Quo(diff, new(big.Float).SetInt(expected)) + delta, _ := scaledDiff.Float64() + t.Logf("expected price: %s; actual price: %s; diff %s", expected.String(), actual.String(), diff.String()) + t.Logf("acceptable delta: %.25f; actual delta: %.25f", acceptableDelta, delta) + + switch { + case delta == 0: + // If the difference between the expected and actual price is 0, the prices match. + // No need for a delta comparison. + return + case delta <= acceptableDelta: + // If the difference between the expected and actual price is within the acceptable delta, + // the prices match. + return + default: + // If the difference between the expected and actual price is greater than the acceptable delta, + // the prices do not match. + require.Fail(t, "expected price does not match the actual price; delta is too large") + } +} diff --git a/pkg/math/voteweighted/mocks/mock_validator.go b/pkg/math/voteweighted/mocks/mock_validator.go index d51a4c693..be735a405 100644 --- a/pkg/math/voteweighted/mocks/mock_validator.go +++ b/pkg/math/voteweighted/mocks/mock_validator.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/pkg/math/voteweighted/mocks/mock_validator_store.go b/pkg/math/voteweighted/mocks/mock_validator_store.go index e0bbcba47..8ca20ab0a 100644 --- a/pkg/math/voteweighted/mocks/mock_validator_store.go +++ b/pkg/math/voteweighted/mocks/mock_validator_store.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/providers/apis/defi/raydium/mocks/solana_jsonrpc_client.go b/providers/apis/defi/raydium/mocks/solana_jsonrpc_client.go new file mode 100644 index 000000000..e8d6145cb --- /dev/null +++ b/providers/apis/defi/raydium/mocks/solana_jsonrpc_client.go @@ -0,0 +1,62 @@ +// Code generated by mockery v2.40.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + + rpc "github.com/gagliardetto/solana-go/rpc" + + solana "github.com/gagliardetto/solana-go" +) + +// SolanaJSONRPCClient is an autogenerated mock type for the SolanaJSONRPCClient type +type SolanaJSONRPCClient struct { + mock.Mock +} + +// GetMultipleAccountsWithOpts provides a mock function with given fields: ctx, accounts, opts +func (_m *SolanaJSONRPCClient) GetMultipleAccountsWithOpts(ctx context.Context, accounts []solana.PublicKey, opts *rpc.GetMultipleAccountsOpts) (*rpc.GetMultipleAccountsResult, error) { + ret := _m.Called(ctx, accounts, opts) + + if len(ret) == 0 { + panic("no return value specified for GetMultipleAccountsWithOpts") + } + + var r0 *rpc.GetMultipleAccountsResult + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, []solana.PublicKey, *rpc.GetMultipleAccountsOpts) (*rpc.GetMultipleAccountsResult, error)); ok { + return rf(ctx, accounts, opts) + } + if rf, ok := ret.Get(0).(func(context.Context, []solana.PublicKey, *rpc.GetMultipleAccountsOpts) *rpc.GetMultipleAccountsResult); ok { + r0 = rf(ctx, accounts, opts) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*rpc.GetMultipleAccountsResult) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, []solana.PublicKey, *rpc.GetMultipleAccountsOpts) error); ok { + r1 = rf(ctx, accounts, opts) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// NewSolanaJSONRPCClient creates a new instance of SolanaJSONRPCClient. 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 NewSolanaJSONRPCClient(t interface { + mock.TestingT + Cleanup(func()) +}) *SolanaJSONRPCClient { + mock := &SolanaJSONRPCClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/providers/apis/defi/raydium/multi_client.go b/providers/apis/defi/raydium/multi_client.go new file mode 100644 index 000000000..79cbf375c --- /dev/null +++ b/providers/apis/defi/raydium/multi_client.go @@ -0,0 +1,102 @@ +package raydium + +import ( + "context" + "fmt" + "sync" + + "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/rpc" + "go.uber.org/zap" + + oracleconfig "github.com/skip-mev/slinky/oracle/config" +) + +// MultiJSONRPCClient is an implementation of the SolanaJSONRPCClient interface that delegates +// requests to multiple underlying clients, and aggregates over all provided responses. +type MultiJSONRPCClient struct { + // underlying clients + clients []SolanaJSONRPCClient + + // logger + logger *zap.Logger +} + +func NewMultiJSONRPCClient(clients []SolanaJSONRPCClient, logger *zap.Logger) *MultiJSONRPCClient { + return &MultiJSONRPCClient{ + clients: clients, + logger: logger, + } +} + +// NewMultiJSONRPCClientFromEndpoints creates a new MultiJSONRPCClient from a list of endpoints. +func NewMultiJSONRPCClientFromEndpoints(endpoints []oracleconfig.Endpoint, logger *zap.Logger) *MultiJSONRPCClient { + clients := make([]SolanaJSONRPCClient, len(endpoints)) + for i := range endpoints { + client := rpc.New(endpoints[i].URL) + clients[i] = client + } + return NewMultiJSONRPCClient(clients, logger) +} + +// GetMultipleAccountsWithOpts delegates the request to all underlying clients and applies a filter +// to the responses. +func (c *MultiJSONRPCClient) GetMultipleAccountsWithOpts( + ctx context.Context, + accounts []solana.PublicKey, + opts *rpc.GetMultipleAccountsOpts, +) (*rpc.GetMultipleAccountsResult, error) { + // Create a channel to receive the responses from the underlying clients + responsesCh := make(chan *rpc.GetMultipleAccountsResult, len(c.clients)) + + // spawn a goroutine for each client to fetch the accounts + var wg sync.WaitGroup + wg.Add(len(c.clients)) + + for i := range c.clients { + go func(client SolanaJSONRPCClient) { + defer wg.Done() + resp, err := client.GetMultipleAccountsWithOpts(ctx, accounts, opts) + if err != nil { + c.logger.Error("failed to fetch accounts", zap.Error(err)) + return + } + responsesCh <- resp + }(c.clients[i]) + } + + // close the channel once all responses are received, or the context is cancelled + go func() { + defer close(responsesCh) + wg.Wait() + }() + + responses := make([]*rpc.GetMultipleAccountsResult, 0, len(c.clients)) + for resp := range responsesCh { + responses = append(responses, resp) + } + + // filter the responses + return filterAccountsResponses(responses) +} + +// filterAccountsResponses chooses the rpc response with the highest slot number. +func filterAccountsResponses(responses []*rpc.GetMultipleAccountsResult) (*rpc.GetMultipleAccountsResult, error) { + var ( + maxSlot uint64 + maxResp *rpc.GetMultipleAccountsResult + ) + + if len(responses) == 0 { + return nil, fmt.Errorf("no responses to filter") + } + + for _, resp := range responses { + if resp.Context.Slot > maxSlot { + maxSlot = resp.Context.Slot + maxResp = resp + } + } + + return maxResp, nil +} diff --git a/providers/apis/defi/raydium/multi_client_test.go b/providers/apis/defi/raydium/multi_client_test.go new file mode 100644 index 000000000..04a46c529 --- /dev/null +++ b/providers/apis/defi/raydium/multi_client_test.go @@ -0,0 +1,98 @@ +package raydium_test + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/rpc" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + + "github.com/skip-mev/slinky/providers/apis/defi/raydium" + "github.com/skip-mev/slinky/providers/apis/defi/raydium/mocks" +) + +// TestMultiJSONRPCClient tests the MultiJSONRPCClient. +func TestMultiJSONRPCClient(t *testing.T) { + client1 := mocks.NewSolanaJSONRPCClient(t) + client2 := mocks.NewSolanaJSONRPCClient(t) + client3 := mocks.NewSolanaJSONRPCClient(t) + client := raydium.NewMultiJSONRPCClient([]raydium.SolanaJSONRPCClient{client1, client2, client3}, zap.NewNop()) + + // test adherence to the context + t.Run("test failures in underlying client", func(t *testing.T) { + accounts := []solana.PublicKey{{}} + opts := &rpc.GetMultipleAccountsOpts{} + + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + // mocks + client1.On("GetMultipleAccountsWithOpts", ctx, accounts, opts).Return(&rpc.GetMultipleAccountsResult{ + RPCContext: rpc.RPCContext{ + Context: rpc.Context{ + Slot: 1, + }, + }, + }, nil) + client2.On("GetMultipleAccountsWithOpts", ctx, accounts, opts).Return(&rpc.GetMultipleAccountsResult{ + RPCContext: rpc.RPCContext{ + Context: rpc.Context{ + Slot: 2, + }, + }, + }, nil) + client3.On("GetMultipleAccountsWithOpts", ctx, accounts, opts).Return(&rpc.GetMultipleAccountsResult{ + RPCContext: rpc.RPCContext{ + Context: rpc.Context{ + Slot: 3, + }, + }, + }, fmt.Errorf("error")) + + resp, err := client.GetMultipleAccountsWithOpts(ctx, accounts, opts) + require.NoError(t, err) + + require.Equal(t, uint64(2), resp.RPCContext.Context.Slot) + }) + + // test correct aggregation of responses + t.Run("test correct aggregation of responses", func(t *testing.T) { + accounts := []solana.PublicKey{{}} + opts := &rpc.GetMultipleAccountsOpts{} + + ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second) + defer cancel() + + // mocks + client1.On("GetMultipleAccountsWithOpts", ctx, accounts, opts).Return(&rpc.GetMultipleAccountsResult{ + RPCContext: rpc.RPCContext{ + Context: rpc.Context{ + Slot: 1, + }, + }, + }, nil) + client2.On("GetMultipleAccountsWithOpts", ctx, accounts, opts).Return(&rpc.GetMultipleAccountsResult{ + RPCContext: rpc.RPCContext{ + Context: rpc.Context{ + Slot: 2, + }, + }, + }, nil) + client3.On("GetMultipleAccountsWithOpts", ctx, accounts, opts).Return(&rpc.GetMultipleAccountsResult{ + RPCContext: rpc.RPCContext{ + Context: rpc.Context{ + Slot: 3, + }, + }, + }, nil) + + resp, err := client.GetMultipleAccountsWithOpts(ctx, accounts, opts) + require.NoError(t, err) + + require.Equal(t, uint64(3), resp.RPCContext.Context.Slot) + }) +} diff --git a/providers/apis/defi/raydium/options.go b/providers/apis/defi/raydium/options.go new file mode 100644 index 000000000..622521899 --- /dev/null +++ b/providers/apis/defi/raydium/options.go @@ -0,0 +1,11 @@ +package raydium + +// Option is a function that can be used to modify the APIPriceFetcher. +type Option func(*APIPriceFetcher) + +// WithSolanaClient sets the SolanaJSONRPCClient used to query the API. +func WithSolanaClient(client SolanaJSONRPCClient) Option { + return func(f *APIPriceFetcher) { + f.client = client + } +} diff --git a/providers/apis/defi/raydium/price_fetcher.go b/providers/apis/defi/raydium/price_fetcher.go new file mode 100644 index 000000000..b94ac998d --- /dev/null +++ b/providers/apis/defi/raydium/price_fetcher.go @@ -0,0 +1,282 @@ +package raydium + +import ( + "context" + "fmt" + "math/big" + "time" + + binary "github.com/gagliardetto/binary" + "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/programs/token" + "github.com/gagliardetto/solana-go/rpc" + "go.uber.org/zap" + + "github.com/skip-mev/slinky/oracle/config" + oracletypes "github.com/skip-mev/slinky/oracle/types" + "github.com/skip-mev/slinky/pkg/math" + oraclemath "github.com/skip-mev/slinky/pkg/math/oracle" + providertypes "github.com/skip-mev/slinky/providers/types" + mmtypes "github.com/skip-mev/slinky/x/marketmap/types" +) + +var _ oracletypes.PriceAPIFetcher = (*APIPriceFetcher)(nil) + +// SolanaJSONRPCClient is the expected interface for a solana JSON-RPC client according +// to the APIPriceFetcher. +// +//go:generate mockery --name SolanaJSONRPCClient --output ./mocks/ --case underscore +type SolanaJSONRPCClient interface { + GetMultipleAccountsWithOpts( + ctx context.Context, + accounts []solana.PublicKey, + opts *rpc.GetMultipleAccountsOpts, + ) (out *rpc.GetMultipleAccountsResult, err error) +} + +// APIPriceFetcher is responsible for interacting with the solana API and querying information +// about the price of a given currency pair. +type APIPriceFetcher struct { + // market represents the ticker configurations for this provider. + markets oracletypes.ProviderMarketMap + + // config is the APIConfiguration for this provider + config config.APIConfig + + // client is the solana JSON-RPC client used to query the API. + client SolanaJSONRPCClient + + // metaDataPerTicker is a map of ticker.String() -> TickerMetadata + metaDataPerTicker map[string]TickerMetadata + + // logger + logger *zap.Logger +} + +// NewAPIPriceFetcher returns a new APIPriceFetcher. This method constructs the +// default solana JSON-RPC client in accordance with the config's URL param. +func NewAPIPriceFetcher( + market oracletypes.ProviderMarketMap, + config config.APIConfig, + logger *zap.Logger, + opts ...Option, +) (*APIPriceFetcher, error) { + // use a multi-client if multiple endpoints are provided + if len(config.Endpoints) > 0 { + if len(config.Endpoints) > 1 { + opts = append(opts, WithSolanaClient( + NewMultiJSONRPCClientFromEndpoints( + config.Endpoints, + logger.With(zap.String("raydium_multi_client", Name)), + ), + )) + } else { + config.URL = config.Endpoints[0].URL + } + } + + return NewAPIPriceFetcherWithClient( + market, + config, + rpc.New(config.URL), + logger, + opts..., + ) +} + +// NewAPIPriceFetcherWithClient returns a new APIPriceFetcher. This method requires +// that the given market + config are valid, otherwise a nil implementation + an error +// will be returned. +func NewAPIPriceFetcherWithClient( + markets oracletypes.ProviderMarketMap, + config config.APIConfig, + client SolanaJSONRPCClient, + logger *zap.Logger, + opts ...Option, +) (*APIPriceFetcher, error) { + if err := config.ValidateBasic(); err != nil { + return nil, fmt.Errorf("config for raydium is invalid: %w", err) + } + + if err := markets.ValidateBasic(); err != nil { + return nil, fmt.Errorf("market config for raydium is invalid: %w", err) + } + + // check fields of config + if config.Name != Name { + return nil, fmt.Errorf("configured name is incorrect; expected: %s, got: %s", Name, config.Name) + } + + if markets.Name != Name { + return nil, fmt.Errorf("market config name is incorrect; expected: %s, got: %s", Name, markets.Name) + } + + if !config.Enabled { + return nil, fmt.Errorf("config is not enabled") + } + + // generate metadata per ticker + metadataPerTicker := make(map[string]TickerMetadata) + for _, ticker := range markets.OffChainMap { + metadata, err := unmarshalMetadataJSON(ticker.Metadata_JSON) + if err != nil { + return nil, fmt.Errorf("error unmarshalling metadata for ticker %s: %w", ticker.String(), err) + } + + if err := metadata.ValidateBasic(); err != nil { + return nil, fmt.Errorf("metadata for ticker %s is invalid: %w", ticker.String(), err) + } + + metadataPerTicker[ticker.String()] = metadata + } + + pf := &APIPriceFetcher{ + markets: markets, + config: config, + client: client, + metaDataPerTicker: metadataPerTicker, + logger: logger.With(zap.String("raydium_api_price_fetcher", Name)), + } + + for _, opt := range opts { + opt(pf) + } + + return pf, nil +} + +// FetchPrices fetches prices from the solana JSON-RPC API for the given currency-pairs. Specifically +// for each currency-pair, +// - Query the raydium API base (coin) / quote (pc) token vault addresses +// - Normalize the token balances by 1e18 +// - Calculate the price as quote / base, and scale by ticker.Decimals +func (pf *APIPriceFetcher) Fetch( + ctx context.Context, + tickers []mmtypes.Ticker, +) providertypes.GetResponse[mmtypes.Ticker, *big.Int] { + // get the acounts to query in order of the tickers given + expectedNumAccounts := len(tickers) * 2 + accounts := make([]solana.PublicKey, expectedNumAccounts) + + for i, ticker := range tickers { + metadata, ok := pf.metaDataPerTicker[ticker.String()] + if !ok { + return providertypes.NewGetResponseWithErr[mmtypes.Ticker, *big.Int]( + tickers, + providertypes.NewErrorWithCode( + NoRaydiumMetadataForTickerError(ticker.String()), + providertypes.ErrorUnknownPair, + ), + ) + } + + accounts[i*2] = solana.MustPublicKeyFromBase58(metadata.BaseTokenVault.TokenVaultAddress) + accounts[i*2+1] = solana.MustPublicKeyFromBase58(metadata.QuoteTokenVault.TokenVaultAddress) + } + + // query the accounts + // We assume that the solana JSON-RPC response returns all accounts in the order + // that they were queried, there is not a very good way to handle if this order is incorrect + // or verify that the order is correct, as there is no way to correlate account data <> address + ctx, cancel := context.WithTimeout(ctx, pf.config.Timeout) + defer cancel() + + accountsResp, err := pf.client.GetMultipleAccountsWithOpts(ctx, accounts, &rpc.GetMultipleAccountsOpts{ + Commitment: rpc.CommitmentFinalized, + // TODO(nikhil): Keep track of latest height queried as well? + }) + if err != nil { + return providertypes.NewGetResponseWithErr[mmtypes.Ticker, *big.Int]( + tickers, + providertypes.NewErrorWithCode( + SolanaJSONRPCError(err), + providertypes.ErrorAPIGeneral, + ), + ) + } + + // expect a base / quote vault account for each ticker queried + if len(accountsResp.Value) != expectedNumAccounts { + return providertypes.NewGetResponseWithErr[mmtypes.Ticker, *big.Int]( + tickers, + providertypes.NewErrorWithCode( + SolanaJSONRPCError(fmt.Errorf("expected %d accounts, got %d", expectedNumAccounts, len(accountsResp.Value))), + providertypes.ErrorAPIGeneral, + ), + ) + } + + resolved := make(oracletypes.ResolvedPrices) + unresolved := make(oracletypes.UnResolvedPrices) + for i, ticker := range tickers { + baseAccount := accountsResp.Value[i*2] + quoteAccount := accountsResp.Value[i*2+1] + + metadata := pf.metaDataPerTicker[ticker.String()] + + // parse the token balances + baseTokenBalance, err := getScaledTokenBalance(baseAccount, metadata.BaseTokenVault.TokenDecimals) + if err != nil { + pf.logger.Debug("error getting base token balance", zap.Error(err)) + unresolved[ticker] = providertypes.UnresolvedResult{ + ErrorWithCode: providertypes.NewErrorWithCode( + SolanaJSONRPCError(err), + providertypes.ErrorAPIGeneral, + ), + } + continue + } + + quoteTokenBalance, err := getScaledTokenBalance(quoteAccount, metadata.QuoteTokenVault.TokenDecimals) + if err != nil { + pf.logger.Debug("error getting quote token balance", zap.Error(err)) + unresolved[ticker] = providertypes.UnresolvedResult{ + ErrorWithCode: providertypes.NewErrorWithCode( + SolanaJSONRPCError(err), + providertypes.ErrorAPIGeneral, + ), + } + continue + } + + pf.logger.Debug("balances", zap.String("base", baseTokenBalance.String()), zap.String("quote", quoteTokenBalance.String())) + + // calculate the price + price := calculatePrice(baseTokenBalance, quoteTokenBalance, ticker.Decimals) + + // return the price + resolved[ticker] = oracletypes.NewPriceResult(price, time.Now()) + } + + return oracletypes.NewPriceResponse(resolved, unresolved) +} + +func getScaledTokenBalance(account *rpc.Account, tokenDecimals uint64) (*big.Int, error) { + // if the account is nil, return error + if account == nil { + return nil, fmt.Errorf("account is nil") + } + + // if the account is empty, return error + if account.Data == nil { + return nil, fmt.Errorf("account data is nil") + } + + // unmarshal the account data into a token account + var tokenAccount token.Account + if err := binary.NewBinDecoder(account.Data.GetBinary()).Decode(&tokenAccount); err != nil { + return nil, err + } + + // get the token balance + scale by decimals + balance := new(big.Int).SetUint64(tokenAccount.Amount) + return oraclemath.ScaleUpCurrencyPairPrice(tokenDecimals, balance) +} + +func calculatePrice(baseTokenBalance, quoteTokenBalance *big.Int, decimals uint64) *big.Int { + // calculate the price as quote / base + price := new(big.Float).Quo(new(big.Float).SetInt(quoteTokenBalance), new(big.Float).SetInt(baseTokenBalance)) + + // scale by the ticker decimals + return math.BigFloatToBigInt(price, decimals) +} diff --git a/providers/apis/defi/raydium/price_fetcher_test.go b/providers/apis/defi/raydium/price_fetcher_test.go new file mode 100644 index 000000000..3b5172a08 --- /dev/null +++ b/providers/apis/defi/raydium/price_fetcher_test.go @@ -0,0 +1,629 @@ +package raydium_test + +import ( + "bytes" + "context" + "encoding/json" + "fmt" + "strings" + "testing" + "time" + + bin "github.com/gagliardetto/binary" + "github.com/gagliardetto/solana-go" + "github.com/gagliardetto/solana-go/programs/token" + "github.com/gagliardetto/solana-go/rpc" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "go.uber.org/zap" + + oracleconfig "github.com/skip-mev/slinky/oracle/config" + oracletypes "github.com/skip-mev/slinky/oracle/types" + slinkytypes "github.com/skip-mev/slinky/pkg/types" + "github.com/skip-mev/slinky/providers/apis/defi/raydium" + "github.com/skip-mev/slinky/providers/apis/defi/raydium/mocks" + mmtypes "github.com/skip-mev/slinky/x/marketmap/types" +) + +const ( + USDCVaultAddress = "8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6" + BTCVaultAddress = "8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh5" + ETHVaultAddress = "8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh4" + USDTVaultAddress = "8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh3" + MOGVaultAddress = "8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh2" + SOLVaultAddress = "8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh1" +) + +func TestTickerMetadataValidateBasic(t *testing.T) { + tcs := []struct { + name string + raydium.TickerMetadata + expFail bool + }{ + { + name: "invalid base token vault address", + TickerMetadata: raydium.TickerMetadata{ + BaseTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: "", + TokenDecimals: 6, + }, + QuoteTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: USDCVaultAddress, + TokenDecimals: 6, + }, + }, + expFail: true, + }, + { + name: "invalid quote token vault address", + TickerMetadata: raydium.TickerMetadata{ + BaseTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: USDCVaultAddress, + TokenDecimals: 6, + }, + QuoteTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: "", + TokenDecimals: 6, + }, + }, + expFail: true, + }, + { + name: "valid", + TickerMetadata: raydium.TickerMetadata{ + BaseTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: USDCVaultAddress, + TokenDecimals: 6, + }, + QuoteTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: USDCVaultAddress, + TokenDecimals: 6, + }, + }, + expFail: false, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + err := tc.TickerMetadata.ValidateBasic() + if tc.expFail { + require.Error(t, err) + } else { + require.NoError(t, err) + } + }) + } +} + +// Test Provider init. +func TestProviderInit(t *testing.T) { + t.Run("config fails validate basic", func(t *testing.T) { + cfg := oracleconfig.APIConfig{ + Enabled: true, + MaxQueries: 0, + } + + _, err := raydium.NewAPIPriceFetcher( + oracletypes.ProviderMarketMap{}, + cfg, + zap.NewNop(), + ) + + require.True(t, strings.Contains(err.Error(), "config for raydium is invalid")) + }) + + t.Run("market config fails validate basic", func(t *testing.T) { + // valid config + cfg := oracleconfig.APIConfig{ + Enabled: false, + MaxQueries: 2, + Interval: 1 * time.Second, + Timeout: 2 * time.Second, + ReconnectTimeout: 2 * time.Second, + } + market := oracletypes.ProviderMarketMap{ + Name: raydium.Name, + OffChainMap: map[string]mmtypes.Ticker{ + "BTC/USDC": { + CurrencyPair: slinkytypes.NewCurrencyPair("BTC", "USDC"), + }, + }, + } + + _, err := raydium.NewAPIPriceFetcher( + market, + cfg, + zap.NewNop(), + ) + require.True(t, strings.Contains(err.Error(), "market config for raydium is invalid")) + }) + + t.Run("incorrect provider name", func(t *testing.T) { + cfg := oracleconfig.APIConfig{ + Enabled: true, + MaxQueries: 2, + Interval: 1 * time.Second, + Timeout: 2 * time.Second, + ReconnectTimeout: 2 * time.Second, + URL: "https://api.raydium.io", + Name: raydium.Name + "a", + } + market := oracletypes.ProviderMarketMap{ + Name: raydium.Name + "a", + } + + _, err := raydium.NewAPIPriceFetcher( + market, + cfg, + zap.NewNop(), + ) + require.Equal(t, err.Error(), fmt.Sprintf("configured name is incorrect; expected: %s, got: %s", raydium.Name, raydium.Name+"a")) + + cfg = oracleconfig.APIConfig{ + Enabled: true, + MaxQueries: 2, + Interval: 1 * time.Second, + Timeout: 2 * time.Second, + ReconnectTimeout: 2 * time.Second, + URL: "https://api.raydium.io", + Name: raydium.Name, + } + market = oracletypes.ProviderMarketMap{ + Name: raydium.Name + "a", + } + + _, err = raydium.NewAPIPriceFetcher( + market, + cfg, + zap.NewNop(), + ) + require.Equal(t, err.Error(), fmt.Sprintf("market config name is incorrect; expected: %s, got: %s", raydium.Name, raydium.Name+"a")) + }) + + t.Run("api not enabled", func(t *testing.T) { + cfg := oracleconfig.APIConfig{ + Enabled: false, + MaxQueries: 2, + Interval: 1 * time.Second, + Timeout: 2 * time.Second, + ReconnectTimeout: 2 * time.Second, + Name: raydium.Name, + } + market := oracletypes.ProviderMarketMap{ + Name: raydium.Name, + } + + _, err := raydium.NewAPIPriceFetcher( + market, + cfg, + zap.NewNop(), + ) + require.Error(t, err, "config is not enabled") + }) + + t.Run("unmarshalling metadata json for tickers fails", func(t *testing.T) { + cfg := oracleconfig.APIConfig{ + Enabled: true, + MaxQueries: 2, + Interval: 1 * time.Second, + Timeout: 2 * time.Second, + ReconnectTimeout: 2 * time.Second, + Name: raydium.Name, + URL: "https://raydium.io", + } + market := oracletypes.ProviderMarketMap{ + Name: raydium.Name, + TickerConfigs: oracletypes.TickerToProviderConfig{ + mmtypes.Ticker{ + CurrencyPair: slinkytypes.NewCurrencyPair("BTC", "USDC"), + Decimals: 8, + MinProviderCount: 1, + Metadata_JSON: `{ + "base_token_vault": ["base_token_vault_address"] + }`, + }: { + OffChainTicker: "BTC/USDC", + Name: raydium.Name, + }, + }, + OffChainMap: map[string]mmtypes.Ticker{ + "BTC/USDC": { + CurrencyPair: slinkytypes.NewCurrencyPair("BTC", "USDC"), + Decimals: 8, + MinProviderCount: 1, + Metadata_JSON: `{ + "base_token_vault": ["base_token_vault_address"] + }`, + }, + }, + } + + _, err := raydium.NewAPIPriceFetcher( + market, + cfg, + zap.NewNop(), + ) + t.Log(err) + require.True(t, strings.Contains(err.Error(), fmt.Sprintf("error unmarshalling metadata for ticker %s", slinkytypes.NewCurrencyPair("BTC", "USDC")))) + }) + + t.Run("invalid metadata json in config", func(t *testing.T) { + cfg := oracleconfig.APIConfig{ + Enabled: true, + MaxQueries: 2, + Interval: 1 * time.Second, + Timeout: 2 * time.Second, + ReconnectTimeout: 2 * time.Second, + Name: raydium.Name, + URL: "https://raydium.io", + } + + bz, err := json.Marshal(raydium.TickerMetadata{ + BaseTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: "abc", + }, + }) + require.NoError(t, err) + + market := oracletypes.ProviderMarketMap{ + Name: raydium.Name, + TickerConfigs: oracletypes.TickerToProviderConfig{ + mmtypes.Ticker{ + CurrencyPair: slinkytypes.NewCurrencyPair("BTC", "USDC"), + Decimals: 8, + MinProviderCount: 1, + Metadata_JSON: string(bz), + }: { + OffChainTicker: "BTC/USDC", + Name: raydium.Name, + }, + }, + OffChainMap: map[string]mmtypes.Ticker{ + "BTC/USDC": { + CurrencyPair: slinkytypes.NewCurrencyPair("BTC", "USDC"), + Decimals: 8, + MinProviderCount: 1, + Metadata_JSON: string(bz), + }, + }, + } + + _, err = raydium.NewAPIPriceFetcher( + market, + cfg, + zap.NewNop(), + ) + t.Log(err) + require.True(t, strings.Contains(err.Error(), fmt.Sprintf("metadata for ticker %s is invalid", slinkytypes.NewCurrencyPair("BTC", "USDC")))) + }) + + t.Run("correctly unmarshals metadata json for ticker", func(t *testing.T) { + cfg := oracleconfig.APIConfig{ + Enabled: true, + MaxQueries: 2, + Interval: 1 * time.Second, + Timeout: 2 * time.Second, + ReconnectTimeout: 2 * time.Second, + Name: raydium.Name, + Endpoints: []oracleconfig.Endpoint{ + { + URL: "https://raydium.io", + }, + }, + } + market := oracletypes.ProviderMarketMap{ + Name: raydium.Name, + TickerConfigs: oracletypes.TickerToProviderConfig{ + mmtypes.Ticker{ + CurrencyPair: slinkytypes.NewCurrencyPair("BTC", "USDC"), + Decimals: 8, + MinProviderCount: 1, + Metadata_JSON: `{ + "base_token_vault": { + "token_vault_address": "` + USDCVaultAddress + `", + "token_vault_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "` + BTCVaultAddress + `", + "token_vault_decimals": 8 + } + }`, + }: { + OffChainTicker: "BTC/USDC", + Name: raydium.Name, + }, + }, + OffChainMap: map[string]mmtypes.Ticker{ + "BTC/USDC": { + CurrencyPair: slinkytypes.NewCurrencyPair("BTC", "USDC"), + Decimals: 8, + MinProviderCount: 1, + Metadata_JSON: `{ + "base_token_vault": { + "token_vault_address": "` + USDCVaultAddress + `", + "token_vault_decimals": 6 + }, + "quote_token_vault": { + "token_vault_address": "` + BTCVaultAddress + `", + "token_vault_decimals": 8 + } + }`, + }, + }, + } + + _, err := raydium.NewAPIPriceFetcher( + market, + cfg, + zap.NewNop(), + ) + t.Log(err) + require.NoError(t, err) + }) +} + +// Test getting prices. +func TestProviderFetch(t *testing.T) { + btcUSDCMetadata := raydium.TickerMetadata{ + BaseTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: BTCVaultAddress, + TokenDecimals: 8, + }, + QuoteTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: USDCVaultAddress, + TokenDecimals: 6, + }, + } + ethUSDTMetadata := raydium.TickerMetadata{ + BaseTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: ETHVaultAddress, + TokenDecimals: 18, + }, + QuoteTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: USDTVaultAddress, + TokenDecimals: 6, + }, + } + mogSOLMetadata := raydium.TickerMetadata{ + BaseTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: MOGVaultAddress, + TokenDecimals: 18, + }, + QuoteTokenVault: raydium.AMMTokenVaultMetadata{ + TokenVaultAddress: SOLVaultAddress, + TokenDecimals: 9, + }, + } + + tickers := []mmtypes.Ticker{ + { + CurrencyPair: slinkytypes.NewCurrencyPair("BTC", "USDC"), + Decimals: 8, + MinProviderCount: 1, + Metadata_JSON: marshalDataToJSON(btcUSDCMetadata), + }, + { + CurrencyPair: slinkytypes.NewCurrencyPair("ETH", "USDT"), + Decimals: 8, + MinProviderCount: 1, + Metadata_JSON: marshalDataToJSON(ethUSDTMetadata), + }, + { + CurrencyPair: slinkytypes.NewCurrencyPair("MOG", "SOL"), + Decimals: 18, + MinProviderCount: 1, + Metadata_JSON: marshalDataToJSON(mogSOLMetadata), + }, + } + + client := mocks.NewSolanaJSONRPCClient(t) + pf, err := newPriceFetcherFromTickers(tickers, client) + require.NoError(t, err) + + t.Run("accounts resp returns len(tickers) * 2 accounts", func(t *testing.T) { + ctx := context.Background() + btcVaultPk := solana.MustPublicKeyFromBase58(BTCVaultAddress) + usdcVaultPk := solana.MustPublicKeyFromBase58(USDCVaultAddress) + ethVaultPk := solana.MustPublicKeyFromBase58(ETHVaultAddress) + usdtVaultPk := solana.MustPublicKeyFromBase58(USDTVaultAddress) + client.On("GetMultipleAccountsWithOpts", mock.Anything, []solana.PublicKey{ + btcVaultPk, usdcVaultPk, ethVaultPk, usdtVaultPk, + }, &rpc.GetMultipleAccountsOpts{ + Commitment: rpc.CommitmentFinalized, + }).Return( + &rpc.GetMultipleAccountsResult{}, nil, + ).Once() + + resp := pf.Fetch(ctx, tickers[:2]) + // expect a failed response + require.Equal(t, len(resp.Resolved), 0) + require.Equal(t, len(resp.UnResolved), 2) + + for _, result := range resp.UnResolved { + require.True(t, strings.Contains(result.Error(), "expected 4 accounts, got 0")) + } + }) + + t.Run("failing accounts query", func(t *testing.T) { + ctx := context.Background() + err := fmt.Errorf("error") + btcVaultPk := solana.MustPublicKeyFromBase58(BTCVaultAddress) + usdcVaultPk := solana.MustPublicKeyFromBase58(USDCVaultAddress) + ethVaultPk := solana.MustPublicKeyFromBase58(ETHVaultAddress) + usdtVaultPk := solana.MustPublicKeyFromBase58(USDTVaultAddress) + client.On("GetMultipleAccountsWithOpts", mock.Anything, []solana.PublicKey{ + btcVaultPk, usdcVaultPk, ethVaultPk, usdtVaultPk, + }, &rpc.GetMultipleAccountsOpts{ + Commitment: rpc.CommitmentFinalized, + }).Return( + &rpc.GetMultipleAccountsResult{}, err, + ).Once() + + resp := pf.Fetch(ctx, tickers[:2]) + // expect a failed response + require.Equal(t, len(resp.Resolved), 0) + require.Equal(t, len(resp.UnResolved), 2) + + for _, result := range resp.UnResolved { + require.True(t, strings.Contains(result.Error(), raydium.SolanaJSONRPCError(err).Error())) + } + }) + + t.Run("unexpected ticker in query", func(t *testing.T) { + ctx := context.Background() + + resp := pf.Fetch(ctx, []mmtypes.Ticker{ + { + CurrencyPair: slinkytypes.NewCurrencyPair("MOG", "TIA"), + }, + }) + // expect a failed response + require.Equal(t, len(resp.Resolved), 0) + require.Equal(t, len(resp.UnResolved), 1) + + for _, result := range resp.UnResolved { + t.Log(result.Error()) + require.True(t, strings.Contains(result.Error(), raydium.NoRaydiumMetadataForTickerError("MOG/TIA").Error())) + } + }) + + t.Run("nil accounts are handled gracefully (skipped + added to unresolved)", func(t *testing.T) { + ctx := context.Background() + btcVaultPk := solana.MustPublicKeyFromBase58(BTCVaultAddress) + usdcVaultPk := solana.MustPublicKeyFromBase58(USDCVaultAddress) + mogVaultPk := solana.MustPublicKeyFromBase58(MOGVaultAddress) + solVaultPk := solana.MustPublicKeyFromBase58(SOLVaultAddress) + ethVaultPk := solana.MustPublicKeyFromBase58(ETHVaultAddress) + usdtVaultPk := solana.MustPublicKeyFromBase58(USDTVaultAddress) + + ethVaultBz := new(bytes.Buffer) + ethEnc := bin.NewBinEncoder(ethVaultBz) + ethVaultTokenMetadata := token.Account{ + Amount: uint64(1e18), + } + ethVaultTokenMetadata.MarshalWithEncoder(ethEnc) + + usdtVaultBz := new(bytes.Buffer) + usdcEnc := bin.NewBinEncoder(usdtVaultBz) + usdtTokenVaultMetadata := token.Account{ + Amount: 3 * (1e6), + } + usdtTokenVaultMetadata.MarshalWithEncoder(usdcEnc) + + solVaultBz := new(bytes.Buffer) + solEnc := bin.NewBinEncoder(solVaultBz) + solTokenVaultMetadata := token.Account{ + Amount: 1e9, + } + solTokenVaultMetadata.MarshalWithEncoder(solEnc) + + client.On("GetMultipleAccountsWithOpts", mock.Anything, []solana.PublicKey{ + btcVaultPk, usdcVaultPk, ethVaultPk, usdtVaultPk, mogVaultPk, solVaultPk, + }, &rpc.GetMultipleAccountsOpts{ + Commitment: rpc.CommitmentFinalized, + }).Return( + &rpc.GetMultipleAccountsResult{ + Value: []*rpc.Account{ + { + Data: nil, // btc/usdc shld be unresolved + }, + { + Data: nil, + }, + { + Data: rpc.DataBytesOrJSONFromBytes(ethVaultBz.Bytes()), + }, + { + Data: rpc.DataBytesOrJSONFromBytes(usdtVaultBz.Bytes()), + }, + { + Data: rpc.DataBytesOrJSONFromBytes(solVaultBz.Bytes()), + }, + nil, + }, + }, nil, + ) + + resp := pf.Fetch(ctx, tickers[:3]) + + // expect a failed response + require.Equal(t, len(resp.Resolved), 1) + require.Equal(t, len(resp.UnResolved), 2) + + require.True(t, strings.Contains(resp.UnResolved[tickers[0]].Error(), "solana json-rpc error")) + result := resp.Resolved[tickers[1]] + require.Equal(t, result.Value.Uint64(), uint64(3e8)) + }) + + t.Run("incorrectly encoded accounts are handled gracefully", func(t *testing.T) { + ctx := context.Background() + btcVaultPk := solana.MustPublicKeyFromBase58(BTCVaultAddress) + usdcVaultPk := solana.MustPublicKeyFromBase58(USDCVaultAddress) + + client.On("GetMultipleAccountsWithOpts", mock.Anything, []solana.PublicKey{ + btcVaultPk, usdcVaultPk, + }, &rpc.GetMultipleAccountsOpts{ + Commitment: rpc.CommitmentFinalized, + }).Return( + &rpc.GetMultipleAccountsResult{ + Value: []*rpc.Account{ + { + Data: rpc.DataBytesOrJSONFromBytes([]byte{1, 2, 3}), // btc/usdc shld be unresolved + }, + { + Data: nil, + }, + }, + }, nil, + ) + + resp := pf.Fetch(ctx, tickers[:1]) + + // expect a failed response + require.Equal(t, len(resp.Resolved), 0) + require.Equal(t, len(resp.UnResolved), 1) + + require.True(t, strings.Contains(resp.UnResolved[tickers[0]].Error(), "solana json-rpc error")) + }) +} + +func marshalDataToJSON(obj interface{}) string { + data, err := json.Marshal(obj) + if err != nil { + panic(err) + } + return string(data) +} + +func newPriceFetcherFromTickers(tickers []mmtypes.Ticker, client *mocks.SolanaJSONRPCClient) (*raydium.APIPriceFetcher, error) { + cfg := oracleconfig.APIConfig{ + Enabled: true, + MaxQueries: 2, + Interval: 1 * time.Second, + Timeout: 2 * time.Second, + ReconnectTimeout: 2 * time.Second, + Name: raydium.Name, + URL: "https://raydium.io", + } + market := oracletypes.ProviderMarketMap{ + Name: raydium.Name, + TickerConfigs: make(oracletypes.TickerToProviderConfig), + OffChainMap: make(map[string]mmtypes.Ticker), + } + + for _, ticker := range tickers { + market.TickerConfigs[ticker] = mmtypes.ProviderConfig{ + Name: raydium.Name, + OffChainTicker: ticker.String(), + } + market.OffChainMap[ticker.String()] = ticker + } + + return raydium.NewAPIPriceFetcherWithClient( + market, + cfg, + client, + zap.NewExample(), + ) +} diff --git a/providers/apis/defi/raydium/types.go b/providers/apis/defi/raydium/types.go new file mode 100644 index 000000000..def0d2d09 --- /dev/null +++ b/providers/apis/defi/raydium/types.go @@ -0,0 +1,87 @@ +package raydium + +import ( + "encoding/json" + "fmt" + "time" + + "github.com/gagliardetto/solana-go" + + oracleconfig "github.com/skip-mev/slinky/oracle/config" +) + +const ( + // Name is the name of the Raydium API. + Name = "raydium_api" + + // NormalizedTokenAmountExponent. + NormalizedTokenAmountExponent = 18 +) + +// TickerMetadata represents the metadata associated with a ticker's corresponding +// raydium pool. +type TickerMetadata struct { + // BaseTokenVault is the metadata associated with the base token's token vault + BaseTokenVault AMMTokenVaultMetadata `json:"base_token_vault"` + + // QuoteTokenVault is the metadata associated with the quote token's token vault + QuoteTokenVault AMMTokenVaultMetadata `json:"quote_token_vault"` +} + +// ValidateBasic checks that the solana token vault addresses are valid. +func (metadata TickerMetadata) ValidateBasic() error { + if _, err := solana.PublicKeyFromBase58(metadata.BaseTokenVault.TokenVaultAddress); err != nil { + return err + } + + if _, err := solana.PublicKeyFromBase58(metadata.QuoteTokenVault.TokenVaultAddress); err != nil { + return err + } + + return nil +} + +// AMMTokenVaultMetadata represents the metadata associated with a raydium AMM pool's +// token vault. Specifically, we require the token vault address and the token decimals +// for the token that the vault is associated with. +type AMMTokenVaultMetadata struct { + // QuoteTokenAddress is the base58 encoded address of the serum token corresponding + // to this market's quote address + TokenVaultAddress string `json:"token_vault_address"` + + // TokenDecimals is the number of decimals used for the token, we use this for + // normalizing the balance of tokens at the designated vault address + TokenDecimals uint64 `json:"token_decimals"` +} + +// unmarshalMetadataJSON unmarshals the given metadata string into a TickerMetadata, +// this method assumes that the metadata string is valid json, otherwise an error is returned. +func unmarshalMetadataJSON(metadata string) (TickerMetadata, error) { + // unmarshal the metadata string into a TickerMetadata + var tickerMetadata TickerMetadata + if err := json.Unmarshal([]byte(metadata), &tickerMetadata); err != nil { + return TickerMetadata{}, err + } + + return tickerMetadata, nil +} + +// NoRaydiumMetadataForTickerError is returned when there is no metadata associated with a given ticker. +func NoRaydiumMetadataForTickerError(ticker string) error { + return fmt.Errorf("no raydium metadata for ticker: %s", ticker) +} + +// SolanaJSONRPCError is returned when there is an error querying the solana JSON-RPC client. +func SolanaJSONRPCError(err error) error { + return fmt.Errorf("solana json-rpc error: %s", err.Error()) +} + +var DefaultAPIConfig = oracleconfig.APIConfig{ + Enabled: true, + Name: Name, + Timeout: 500 * time.Millisecond, + Interval: 500 * time.Millisecond, + ReconnectTimeout: 2000 * time.Millisecond, + MaxQueries: 10, + Atomic: true, +} diff --git a/providers/apis/defi/uniswapv3/README.md b/providers/apis/defi/uniswapv3/README.md new file mode 100644 index 000000000..7b2db436b --- /dev/null +++ b/providers/apis/defi/uniswapv3/README.md @@ -0,0 +1,17 @@ +# Uniswap v3 API Provider + +> Please read over the [Uniswap v3 documentation](https://blog.uniswap.org/uniswap-v3-math-primer) to understand the basics of Uniswap v3. + +## Overview + +The Uniswap v3 API Provider allows you to interact with the Uniswap v3 pools - otherwise known as concentrated liquidity pools (CLPs) - on the Ethereum blockchain. The provider utilizes JSON-RPC to interact with an ethereum node - batching multiple requests into a single HTTP request to reduce latency and improve performance. + +Uniswap v3 shows the current price of the pool in `slot0` of the pool contract. `slot0` is where most of the commonly accessed values are stored, making it a good starting point for data collection. You can get the price from two places; either from the `sqrtPriceX96` or calculating the price from the pool `tick` value. Using `sqrtPriceX96` should be preferred over calculating the price from the current tick, because the current tick may lose precision due to the integer constraints. As such, this provider uses the `sqrtPriceX96` value to calculate the price of the pool. + +Based on the [analysis](https://docs.chainstack.com/docs/http-batch-request-vs-multicall-contract#performance-comparison) of various approaches for querying EVM state, this implementation utilizes `BatchCallContext` available on any client that implements the go-ethereum's `ethclient` interface. This allows for multiple requests to be batched into a single HTTP request, reducing latency and improving performance. This is preferrable to using the `multicall` contract, which is a contract that aggregates multiple calls into a single call. + +To generate the ABI for the Uniswap v3 pool contract, you can use the `abigen` tool provided by the go-ethereum library. The ABI is used to interact with the Uniswap v3 pool contract. + +```bash +abigen --sol ./contracts/UniswapV3Pool.sol --pkg uniswap --out ./uniswap_v3_pool.go +``` diff --git a/providers/apis/defi/uniswapv3/client.go b/providers/apis/defi/uniswapv3/client.go new file mode 100644 index 000000000..24a834c13 --- /dev/null +++ b/providers/apis/defi/uniswapv3/client.go @@ -0,0 +1,41 @@ +package uniswapv3 + +import ( + "context" + + "github.com/ethereum/go-ethereum/rpc" +) + +// EVMClient is an interface that abstracts the evm client. +// +//go:generate mockery --name EVMClient +type EVMClient interface { + // BatchCallContext is a batch call to an EVM. + BatchCallContext(ctx context.Context, calls []rpc.BatchElem) error +} + +var _ EVMClient = (*GoEthereumClientImpl)(nil) + +// GoEthereumClient is a go-ethereum client implementation using the go-ethereum RPC +// library. +type GoEthereumClientImpl struct { + client *rpc.Client +} + +// NewGoEthereumClientImpl returns a new go-ethereum client. This is the default +// implementation that connects to an ethereum node via rpc. +func NewGoEthereumClientImpl(url string) (EVMClient, error) { + return rpc.Dial(url) +} + +// BatchCallContext sends all given requests as a single batch and waits for the server +// to return a response for all of them. The wait duration is bounded by the context's deadline. +// +// In contrast to CallContext, BatchCallContext only returns errors that have occurred while +// sending the request. Any error specific to a request is reported through the Error field of +// the corresponding BatchElem. +// +// Note that batch calls may not be executed atomically on the server side. +func (c *GoEthereumClientImpl) BatchCallContext(ctx context.Context, calls []rpc.BatchElem) error { + return c.client.BatchCallContext(ctx, calls) +} diff --git a/providers/apis/defi/uniswapv3/fetcher.go b/providers/apis/defi/uniswapv3/fetcher.go new file mode 100644 index 000000000..043a787a7 --- /dev/null +++ b/providers/apis/defi/uniswapv3/fetcher.go @@ -0,0 +1,269 @@ +package uniswapv3 + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "time" + + "go.uber.org/zap" + + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/rpc" + "github.com/skip-mev/slinky/oracle/config" + "github.com/skip-mev/slinky/oracle/types" + uniswappool "github.com/skip-mev/slinky/providers/apis/defi/uniswapv3/pool" + "github.com/skip-mev/slinky/providers/base/api/metrics" + providertypes "github.com/skip-mev/slinky/providers/types" + mmtypes "github.com/skip-mev/slinky/x/marketmap/types" +) + +var _ types.PriceAPIFetcher = (*PriceFetcher)(nil) + +// UniswapV3PriceFetcher is the Uniswap V3 price fetcher. This fetcher is responsible for +// querying Uniswap V3 pool contracts and returning the price of a given ticker. The price is +// derived from the slot 0 data of the pool contract. +// +// To read more about how the price is calculated, see the Uniswap V3 documentation +// https://blog.uniswap.org/uniswap-v3-math-primer. +// +// We utilize the eth client's BatchCallContext to batch the calls to the ethereum network as +// this is more performant than making individual calls or the multi call contract: +// https://docs.chainstack.com/docs/http-batch-request-vs-multicall-contract#performance-comparison. +type PriceFetcher struct { + logger *zap.Logger + metrics metrics.APIMetrics + api config.APIConfig + + // client is the EVM client implementation. This is used to interact with the ethereum network. + client EVMClient + // abi is the uniswap v3 pool abi. This is used to pack the slot0 call to the pool contract + // and parse the result. + abi *abi.ABI + // payload is the packed slot0 call to the pool contract. Since the slot0 payload is the same + // for all pools, we can reuse this payload for all pools. + payload []byte + // poolCache is a cache of the tickers to pool configs. This is used to avoid unmarshalling + // the metadata for each ticker. + poolCache map[mmtypes.Ticker]PoolConfig +} + +// NewPriceFetcher returns a new Uniswap V3 price fetcher. +func NewPriceFetcher( + logger *zap.Logger, + metrics metrics.APIMetrics, + api config.APIConfig, + client EVMClient, +) (*PriceFetcher, error) { + if logger == nil { + return nil, fmt.Errorf("logger cannot be nil") + } + + if metrics == nil { + return nil, fmt.Errorf("metrics cannot be nil") + } + + if api.Name != Name { + return nil, fmt.Errorf("expected api config name %s, got %s", Name, api.Name) + } + + if !api.Enabled { + return nil, fmt.Errorf("api config for %s is not enabled", Name) + } + + if err := api.ValidateBasic(); err != nil { + return nil, fmt.Errorf("invalid api config: %w", err) + } + + abi, err := uniswappool.UniswapMetaData.GetAbi() + if err != nil { + return nil, fmt.Errorf("failed to get uniswap abi: %w", err) + } + + payload, err := abi.Pack(ContractMethod) + if err != nil { + return nil, fmt.Errorf("failed to pack slot0: %w", err) + } + + return &PriceFetcher{ + logger: logger, + metrics: metrics, + api: api, + client: client, + abi: abi, + payload: payload, + poolCache: make(map[mmtypes.Ticker]PoolConfig), + }, nil +} + +// Fetch returns the price of a given set of tickers. This fetch utilizes the batch call to lower +// overhead of making individual RPC calls for each ticker. The fetcher will query the Uniswap V3 +// pool contract for the price of the pool. The price is derived from the slot 0 data of the pool +// contract, specifically the sqrtPriceX96 value. +func (u *PriceFetcher) Fetch( + ctx context.Context, + tickers []mmtypes.Ticker, +) types.PriceResponse { + start := time.Now() + defer func() { + u.metrics.ObserveProviderResponseLatency(Name, time.Since(start)) + }() + + var ( + resolved = make(types.ResolvedPrices) + unResolved = make(types.UnResolvedPrices) + ) + + // Create a batch element for each ticker and pool. + batchElems := make([]rpc.BatchElem, len(tickers)) + pools := make([]PoolConfig, len(tickers)) + for i, ticker := range tickers { + pool, err := u.GetPool(ticker) + if err != nil { + u.logger.Error( + "failed to get pool for ticker", + zap.String("ticker", ticker.String()), + zap.Error(err), + ) + + return types.NewPriceResponseWithErr( + tickers, + providertypes.NewErrorWithCode( + fmt.Errorf("failed to get pool: %w", err), + providertypes.ErrorFailedToDecode, + ), + ) + } + + // Create a batch element for the ticker and pool. + var result string + batchElems[i] = rpc.BatchElem{ + Method: "eth_call", + Args: []interface{}{ + map[string]interface{}{ + "to": common.HexToAddress(pool.Address), + "data": hexutil.Bytes(u.payload), // slot0 call to the pool contract. + }, + "latest", // latest signifies the latest block. + }, + Result: &result, + } + pools[i] = pool + } + + // Batch call to the EVM. + if err := u.client.BatchCallContext(ctx, batchElems); err != nil { + u.logger.Error( + "failed to batch call to ethereum network for all tickers", + zap.Error(err), + ) + + return types.NewPriceResponseWithErr( + tickers, + providertypes.NewErrorWithCode(err, providertypes.ErrorAPIGeneral), + ) + } + + // Parse the result from the batch call for each ticker. + for i, ticker := range tickers { + result := batchElems[i] + if result.Error != nil { + u.logger.Error( + "failed to batch call to ethereum network for ticker", + zap.String("ticker", ticker.String()), + zap.Error(result.Error), + ) + + unResolved[ticker] = providertypes.UnresolvedResult{ + ErrorWithCode: providertypes.NewErrorWithCode( + result.Error, + providertypes.ErrorUnknown, + ), + } + + continue + } + + // Parse the sqrtPriceX96 from the result. + sqrtPriceX96, err := u.ParseSqrtPriceX96(result.Result) + if err != nil { + u.logger.Error( + "failed to parse sqrt price x96", + zap.String("ticker", ticker.String()), + zap.Error(err), + ) + + unResolved[ticker] = providertypes.UnresolvedResult{ + ErrorWithCode: providertypes.NewErrorWithCode( + err, + providertypes.ErrorFailedToParsePrice, + ), + } + + continue + } + + // Convert the sqrtPriceX96 to a price. This is the raw, unscaled price. + price := ConvertSquareRootX96Price(sqrtPriceX96) + + // Scale the price to the respective token decimals. + scaledPrice := ScalePrice(ticker, pools[i], price) + intPrice, _ := scaledPrice.Int(nil) + resolved[ticker] = types.NewPriceResult(intPrice, time.Now()) + } + + // Add the price to the resolved prices. + return types.NewPriceResponse(resolved, unResolved) +} + +// GetPool returns the uniswap pool for the given ticker. This will unmarshal the metadata +// and validate the pool config which contains all required information to query the EVM. +func (u *PriceFetcher) GetPool( + ticker mmtypes.Ticker, +) (PoolConfig, error) { + if pool, ok := u.poolCache[ticker]; ok { + return pool, nil + } + + var cfg PoolConfig + if err := json.Unmarshal([]byte(ticker.Metadata_JSON), &cfg); err != nil { + return cfg, fmt.Errorf("failed to unmarshal pool config on ticker: %w", err) + } + if err := cfg.ValidateBasic(); err != nil { + return cfg, fmt.Errorf("invalid ticker pool config: %w", err) + } + + u.poolCache[ticker] = cfg + return cfg, nil +} + +// ParseSqrtPriceX96 parses the sqrtPriceX96 from the result of the batch call. +func (u *PriceFetcher) ParseSqrtPriceX96( + result interface{}, +) (*big.Int, error) { + r, ok := result.(*string) + if !ok { + return nil, fmt.Errorf("expected result to be a string, got %T", result) + } + + if r == nil { + return nil, fmt.Errorf("result is nil") + } + + bz, err := hexutil.Decode(*r) + if err != nil { + return nil, fmt.Errorf("failed to decode hex result: %w", err) + } + + out, err := u.abi.Methods[ContractMethod].Outputs.UnpackValues(bz) + if err != nil { + return nil, fmt.Errorf("failed to unpack values: %w", err) + } + + // Parse the sqrtPriceX96 from the result. + sqrtPriceX96 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + return sqrtPriceX96, nil +} diff --git a/providers/apis/defi/uniswapv3/fetcher_test.go b/providers/apis/defi/uniswapv3/fetcher_test.go new file mode 100644 index 000000000..a26b77f9e --- /dev/null +++ b/providers/apis/defi/uniswapv3/fetcher_test.go @@ -0,0 +1,256 @@ +package uniswapv3_test + +import ( + "context" + "fmt" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/rpc" + "github.com/skip-mev/slinky/oracle/types" + "github.com/skip-mev/slinky/pkg/math" + "github.com/skip-mev/slinky/providers/apis/defi/uniswapv3" + "github.com/skip-mev/slinky/providers/apis/defi/uniswapv3/mocks" + providertypes "github.com/skip-mev/slinky/providers/types" + mmtypes "github.com/skip-mev/slinky/x/marketmap/types" + "github.com/stretchr/testify/require" +) + +func TestFetch(t *testing.T) { + testCases := []struct { + name string + tickers []mmtypes.Ticker + client func() uniswapv3.EVMClient + expected types.PriceResponse + }{ + { + name: "no tickers", + tickers: []mmtypes.Ticker{}, + client: func() uniswapv3.EVMClient { + c := mocks.NewEVMClient(t) + c.On("BatchCallContext", context.Background(), []rpc.BatchElem{}).Return(nil) + return c + }, + expected: types.PriceResponse{ + Resolved: map[mmtypes.Ticker]providertypes.ResolvedResult[*big.Int]{}, + UnResolved: map[mmtypes.Ticker]providertypes.UnresolvedResult{}, + }, + }, + { + name: "fails to retrieve pool for an empty ticker", + tickers: []mmtypes.Ticker{ + {}, + }, + client: func() uniswapv3.EVMClient { + return mocks.NewEVMClient(t) + }, + expected: types.PriceResponse{ + Resolved: map[mmtypes.Ticker]providertypes.ResolvedResult[*big.Int]{}, + UnResolved: map[mmtypes.Ticker]providertypes.UnresolvedResult{ + {}: {}, + }, + }, + }, + { + name: "fails to make a batch call", + tickers: []mmtypes.Ticker{ + weth_usdc_ticker, + }, + client: func() uniswapv3.EVMClient { + return createEVMClientWithResponse(t, fmt.Errorf("failed to make a batch call"), nil, nil) + }, + expected: types.PriceResponse{ + Resolved: map[mmtypes.Ticker]providertypes.ResolvedResult[*big.Int]{}, + UnResolved: map[mmtypes.Ticker]providertypes.UnresolvedResult{ + weth_usdc_ticker: {}, + }, + }, + }, + { + name: "batch request has an error for a single ticker", + tickers: []mmtypes.Ticker{ + weth_usdc_ticker, + }, + client: func() uniswapv3.EVMClient { + batchErrors := []error{ + fmt.Errorf("request for ticker did not return a result"), + } + responses := []string{ + "", + } + return createEVMClientWithResponse(t, nil, responses, batchErrors) + }, + expected: types.PriceResponse{ + Resolved: map[mmtypes.Ticker]providertypes.ResolvedResult[*big.Int]{}, + UnResolved: map[mmtypes.Ticker]providertypes.UnresolvedResult{ + weth_usdc_ticker: {}, + }, + }, + }, + { + name: "batch request returns a result that cannot be parsed", + tickers: []mmtypes.Ticker{ + weth_usdc_ticker, + }, + client: func() uniswapv3.EVMClient { + batchErrors := []error{ + nil, + } + responses := []string{ + "not a valid result", + } + return createEVMClientWithResponse(t, nil, responses, batchErrors) + }, + expected: types.PriceResponse{ + Resolved: map[mmtypes.Ticker]providertypes.ResolvedResult[*big.Int]{}, + UnResolved: map[mmtypes.Ticker]providertypes.UnresolvedResult{ + weth_usdc_ticker: {}, + }, + }, + }, + { + name: "weth/usdc mainnet result", + tickers: []mmtypes.Ticker{ + weth_usdc_ticker, + }, + client: func() uniswapv3.EVMClient { + batchErrors := []error{ + nil, + } + responses := []string{ + "0x00000000000000000000000000000000000043dd3b966e761000000000000000000000000000000000000000000000000000000000000000000000000002fabf000000000000000000000000000000000000000000000000000000000000057900000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000005a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + } + return createEVMClientWithResponse(t, nil, responses, batchErrors) + }, + expected: types.PriceResponse{ + Resolved: map[mmtypes.Ticker]providertypes.ResolvedResult[*big.Int]{ + weth_usdc_ticker: { + Value: func() *big.Int { + v, ok := new(big.Float).SetString("3.313131879703878971626114658316303e+21") + require.True(t, ok) + i, _ := v.Int(nil) + return i + }(), + }, + }, + UnResolved: map[mmtypes.Ticker]providertypes.UnresolvedResult{}, + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + fetcher := createPriceFetcherWithClient(t, tc.client()) + + response := fetcher.Fetch(context.Background(), tc.tickers) + require.Equal(t, len(tc.expected.Resolved), len(response.Resolved)) + require.Equal(t, len(tc.expected.UnResolved), len(response.UnResolved)) + + for ticker, result := range tc.expected.Resolved { + require.Contains(t, response.Resolved, ticker) + math.VerifyPrice(t, result.Value, response.Resolved[ticker].Value, acceptableDelta) + } + + for ticker := range tc.expected.UnResolved { + require.Contains(t, response.UnResolved, ticker) + } + }) + } +} + +func TestGetPool(t *testing.T) { + fetcher := createPriceFetcher(t) + + t.Run("ticker is empty", func(t *testing.T) { + ticker := mmtypes.Ticker{} + _, err := fetcher.GetPool(ticker) + require.Error(t, err) + }) + + t.Run("ticker does not have valid metadata", func(t *testing.T) { + expected := uniswapv3.PoolConfig{ + Address: "0x1234", + } + ticker := mmtypes.Ticker{ + Metadata_JSON: expected.MustToJSON(), + } + _, err := fetcher.GetPool(ticker) + require.Error(t, err) + }) + + t.Run("ticker is not json formatted", func(t *testing.T) { + ticker := mmtypes.Ticker{ + Metadata_JSON: "not json, just a string", + } + _, err := fetcher.GetPool(ticker) + require.Error(t, err) + }) + + t.Run("ticker has valid metadata", func(t *testing.T) { + expected := uniswapv3.PoolConfig{ + Address: "0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8", // WETH/USDC + BaseDecimals: 18, + QuoteDecimals: 6, + Invert: true, + } + ticker := mmtypes.Ticker{ + Metadata_JSON: expected.MustToJSON(), + } + pool, err := fetcher.GetPool(ticker) + require.NoError(t, err) + require.Equal(t, expected, pool) + }) +} + +func TestParseSqrtPriceX96(t *testing.T) { + fetcher := createPriceFetcher(t) + + t.Run("result does not map to a string pointer", func(t *testing.T) { + _, err := fetcher.ParseSqrtPriceX96(42) + require.Error(t, err) + }) + + t.Run("result is nil", func(t *testing.T) { + _, err := fetcher.ParseSqrtPriceX96(nil) + require.Error(t, err) + }) + + t.Run("result is a nil string pointer", func(t *testing.T) { + _, err := fetcher.ParseSqrtPriceX96((*string)(nil)) + require.Error(t, err) + }) + + t.Run("result is a empty string pointer", func(t *testing.T) { + _, err := fetcher.ParseSqrtPriceX96(new(string)) + require.Error(t, err) + }) + + t.Run("result cannot be unpacked by the uniswap abi", func(t *testing.T) { + result := new(string) + *result = "0x1234" + _, err := fetcher.ParseSqrtPriceX96(result) + require.Error(t, err) + }) + + t.Run("mainnet result for BTC/USDT", func(t *testing.T) { + result := new(string) + *result = "0x000000000000000000000000000000000000001a105ec774c5175b820a157dac000000000000000000000000000000000000000000000000000000000000febe000000000000000000000000000000000000000000000000000000000000000d0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001" + sqrtPriceX96, err := fetcher.ParseSqrtPriceX96(result) + require.NoError(t, err) + + expectedResult, ok := new(big.Int).SetString("2064998566460012397847876304300", 10) + require.True(t, ok) + require.Equal(t, expectedResult, sqrtPriceX96) + }) + + t.Run("mainnet result for MOG/ETH", func(t *testing.T) { + result := new(string) + *result = "0x00000000000000000000000000000000000000000000d4df8e2f67f1e094d4dafffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8f1c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001" + sqrtPriceX96, err := fetcher.ParseSqrtPriceX96(result) + require.NoError(t, err) + + expectedResult, ok := new(big.Int).SetString("1005265563818767859111130", 10) + require.True(t, ok) + require.Equal(t, expectedResult, sqrtPriceX96) + }) +} diff --git a/providers/apis/defi/uniswapv3/helper_test.go b/providers/apis/defi/uniswapv3/helper_test.go new file mode 100644 index 000000000..f00442601 --- /dev/null +++ b/providers/apis/defi/uniswapv3/helper_test.go @@ -0,0 +1,115 @@ +package uniswapv3_test + +import ( + "testing" + + "github.com/ethereum/go-ethereum/rpc" + pkgtypes "github.com/skip-mev/slinky/pkg/types" + "github.com/skip-mev/slinky/providers/apis/defi/uniswapv3" + "github.com/skip-mev/slinky/providers/apis/defi/uniswapv3/mocks" + "github.com/skip-mev/slinky/providers/base/api/metrics" + mmtypes "github.com/skip-mev/slinky/x/marketmap/types" + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + "go.uber.org/zap" +) + +const ( + // precision is the precision used for big.Float calculations. Specifically + // this is used to ensure that float values are the same within a certain + // precision. + precision = 30 + + // acceptableDelta is the acceptable difference between the expected and actual price. + // In this case, we use a delta of 1e-8. This means we will accept any price that is + // within 1e-8 of the expected price. + acceptableDelta = 1e-8 +) + +var ( + logger, _ = zap.NewDevelopment() + m = metrics.NewNopAPIMetrics() + + // PoolConfigs used for testing. + weth_usdc_cfg = uniswapv3.PoolConfig{ //nolint + Address: "0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8", + BaseDecimals: 18, + QuoteDecimals: 6, + Invert: true, + } + + // Tickers used for testing. + weth_usdc_ticker = mmtypes.Ticker{ //nolint + CurrencyPair: pkgtypes.CurrencyPair{ + Base: "WETH", + Quote: "USDC", + }, + Decimals: 18, + Metadata_JSON: weth_usdc_cfg.MustToJSON(), + } +) + +func createPriceFetcher( + t *testing.T, +) *uniswapv3.PriceFetcher { + t.Helper() + + client := mocks.NewEVMClient(t) + fetcher, err := uniswapv3.NewPriceFetcher( + logger, + m, + uniswapv3.DefaultAPIConfig, + client, + ) + require.NoError(t, err) + + return fetcher +} + +func createPriceFetcherWithClient( + t *testing.T, + client uniswapv3.EVMClient, +) *uniswapv3.PriceFetcher { + t.Helper() + + fetcher, err := uniswapv3.NewPriceFetcher( + logger, + m, + uniswapv3.DefaultAPIConfig, + client, + ) + require.NoError(t, err) + + return fetcher +} + +func createEVMClientWithResponse( + t *testing.T, + failedRequestErr error, + responses []string, + errs []error, +) uniswapv3.EVMClient { + t.Helper() + + c := mocks.NewEVMClient(t) + if failedRequestErr != nil { + c.On("BatchCallContext", mock.Anything, mock.Anything).Return(failedRequestErr) + } else { + c.On("BatchCallContext", mock.Anything, mock.Anything).Return(nil).Run(func(args mock.Arguments) { + elems, ok := args.Get(1).([]rpc.BatchElem) + require.True(t, ok) + + require.True(t, ok) + require.Equal(t, len(elems), len(responses)) + require.Equal(t, len(elems), len(errs)) + + for i, elem := range elems { + elem.Result = &responses[i] + elem.Error = errs[i] + elems[i] = elem + } + }) + } + + return c +} diff --git a/providers/apis/defi/uniswapv3/math.go b/providers/apis/defi/uniswapv3/math.go new file mode 100644 index 000000000..1e046798c --- /dev/null +++ b/providers/apis/defi/uniswapv3/math.go @@ -0,0 +1,76 @@ +package uniswapv3 + +import ( + "math/big" + + "github.com/skip-mev/slinky/pkg/math" + "github.com/skip-mev/slinky/pkg/math/oracle" + mmtypes "github.com/skip-mev/slinky/x/marketmap/types" +) + +// ConvertSquareRootX96Price converts the slot 0 sqrtPriceX96 value to a price. Note that this +// price is not scaled to the token decimals. This calculation is equivalent to: +// +// price = (sqrtPriceX96 / 2^96) ^ 2. +func ConvertSquareRootX96Price( + sqrtPriceX96 *big.Int, +) *big.Float { + // Convert the original sqrtPriceX96 to a big float to retain precision when dividing. + sqrtPriceX96Float := new(big.Float).SetInt(sqrtPriceX96) + + // x96Float is the fixed-point precision for Uniswap V3 prices. This is equal to 2^96. + x96Float := new(big.Float).SetInt( + new(big.Int).Exp(big.NewInt(2), big.NewInt(96), nil), + ) + + // Divide the sqrtPriceX96 by the fixed-point precision. + sqrtPriceFloat := new(big.Float).Quo(sqrtPriceX96Float, x96Float) + + // Square the price to get the final result. + return new(big.Float).Mul(sqrtPriceFloat, sqrtPriceFloat) +} + +// ScalePrice scales the price to the desired ticker decimals. The price is first normalized to +// the token decimals in the erc20 token contracts. The price is then scaled to the desired +// ticker decimals. The price is inverted if the configuration specifies to do so. +func ScalePrice( + ticker mmtypes.Ticker, + cfg PoolConfig, + price *big.Float, +) *big.Float { + // Adjust the price based on the difference between the token decimals in the erc20 token contracts. + erc20ScalingFactor := GetScalingFactor( + cfg.BaseDecimals, + cfg.QuoteDecimals, + ) + + // Invert the price if the configuration specifies to do so. + var scaledERC20AdjustedPrice *big.Float + if cfg.Invert { + scaledERC20AdjustedPrice = new(big.Float).Quo(price, erc20ScalingFactor) + scaledERC20AdjustedPrice = new(big.Float).Quo(big.NewFloat(1), scaledERC20AdjustedPrice) + } else { + scaledERC20AdjustedPrice = new(big.Float).Mul(price, erc20ScalingFactor) + } + + one := new(big.Float).SetInt(oracle.ScaledOne(ticker.Decimals)) + return new(big.Float).Mul(scaledERC20AdjustedPrice, one) +} + +// GetScalingFactor returns the scaling factor for the price based on the difference between +// the token decimals in the erc20 token contracts. Please read over the Uniswap V3 math primer +// for more information on how this is utilized. +func GetScalingFactor( + first, second int64, +) *big.Float { + // Determine the scaling factor for the price. + decimalDiff := first - second + exp := new(big.Float).SetInt( + new(big.Int).Exp(big.NewInt(10), big.NewInt(math.Abs(decimalDiff)), nil), + ) + + if decimalDiff > 0 { + return exp + } + return new(big.Float).Quo(big.NewFloat(1), exp) +} diff --git a/providers/apis/defi/uniswapv3/math_test.go b/providers/apis/defi/uniswapv3/math_test.go new file mode 100644 index 000000000..6ea33e24e --- /dev/null +++ b/providers/apis/defi/uniswapv3/math_test.go @@ -0,0 +1,217 @@ +package uniswapv3_test + +import ( + "math/big" + "testing" + + "github.com/skip-mev/slinky/providers/apis/defi/uniswapv3" + mmtypes "github.com/skip-mev/slinky/x/marketmap/types" + "github.com/stretchr/testify/require" +) + +func TestConvertSquareRootX96Price(t *testing.T) { + t.Run("weth/usdc uniswap primer example", func(t *testing.T) { + val, converted := big.NewInt(1).SetString("2018382873588440326581633304624437", 10) + require.True(t, converted) + + expected := big.NewFloat(649004842.7013700766389061032587755).SetPrec(precision) + actual := uniswapv3.ConvertSquareRootX96Price(val).SetPrec(precision) + require.Equal(t, expected, actual) + }) + + t.Run("works with a value of 0", func(t *testing.T) { + val := big.NewInt(0) + expected := big.NewFloat(0).SetPrec(precision) + actual := uniswapv3.ConvertSquareRootX96Price(val).SetPrec(precision) + require.Equal(t, expected, actual) + }) + + t.Run("should be 1 when the value is 2^96", func(t *testing.T) { + val := new(big.Int).Exp(big.NewInt(2), big.NewInt(96), nil) + expected := big.NewFloat(1).SetPrec(precision) + actual := uniswapv3.ConvertSquareRootX96Price(val).SetPrec(precision) + require.Equal(t, expected, actual) + }) +} + +func TestScalePrice(t *testing.T) { + testCases := []struct { + name string + price *big.Float + cfg uniswapv3.PoolConfig + ticker mmtypes.Ticker + expected *big.Float + }{ + { + name: "uniswap primer example for weth/usdc", + price: big.NewFloat(649004842.70137), + cfg: uniswapv3.PoolConfig{ + BaseDecimals: 18, + QuoteDecimals: 6, + Invert: true, + }, + ticker: mmtypes.Ticker{ + Decimals: 18, + }, + expected: big.NewFloat(1540.82 * 1e18), + }, + { + name: "uniswap primer example for eth/usdc but with lower precision", + price: big.NewFloat(649004842.70137), + cfg: uniswapv3.PoolConfig{ + BaseDecimals: 18, + QuoteDecimals: 6, + Invert: true, + }, + ticker: mmtypes.Ticker{ + Decimals: 6, + }, + expected: big.NewFloat(1540.82 * 1e6), + }, + { + name: "mainnet example for weth/usdc", + price: big.NewFloat(2.913786192888320737692333570997812e+08), + cfg: uniswapv3.PoolConfig{ + BaseDecimals: 18, + QuoteDecimals: 6, + Invert: true, + }, + ticker: mmtypes.Ticker{ + Decimals: 18, + }, + expected: big.NewFloat(3431.960802205393266704 * 1e18), + }, + { + name: "mainnet example for weth/usdc but with lower precision", + price: big.NewFloat(2.913786192888320737692333570997812e+08), + cfg: uniswapv3.PoolConfig{ + BaseDecimals: 18, + QuoteDecimals: 6, + Invert: true, + }, + ticker: mmtypes.Ticker{ + Decimals: 6, + }, + expected: big.NewFloat(3431.96 * 1e6), + }, + { + name: "mainnet example for eth/usdc", + price: big.NewFloat(2.926645918358364572159014271666027e+08), + cfg: uniswapv3.PoolConfig{ + BaseDecimals: 18, + QuoteDecimals: 6, + Invert: true, + }, + ticker: mmtypes.Ticker{ + Decimals: 18, + }, + expected: big.NewFloat(3416.880715658719806983 * 1e18), + }, + { + name: "mainnet example for mog/eth", + price: big.NewFloat(1.63833946559934409985296037965e-10), + cfg: uniswapv3.PoolConfig{ + BaseDecimals: 18, + QuoteDecimals: 18, + Invert: false, + }, + ticker: mmtypes.Ticker{ + Decimals: 18, + }, + expected: big.NewFloat(163833946), + }, + { + name: "mainnet example for mog/eth but with lower precision", + price: big.NewFloat(1.63833946559934409985296037965e-10), + cfg: uniswapv3.PoolConfig{ + BaseDecimals: 18, + QuoteDecimals: 18, + Invert: false, + }, + ticker: mmtypes.Ticker{ + Decimals: 12, + }, + expected: big.NewFloat(163.833946), + }, + { + name: "mainnet example for btc/usdt", + price: big.NewFloat(688.8936521667327881055693350566), + cfg: uniswapv3.PoolConfig{ + BaseDecimals: 8, + QuoteDecimals: 6, + Invert: false, + }, + ticker: mmtypes.Ticker{ + Decimals: 5, + }, + expected: big.NewFloat(68889.36521667327881055693350566 * 1e5), + }, + { + name: "mainnet example for btc/usdt where usdt now assumes 10", + price: big.NewFloat(6888936.521667327881055693350566), + cfg: uniswapv3.PoolConfig{ + BaseDecimals: 8, + QuoteDecimals: 10, + Invert: false, + }, + ticker: mmtypes.Ticker{ + Decimals: 5, + }, + expected: big.NewFloat(68889.36521667327881055693350566 * 1e5), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + actual := uniswapv3.ScalePrice(tc.ticker, tc.cfg, tc.price).SetPrec(5) + require.Equal(t, tc.expected.SetPrec(5), actual) + }) + } +} + +func TestGetScalingFactor(t *testing.T) { + t.Run("base and quote decimals for erc20 tokens are the same", func(t *testing.T) { + cfg := uniswapv3.PoolConfig{ + BaseDecimals: 18, + QuoteDecimals: 18, + } + + actual := uniswapv3.GetScalingFactor( + cfg.BaseDecimals, + cfg.QuoteDecimals, + ).SetPrec(precision) + + expected := big.NewFloat(1).SetPrec(precision) + require.Equal(t, expected, actual) + }) + + t.Run("base decimals are greater than quote decimals for erc20 tokens", func(t *testing.T) { + cfg := uniswapv3.PoolConfig{ + BaseDecimals: 18, + QuoteDecimals: 6, + } + + actual := uniswapv3.GetScalingFactor( + cfg.BaseDecimals, + cfg.QuoteDecimals, + ).SetPrec(precision) + + expected := big.NewFloat(1e12).SetPrec(precision) + require.Equal(t, expected, actual) + }) + + t.Run("quote decimals are greater than base decimals for erc20 tokens", func(t *testing.T) { + cfg := uniswapv3.PoolConfig{ + BaseDecimals: 6, + QuoteDecimals: 18, + } + + actual := uniswapv3.GetScalingFactor( + cfg.BaseDecimals, + cfg.QuoteDecimals, + ).SetPrec(precision) + + expected := big.NewFloat(1e-12).SetPrec(precision) + require.Equal(t, expected, actual) + }) +} diff --git a/providers/apis/defi/uniswapv3/mocks/EVMClient.go b/providers/apis/defi/uniswapv3/mocks/EVMClient.go new file mode 100644 index 000000000..b91db5fe9 --- /dev/null +++ b/providers/apis/defi/uniswapv3/mocks/EVMClient.go @@ -0,0 +1,43 @@ +// Code generated by mockery v2.30.1. DO NOT EDIT. + +package mocks + +import ( + context "context" + + rpc "github.com/ethereum/go-ethereum/rpc" + mock "github.com/stretchr/testify/mock" +) + +// EVMClient is an autogenerated mock type for the EVMClient type +type EVMClient struct { + mock.Mock +} + +// BatchCallContext provides a mock function with given fields: ctx, calls +func (_m *EVMClient) BatchCallContext(ctx context.Context, calls []rpc.BatchElem) error { + ret := _m.Called(ctx, calls) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []rpc.BatchElem) error); ok { + r0 = rf(ctx, calls) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// NewEVMClient creates a new instance of EVMClient. 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 NewEVMClient(t interface { + mock.TestingT + Cleanup(func()) +}) *EVMClient { + mock := &EVMClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/providers/apis/defi/uniswapv3/pool/uniswap_v3_pool.go b/providers/apis/defi/uniswapv3/pool/uniswap_v3_pool.go new file mode 100644 index 000000000..7ff5814a5 --- /dev/null +++ b/providers/apis/defi/uniswapv3/pool/uniswap_v3_pool.go @@ -0,0 +1,2455 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package pool + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// UniswapMetaData contains all meta data concerning the Uniswap contract. +var UniswapMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"int24\",\"name\":\"tickLower\",\"type\":\"int24\"},{\"indexed\":true,\"internalType\":\"int24\",\"name\":\"tickUpper\",\"type\":\"int24\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"name\":\"Burn\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"int24\",\"name\":\"tickLower\",\"type\":\"int24\"},{\"indexed\":true,\"internalType\":\"int24\",\"name\":\"tickUpper\",\"type\":\"int24\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"amount0\",\"type\":\"uint128\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"amount1\",\"type\":\"uint128\"}],\"name\":\"Collect\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"amount0\",\"type\":\"uint128\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"amount1\",\"type\":\"uint128\"}],\"name\":\"CollectProtocol\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"paid0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"paid1\",\"type\":\"uint256\"}],\"name\":\"Flash\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"observationCardinalityNextOld\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"observationCardinalityNextNew\",\"type\":\"uint16\"}],\"name\":\"IncreaseObservationCardinalityNext\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint160\",\"name\":\"sqrtPriceX96\",\"type\":\"uint160\"},{\"indexed\":false,\"internalType\":\"int24\",\"name\":\"tick\",\"type\":\"int24\"}],\"name\":\"Initialize\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"int24\",\"name\":\"tickLower\",\"type\":\"int24\"},{\"indexed\":true,\"internalType\":\"int24\",\"name\":\"tickUpper\",\"type\":\"int24\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"name\":\"Mint\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"feeProtocol0Old\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"feeProtocol1Old\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"feeProtocol0New\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"feeProtocol1New\",\"type\":\"uint8\"}],\"name\":\"SetFeeProtocol\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"amount0\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"amount1\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint160\",\"name\":\"sqrtPriceX96\",\"type\":\"uint160\"},{\"indexed\":false,\"internalType\":\"uint128\",\"name\":\"liquidity\",\"type\":\"uint128\"},{\"indexed\":false,\"internalType\":\"int24\",\"name\":\"tick\",\"type\":\"int24\"}],\"name\":\"Swap\",\"type\":\"event\"},{\"inputs\":[{\"internalType\":\"int24\",\"name\":\"tickLower\",\"type\":\"int24\"},{\"internalType\":\"int24\",\"name\":\"tickUpper\",\"type\":\"int24\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"}],\"name\":\"burn\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"int24\",\"name\":\"tickLower\",\"type\":\"int24\"},{\"internalType\":\"int24\",\"name\":\"tickUpper\",\"type\":\"int24\"},{\"internalType\":\"uint128\",\"name\":\"amount0Requested\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"amount1Requested\",\"type\":\"uint128\"}],\"name\":\"collect\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"amount0\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"amount1\",\"type\":\"uint128\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint128\",\"name\":\"amount0Requested\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"amount1Requested\",\"type\":\"uint128\"}],\"name\":\"collectProtocol\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"amount0\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"amount1\",\"type\":\"uint128\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"factory\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"fee\",\"outputs\":[{\"internalType\":\"uint24\",\"name\":\"\",\"type\":\"uint24\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeGrowthGlobal0X128\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"feeGrowthGlobal1X128\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"flash\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"observationCardinalityNext\",\"type\":\"uint16\"}],\"name\":\"increaseObservationCardinalityNext\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint160\",\"name\":\"sqrtPriceX96\",\"type\":\"uint160\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"liquidity\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"maxLiquidityPerTick\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"int24\",\"name\":\"tickLower\",\"type\":\"int24\"},{\"internalType\":\"int24\",\"name\":\"tickUpper\",\"type\":\"int24\"},{\"internalType\":\"uint128\",\"name\":\"amount\",\"type\":\"uint128\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"mint\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"amount0\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"amount1\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"observations\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"blockTimestamp\",\"type\":\"uint32\"},{\"internalType\":\"int56\",\"name\":\"tickCumulative\",\"type\":\"int56\"},{\"internalType\":\"uint160\",\"name\":\"secondsPerLiquidityCumulativeX128\",\"type\":\"uint160\"},{\"internalType\":\"bool\",\"name\":\"initialized\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32[]\",\"name\":\"secondsAgos\",\"type\":\"uint32[]\"}],\"name\":\"observe\",\"outputs\":[{\"internalType\":\"int56[]\",\"name\":\"tickCumulatives\",\"type\":\"int56[]\"},{\"internalType\":\"uint160[]\",\"name\":\"secondsPerLiquidityCumulativeX128s\",\"type\":\"uint160[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"positions\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"liquidity\",\"type\":\"uint128\"},{\"internalType\":\"uint256\",\"name\":\"feeGrowthInside0LastX128\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeGrowthInside1LastX128\",\"type\":\"uint256\"},{\"internalType\":\"uint128\",\"name\":\"tokensOwed0\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"tokensOwed1\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"protocolFees\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"token0\",\"type\":\"uint128\"},{\"internalType\":\"uint128\",\"name\":\"token1\",\"type\":\"uint128\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"feeProtocol0\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"feeProtocol1\",\"type\":\"uint8\"}],\"name\":\"setFeeProtocol\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"slot0\",\"outputs\":[{\"internalType\":\"uint160\",\"name\":\"sqrtPriceX96\",\"type\":\"uint160\"},{\"internalType\":\"int24\",\"name\":\"tick\",\"type\":\"int24\"},{\"internalType\":\"uint16\",\"name\":\"observationIndex\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"observationCardinality\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"observationCardinalityNext\",\"type\":\"uint16\"},{\"internalType\":\"uint8\",\"name\":\"feeProtocol\",\"type\":\"uint8\"},{\"internalType\":\"bool\",\"name\":\"unlocked\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int24\",\"name\":\"tickLower\",\"type\":\"int24\"},{\"internalType\":\"int24\",\"name\":\"tickUpper\",\"type\":\"int24\"}],\"name\":\"snapshotCumulativesInside\",\"outputs\":[{\"internalType\":\"int56\",\"name\":\"tickCumulativeInside\",\"type\":\"int56\"},{\"internalType\":\"uint160\",\"name\":\"secondsPerLiquidityInsideX128\",\"type\":\"uint160\"},{\"internalType\":\"uint32\",\"name\":\"secondsInside\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"},{\"internalType\":\"bool\",\"name\":\"zeroForOne\",\"type\":\"bool\"},{\"internalType\":\"int256\",\"name\":\"amountSpecified\",\"type\":\"int256\"},{\"internalType\":\"uint160\",\"name\":\"sqrtPriceLimitX96\",\"type\":\"uint160\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"swap\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"amount0\",\"type\":\"int256\"},{\"internalType\":\"int256\",\"name\":\"amount1\",\"type\":\"int256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int16\",\"name\":\"\",\"type\":\"int16\"}],\"name\":\"tickBitmap\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"tickSpacing\",\"outputs\":[{\"internalType\":\"int24\",\"name\":\"\",\"type\":\"int24\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"int24\",\"name\":\"\",\"type\":\"int24\"}],\"name\":\"ticks\",\"outputs\":[{\"internalType\":\"uint128\",\"name\":\"liquidityGross\",\"type\":\"uint128\"},{\"internalType\":\"int128\",\"name\":\"liquidityNet\",\"type\":\"int128\"},{\"internalType\":\"uint256\",\"name\":\"feeGrowthOutside0X128\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"feeGrowthOutside1X128\",\"type\":\"uint256\"},{\"internalType\":\"int56\",\"name\":\"tickCumulativeOutside\",\"type\":\"int56\"},{\"internalType\":\"uint160\",\"name\":\"secondsPerLiquidityOutsideX128\",\"type\":\"uint160\"},{\"internalType\":\"uint32\",\"name\":\"secondsOutside\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"initialized\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token0\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"token1\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", +} + +// UniswapABI is the input ABI used to generate the binding from. +// Deprecated: Use UniswapMetaData.ABI instead. +var UniswapABI = UniswapMetaData.ABI + +// Uniswap is an auto generated Go binding around an Ethereum contract. +type Uniswap struct { + UniswapCaller // Read-only binding to the contract + UniswapTransactor // Write-only binding to the contract + UniswapFilterer // Log filterer for contract events +} + +// UniswapCaller is an auto generated read-only Go binding around an Ethereum contract. +type UniswapCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UniswapTransactor is an auto generated write-only Go binding around an Ethereum contract. +type UniswapTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UniswapFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type UniswapFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// UniswapSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type UniswapSession struct { + Contract *Uniswap // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// UniswapCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type UniswapCallerSession struct { + Contract *UniswapCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// UniswapTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type UniswapTransactorSession struct { + Contract *UniswapTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// UniswapRaw is an auto generated low-level Go binding around an Ethereum contract. +type UniswapRaw struct { + Contract *Uniswap // Generic contract binding to access the raw methods on +} + +// UniswapCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type UniswapCallerRaw struct { + Contract *UniswapCaller // Generic read-only contract binding to access the raw methods on +} + +// UniswapTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type UniswapTransactorRaw struct { + Contract *UniswapTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewUniswap creates a new instance of Uniswap, bound to a specific deployed contract. +func NewUniswap(address common.Address, backend bind.ContractBackend) (*Uniswap, error) { + contract, err := bindUniswap(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Uniswap{UniswapCaller: UniswapCaller{contract: contract}, UniswapTransactor: UniswapTransactor{contract: contract}, UniswapFilterer: UniswapFilterer{contract: contract}}, nil +} + +// NewUniswapCaller creates a new read-only instance of Uniswap, bound to a specific deployed contract. +func NewUniswapCaller(address common.Address, caller bind.ContractCaller) (*UniswapCaller, error) { + contract, err := bindUniswap(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &UniswapCaller{contract: contract}, nil +} + +// NewUniswapTransactor creates a new write-only instance of Uniswap, bound to a specific deployed contract. +func NewUniswapTransactor(address common.Address, transactor bind.ContractTransactor) (*UniswapTransactor, error) { + contract, err := bindUniswap(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &UniswapTransactor{contract: contract}, nil +} + +// NewUniswapFilterer creates a new log filterer instance of Uniswap, bound to a specific deployed contract. +func NewUniswapFilterer(address common.Address, filterer bind.ContractFilterer) (*UniswapFilterer, error) { + contract, err := bindUniswap(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &UniswapFilterer{contract: contract}, nil +} + +// bindUniswap binds a generic wrapper to an already deployed contract. +func bindUniswap(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := UniswapMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Uniswap *UniswapRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Uniswap.Contract.UniswapCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Uniswap *UniswapRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Uniswap.Contract.UniswapTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Uniswap *UniswapRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Uniswap.Contract.UniswapTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Uniswap *UniswapCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Uniswap.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Uniswap *UniswapTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Uniswap.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Uniswap *UniswapTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Uniswap.Contract.contract.Transact(opts, method, params...) +} + +// Factory is a free data retrieval call binding the contract method 0xc45a0155. +// +// Solidity: function factory() view returns(address) +func (_Uniswap *UniswapCaller) Factory(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "factory") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Factory is a free data retrieval call binding the contract method 0xc45a0155. +// +// Solidity: function factory() view returns(address) +func (_Uniswap *UniswapSession) Factory() (common.Address, error) { + return _Uniswap.Contract.Factory(&_Uniswap.CallOpts) +} + +// Factory is a free data retrieval call binding the contract method 0xc45a0155. +// +// Solidity: function factory() view returns(address) +func (_Uniswap *UniswapCallerSession) Factory() (common.Address, error) { + return _Uniswap.Contract.Factory(&_Uniswap.CallOpts) +} + +// Fee is a free data retrieval call binding the contract method 0xddca3f43. +// +// Solidity: function fee() view returns(uint24) +func (_Uniswap *UniswapCaller) Fee(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "fee") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Fee is a free data retrieval call binding the contract method 0xddca3f43. +// +// Solidity: function fee() view returns(uint24) +func (_Uniswap *UniswapSession) Fee() (*big.Int, error) { + return _Uniswap.Contract.Fee(&_Uniswap.CallOpts) +} + +// Fee is a free data retrieval call binding the contract method 0xddca3f43. +// +// Solidity: function fee() view returns(uint24) +func (_Uniswap *UniswapCallerSession) Fee() (*big.Int, error) { + return _Uniswap.Contract.Fee(&_Uniswap.CallOpts) +} + +// FeeGrowthGlobal0X128 is a free data retrieval call binding the contract method 0xf3058399. +// +// Solidity: function feeGrowthGlobal0X128() view returns(uint256) +func (_Uniswap *UniswapCaller) FeeGrowthGlobal0X128(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "feeGrowthGlobal0X128") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// FeeGrowthGlobal0X128 is a free data retrieval call binding the contract method 0xf3058399. +// +// Solidity: function feeGrowthGlobal0X128() view returns(uint256) +func (_Uniswap *UniswapSession) FeeGrowthGlobal0X128() (*big.Int, error) { + return _Uniswap.Contract.FeeGrowthGlobal0X128(&_Uniswap.CallOpts) +} + +// FeeGrowthGlobal0X128 is a free data retrieval call binding the contract method 0xf3058399. +// +// Solidity: function feeGrowthGlobal0X128() view returns(uint256) +func (_Uniswap *UniswapCallerSession) FeeGrowthGlobal0X128() (*big.Int, error) { + return _Uniswap.Contract.FeeGrowthGlobal0X128(&_Uniswap.CallOpts) +} + +// FeeGrowthGlobal1X128 is a free data retrieval call binding the contract method 0x46141319. +// +// Solidity: function feeGrowthGlobal1X128() view returns(uint256) +func (_Uniswap *UniswapCaller) FeeGrowthGlobal1X128(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "feeGrowthGlobal1X128") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// FeeGrowthGlobal1X128 is a free data retrieval call binding the contract method 0x46141319. +// +// Solidity: function feeGrowthGlobal1X128() view returns(uint256) +func (_Uniswap *UniswapSession) FeeGrowthGlobal1X128() (*big.Int, error) { + return _Uniswap.Contract.FeeGrowthGlobal1X128(&_Uniswap.CallOpts) +} + +// FeeGrowthGlobal1X128 is a free data retrieval call binding the contract method 0x46141319. +// +// Solidity: function feeGrowthGlobal1X128() view returns(uint256) +func (_Uniswap *UniswapCallerSession) FeeGrowthGlobal1X128() (*big.Int, error) { + return _Uniswap.Contract.FeeGrowthGlobal1X128(&_Uniswap.CallOpts) +} + +// Liquidity is a free data retrieval call binding the contract method 0x1a686502. +// +// Solidity: function liquidity() view returns(uint128) +func (_Uniswap *UniswapCaller) Liquidity(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "liquidity") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// Liquidity is a free data retrieval call binding the contract method 0x1a686502. +// +// Solidity: function liquidity() view returns(uint128) +func (_Uniswap *UniswapSession) Liquidity() (*big.Int, error) { + return _Uniswap.Contract.Liquidity(&_Uniswap.CallOpts) +} + +// Liquidity is a free data retrieval call binding the contract method 0x1a686502. +// +// Solidity: function liquidity() view returns(uint128) +func (_Uniswap *UniswapCallerSession) Liquidity() (*big.Int, error) { + return _Uniswap.Contract.Liquidity(&_Uniswap.CallOpts) +} + +// MaxLiquidityPerTick is a free data retrieval call binding the contract method 0x70cf754a. +// +// Solidity: function maxLiquidityPerTick() view returns(uint128) +func (_Uniswap *UniswapCaller) MaxLiquidityPerTick(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "maxLiquidityPerTick") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// MaxLiquidityPerTick is a free data retrieval call binding the contract method 0x70cf754a. +// +// Solidity: function maxLiquidityPerTick() view returns(uint128) +func (_Uniswap *UniswapSession) MaxLiquidityPerTick() (*big.Int, error) { + return _Uniswap.Contract.MaxLiquidityPerTick(&_Uniswap.CallOpts) +} + +// MaxLiquidityPerTick is a free data retrieval call binding the contract method 0x70cf754a. +// +// Solidity: function maxLiquidityPerTick() view returns(uint128) +func (_Uniswap *UniswapCallerSession) MaxLiquidityPerTick() (*big.Int, error) { + return _Uniswap.Contract.MaxLiquidityPerTick(&_Uniswap.CallOpts) +} + +// Observations is a free data retrieval call binding the contract method 0x252c09d7. +// +// Solidity: function observations(uint256 ) view returns(uint32 blockTimestamp, int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128, bool initialized) +func (_Uniswap *UniswapCaller) Observations(opts *bind.CallOpts, arg0 *big.Int) (struct { + BlockTimestamp uint32 + TickCumulative *big.Int + SecondsPerLiquidityCumulativeX128 *big.Int + Initialized bool +}, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "observations", arg0) + + outstruct := new(struct { + BlockTimestamp uint32 + TickCumulative *big.Int + SecondsPerLiquidityCumulativeX128 *big.Int + Initialized bool + }) + if err != nil { + return *outstruct, err + } + + outstruct.BlockTimestamp = *abi.ConvertType(out[0], new(uint32)).(*uint32) + outstruct.TickCumulative = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.SecondsPerLiquidityCumulativeX128 = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.Initialized = *abi.ConvertType(out[3], new(bool)).(*bool) + + return *outstruct, err + +} + +// Observations is a free data retrieval call binding the contract method 0x252c09d7. +// +// Solidity: function observations(uint256 ) view returns(uint32 blockTimestamp, int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128, bool initialized) +func (_Uniswap *UniswapSession) Observations(arg0 *big.Int) (struct { + BlockTimestamp uint32 + TickCumulative *big.Int + SecondsPerLiquidityCumulativeX128 *big.Int + Initialized bool +}, error) { + return _Uniswap.Contract.Observations(&_Uniswap.CallOpts, arg0) +} + +// Observations is a free data retrieval call binding the contract method 0x252c09d7. +// +// Solidity: function observations(uint256 ) view returns(uint32 blockTimestamp, int56 tickCumulative, uint160 secondsPerLiquidityCumulativeX128, bool initialized) +func (_Uniswap *UniswapCallerSession) Observations(arg0 *big.Int) (struct { + BlockTimestamp uint32 + TickCumulative *big.Int + SecondsPerLiquidityCumulativeX128 *big.Int + Initialized bool +}, error) { + return _Uniswap.Contract.Observations(&_Uniswap.CallOpts, arg0) +} + +// Observe is a free data retrieval call binding the contract method 0x883bdbfd. +// +// Solidity: function observe(uint32[] secondsAgos) view returns(int56[] tickCumulatives, uint160[] secondsPerLiquidityCumulativeX128s) +func (_Uniswap *UniswapCaller) Observe(opts *bind.CallOpts, secondsAgos []uint32) (struct { + TickCumulatives []*big.Int + SecondsPerLiquidityCumulativeX128s []*big.Int +}, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "observe", secondsAgos) + + outstruct := new(struct { + TickCumulatives []*big.Int + SecondsPerLiquidityCumulativeX128s []*big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.TickCumulatives = *abi.ConvertType(out[0], new([]*big.Int)).(*[]*big.Int) + outstruct.SecondsPerLiquidityCumulativeX128s = *abi.ConvertType(out[1], new([]*big.Int)).(*[]*big.Int) + + return *outstruct, err + +} + +// Observe is a free data retrieval call binding the contract method 0x883bdbfd. +// +// Solidity: function observe(uint32[] secondsAgos) view returns(int56[] tickCumulatives, uint160[] secondsPerLiquidityCumulativeX128s) +func (_Uniswap *UniswapSession) Observe(secondsAgos []uint32) (struct { + TickCumulatives []*big.Int + SecondsPerLiquidityCumulativeX128s []*big.Int +}, error) { + return _Uniswap.Contract.Observe(&_Uniswap.CallOpts, secondsAgos) +} + +// Observe is a free data retrieval call binding the contract method 0x883bdbfd. +// +// Solidity: function observe(uint32[] secondsAgos) view returns(int56[] tickCumulatives, uint160[] secondsPerLiquidityCumulativeX128s) +func (_Uniswap *UniswapCallerSession) Observe(secondsAgos []uint32) (struct { + TickCumulatives []*big.Int + SecondsPerLiquidityCumulativeX128s []*big.Int +}, error) { + return _Uniswap.Contract.Observe(&_Uniswap.CallOpts, secondsAgos) +} + +// Positions is a free data retrieval call binding the contract method 0x514ea4bf. +// +// Solidity: function positions(bytes32 ) view returns(uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1) +func (_Uniswap *UniswapCaller) Positions(opts *bind.CallOpts, arg0 [32]byte) (struct { + Liquidity *big.Int + FeeGrowthInside0LastX128 *big.Int + FeeGrowthInside1LastX128 *big.Int + TokensOwed0 *big.Int + TokensOwed1 *big.Int +}, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "positions", arg0) + + outstruct := new(struct { + Liquidity *big.Int + FeeGrowthInside0LastX128 *big.Int + FeeGrowthInside1LastX128 *big.Int + TokensOwed0 *big.Int + TokensOwed1 *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.Liquidity = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.FeeGrowthInside0LastX128 = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.FeeGrowthInside1LastX128 = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.TokensOwed0 = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.TokensOwed1 = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// Positions is a free data retrieval call binding the contract method 0x514ea4bf. +// +// Solidity: function positions(bytes32 ) view returns(uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1) +func (_Uniswap *UniswapSession) Positions(arg0 [32]byte) (struct { + Liquidity *big.Int + FeeGrowthInside0LastX128 *big.Int + FeeGrowthInside1LastX128 *big.Int + TokensOwed0 *big.Int + TokensOwed1 *big.Int +}, error) { + return _Uniswap.Contract.Positions(&_Uniswap.CallOpts, arg0) +} + +// Positions is a free data retrieval call binding the contract method 0x514ea4bf. +// +// Solidity: function positions(bytes32 ) view returns(uint128 liquidity, uint256 feeGrowthInside0LastX128, uint256 feeGrowthInside1LastX128, uint128 tokensOwed0, uint128 tokensOwed1) +func (_Uniswap *UniswapCallerSession) Positions(arg0 [32]byte) (struct { + Liquidity *big.Int + FeeGrowthInside0LastX128 *big.Int + FeeGrowthInside1LastX128 *big.Int + TokensOwed0 *big.Int + TokensOwed1 *big.Int +}, error) { + return _Uniswap.Contract.Positions(&_Uniswap.CallOpts, arg0) +} + +// ProtocolFees is a free data retrieval call binding the contract method 0x1ad8b03b. +// +// Solidity: function protocolFees() view returns(uint128 token0, uint128 token1) +func (_Uniswap *UniswapCaller) ProtocolFees(opts *bind.CallOpts) (struct { + Token0 *big.Int + Token1 *big.Int +}, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "protocolFees") + + outstruct := new(struct { + Token0 *big.Int + Token1 *big.Int + }) + if err != nil { + return *outstruct, err + } + + outstruct.Token0 = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Token1 = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + + return *outstruct, err + +} + +// ProtocolFees is a free data retrieval call binding the contract method 0x1ad8b03b. +// +// Solidity: function protocolFees() view returns(uint128 token0, uint128 token1) +func (_Uniswap *UniswapSession) ProtocolFees() (struct { + Token0 *big.Int + Token1 *big.Int +}, error) { + return _Uniswap.Contract.ProtocolFees(&_Uniswap.CallOpts) +} + +// ProtocolFees is a free data retrieval call binding the contract method 0x1ad8b03b. +// +// Solidity: function protocolFees() view returns(uint128 token0, uint128 token1) +func (_Uniswap *UniswapCallerSession) ProtocolFees() (struct { + Token0 *big.Int + Token1 *big.Int +}, error) { + return _Uniswap.Contract.ProtocolFees(&_Uniswap.CallOpts) +} + +// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. +// +// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) +func (_Uniswap *UniswapCaller) Slot0(opts *bind.CallOpts) (struct { + SqrtPriceX96 *big.Int + Tick *big.Int + ObservationIndex uint16 + ObservationCardinality uint16 + ObservationCardinalityNext uint16 + FeeProtocol uint8 + Unlocked bool +}, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "slot0") + + outstruct := new(struct { + SqrtPriceX96 *big.Int + Tick *big.Int + ObservationIndex uint16 + ObservationCardinality uint16 + ObservationCardinalityNext uint16 + FeeProtocol uint8 + Unlocked bool + }) + if err != nil { + return *outstruct, err + } + + outstruct.SqrtPriceX96 = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.Tick = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.ObservationIndex = *abi.ConvertType(out[2], new(uint16)).(*uint16) + outstruct.ObservationCardinality = *abi.ConvertType(out[3], new(uint16)).(*uint16) + outstruct.ObservationCardinalityNext = *abi.ConvertType(out[4], new(uint16)).(*uint16) + outstruct.FeeProtocol = *abi.ConvertType(out[5], new(uint8)).(*uint8) + outstruct.Unlocked = *abi.ConvertType(out[6], new(bool)).(*bool) + + return *outstruct, err + +} + +// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. +// +// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) +func (_Uniswap *UniswapSession) Slot0() (struct { + SqrtPriceX96 *big.Int + Tick *big.Int + ObservationIndex uint16 + ObservationCardinality uint16 + ObservationCardinalityNext uint16 + FeeProtocol uint8 + Unlocked bool +}, error) { + return _Uniswap.Contract.Slot0(&_Uniswap.CallOpts) +} + +// Slot0 is a free data retrieval call binding the contract method 0x3850c7bd. +// +// Solidity: function slot0() view returns(uint160 sqrtPriceX96, int24 tick, uint16 observationIndex, uint16 observationCardinality, uint16 observationCardinalityNext, uint8 feeProtocol, bool unlocked) +func (_Uniswap *UniswapCallerSession) Slot0() (struct { + SqrtPriceX96 *big.Int + Tick *big.Int + ObservationIndex uint16 + ObservationCardinality uint16 + ObservationCardinalityNext uint16 + FeeProtocol uint8 + Unlocked bool +}, error) { + return _Uniswap.Contract.Slot0(&_Uniswap.CallOpts) +} + +// SnapshotCumulativesInside is a free data retrieval call binding the contract method 0xa38807f2. +// +// Solidity: function snapshotCumulativesInside(int24 tickLower, int24 tickUpper) view returns(int56 tickCumulativeInside, uint160 secondsPerLiquidityInsideX128, uint32 secondsInside) +func (_Uniswap *UniswapCaller) SnapshotCumulativesInside(opts *bind.CallOpts, tickLower *big.Int, tickUpper *big.Int) (struct { + TickCumulativeInside *big.Int + SecondsPerLiquidityInsideX128 *big.Int + SecondsInside uint32 +}, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "snapshotCumulativesInside", tickLower, tickUpper) + + outstruct := new(struct { + TickCumulativeInside *big.Int + SecondsPerLiquidityInsideX128 *big.Int + SecondsInside uint32 + }) + if err != nil { + return *outstruct, err + } + + outstruct.TickCumulativeInside = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.SecondsPerLiquidityInsideX128 = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.SecondsInside = *abi.ConvertType(out[2], new(uint32)).(*uint32) + + return *outstruct, err + +} + +// SnapshotCumulativesInside is a free data retrieval call binding the contract method 0xa38807f2. +// +// Solidity: function snapshotCumulativesInside(int24 tickLower, int24 tickUpper) view returns(int56 tickCumulativeInside, uint160 secondsPerLiquidityInsideX128, uint32 secondsInside) +func (_Uniswap *UniswapSession) SnapshotCumulativesInside(tickLower *big.Int, tickUpper *big.Int) (struct { + TickCumulativeInside *big.Int + SecondsPerLiquidityInsideX128 *big.Int + SecondsInside uint32 +}, error) { + return _Uniswap.Contract.SnapshotCumulativesInside(&_Uniswap.CallOpts, tickLower, tickUpper) +} + +// SnapshotCumulativesInside is a free data retrieval call binding the contract method 0xa38807f2. +// +// Solidity: function snapshotCumulativesInside(int24 tickLower, int24 tickUpper) view returns(int56 tickCumulativeInside, uint160 secondsPerLiquidityInsideX128, uint32 secondsInside) +func (_Uniswap *UniswapCallerSession) SnapshotCumulativesInside(tickLower *big.Int, tickUpper *big.Int) (struct { + TickCumulativeInside *big.Int + SecondsPerLiquidityInsideX128 *big.Int + SecondsInside uint32 +}, error) { + return _Uniswap.Contract.SnapshotCumulativesInside(&_Uniswap.CallOpts, tickLower, tickUpper) +} + +// TickBitmap is a free data retrieval call binding the contract method 0x5339c296. +// +// Solidity: function tickBitmap(int16 ) view returns(uint256) +func (_Uniswap *UniswapCaller) TickBitmap(opts *bind.CallOpts, arg0 int16) (*big.Int, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "tickBitmap", arg0) + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TickBitmap is a free data retrieval call binding the contract method 0x5339c296. +// +// Solidity: function tickBitmap(int16 ) view returns(uint256) +func (_Uniswap *UniswapSession) TickBitmap(arg0 int16) (*big.Int, error) { + return _Uniswap.Contract.TickBitmap(&_Uniswap.CallOpts, arg0) +} + +// TickBitmap is a free data retrieval call binding the contract method 0x5339c296. +// +// Solidity: function tickBitmap(int16 ) view returns(uint256) +func (_Uniswap *UniswapCallerSession) TickBitmap(arg0 int16) (*big.Int, error) { + return _Uniswap.Contract.TickBitmap(&_Uniswap.CallOpts, arg0) +} + +// TickSpacing is a free data retrieval call binding the contract method 0xd0c93a7c. +// +// Solidity: function tickSpacing() view returns(int24) +func (_Uniswap *UniswapCaller) TickSpacing(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "tickSpacing") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TickSpacing is a free data retrieval call binding the contract method 0xd0c93a7c. +// +// Solidity: function tickSpacing() view returns(int24) +func (_Uniswap *UniswapSession) TickSpacing() (*big.Int, error) { + return _Uniswap.Contract.TickSpacing(&_Uniswap.CallOpts) +} + +// TickSpacing is a free data retrieval call binding the contract method 0xd0c93a7c. +// +// Solidity: function tickSpacing() view returns(int24) +func (_Uniswap *UniswapCallerSession) TickSpacing() (*big.Int, error) { + return _Uniswap.Contract.TickSpacing(&_Uniswap.CallOpts) +} + +// Ticks is a free data retrieval call binding the contract method 0xf30dba93. +// +// Solidity: function ticks(int24 ) view returns(uint128 liquidityGross, int128 liquidityNet, uint256 feeGrowthOutside0X128, uint256 feeGrowthOutside1X128, int56 tickCumulativeOutside, uint160 secondsPerLiquidityOutsideX128, uint32 secondsOutside, bool initialized) +func (_Uniswap *UniswapCaller) Ticks(opts *bind.CallOpts, arg0 *big.Int) (struct { + LiquidityGross *big.Int + LiquidityNet *big.Int + FeeGrowthOutside0X128 *big.Int + FeeGrowthOutside1X128 *big.Int + TickCumulativeOutside *big.Int + SecondsPerLiquidityOutsideX128 *big.Int + SecondsOutside uint32 + Initialized bool +}, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "ticks", arg0) + + outstruct := new(struct { + LiquidityGross *big.Int + LiquidityNet *big.Int + FeeGrowthOutside0X128 *big.Int + FeeGrowthOutside1X128 *big.Int + TickCumulativeOutside *big.Int + SecondsPerLiquidityOutsideX128 *big.Int + SecondsOutside uint32 + Initialized bool + }) + if err != nil { + return *outstruct, err + } + + outstruct.LiquidityGross = *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + outstruct.LiquidityNet = *abi.ConvertType(out[1], new(*big.Int)).(**big.Int) + outstruct.FeeGrowthOutside0X128 = *abi.ConvertType(out[2], new(*big.Int)).(**big.Int) + outstruct.FeeGrowthOutside1X128 = *abi.ConvertType(out[3], new(*big.Int)).(**big.Int) + outstruct.TickCumulativeOutside = *abi.ConvertType(out[4], new(*big.Int)).(**big.Int) + outstruct.SecondsPerLiquidityOutsideX128 = *abi.ConvertType(out[5], new(*big.Int)).(**big.Int) + outstruct.SecondsOutside = *abi.ConvertType(out[6], new(uint32)).(*uint32) + outstruct.Initialized = *abi.ConvertType(out[7], new(bool)).(*bool) + + return *outstruct, err + +} + +// Ticks is a free data retrieval call binding the contract method 0xf30dba93. +// +// Solidity: function ticks(int24 ) view returns(uint128 liquidityGross, int128 liquidityNet, uint256 feeGrowthOutside0X128, uint256 feeGrowthOutside1X128, int56 tickCumulativeOutside, uint160 secondsPerLiquidityOutsideX128, uint32 secondsOutside, bool initialized) +func (_Uniswap *UniswapSession) Ticks(arg0 *big.Int) (struct { + LiquidityGross *big.Int + LiquidityNet *big.Int + FeeGrowthOutside0X128 *big.Int + FeeGrowthOutside1X128 *big.Int + TickCumulativeOutside *big.Int + SecondsPerLiquidityOutsideX128 *big.Int + SecondsOutside uint32 + Initialized bool +}, error) { + return _Uniswap.Contract.Ticks(&_Uniswap.CallOpts, arg0) +} + +// Ticks is a free data retrieval call binding the contract method 0xf30dba93. +// +// Solidity: function ticks(int24 ) view returns(uint128 liquidityGross, int128 liquidityNet, uint256 feeGrowthOutside0X128, uint256 feeGrowthOutside1X128, int56 tickCumulativeOutside, uint160 secondsPerLiquidityOutsideX128, uint32 secondsOutside, bool initialized) +func (_Uniswap *UniswapCallerSession) Ticks(arg0 *big.Int) (struct { + LiquidityGross *big.Int + LiquidityNet *big.Int + FeeGrowthOutside0X128 *big.Int + FeeGrowthOutside1X128 *big.Int + TickCumulativeOutside *big.Int + SecondsPerLiquidityOutsideX128 *big.Int + SecondsOutside uint32 + Initialized bool +}, error) { + return _Uniswap.Contract.Ticks(&_Uniswap.CallOpts, arg0) +} + +// Token0 is a free data retrieval call binding the contract method 0x0dfe1681. +// +// Solidity: function token0() view returns(address) +func (_Uniswap *UniswapCaller) Token0(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "token0") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Token0 is a free data retrieval call binding the contract method 0x0dfe1681. +// +// Solidity: function token0() view returns(address) +func (_Uniswap *UniswapSession) Token0() (common.Address, error) { + return _Uniswap.Contract.Token0(&_Uniswap.CallOpts) +} + +// Token0 is a free data retrieval call binding the contract method 0x0dfe1681. +// +// Solidity: function token0() view returns(address) +func (_Uniswap *UniswapCallerSession) Token0() (common.Address, error) { + return _Uniswap.Contract.Token0(&_Uniswap.CallOpts) +} + +// Token1 is a free data retrieval call binding the contract method 0xd21220a7. +// +// Solidity: function token1() view returns(address) +func (_Uniswap *UniswapCaller) Token1(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Uniswap.contract.Call(opts, &out, "token1") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Token1 is a free data retrieval call binding the contract method 0xd21220a7. +// +// Solidity: function token1() view returns(address) +func (_Uniswap *UniswapSession) Token1() (common.Address, error) { + return _Uniswap.Contract.Token1(&_Uniswap.CallOpts) +} + +// Token1 is a free data retrieval call binding the contract method 0xd21220a7. +// +// Solidity: function token1() view returns(address) +func (_Uniswap *UniswapCallerSession) Token1() (common.Address, error) { + return _Uniswap.Contract.Token1(&_Uniswap.CallOpts) +} + +// Burn is a paid mutator transaction binding the contract method 0xa34123a7. +// +// Solidity: function burn(int24 tickLower, int24 tickUpper, uint128 amount) returns(uint256 amount0, uint256 amount1) +func (_Uniswap *UniswapTransactor) Burn(opts *bind.TransactOpts, tickLower *big.Int, tickUpper *big.Int, amount *big.Int) (*types.Transaction, error) { + return _Uniswap.contract.Transact(opts, "burn", tickLower, tickUpper, amount) +} + +// Burn is a paid mutator transaction binding the contract method 0xa34123a7. +// +// Solidity: function burn(int24 tickLower, int24 tickUpper, uint128 amount) returns(uint256 amount0, uint256 amount1) +func (_Uniswap *UniswapSession) Burn(tickLower *big.Int, tickUpper *big.Int, amount *big.Int) (*types.Transaction, error) { + return _Uniswap.Contract.Burn(&_Uniswap.TransactOpts, tickLower, tickUpper, amount) +} + +// Burn is a paid mutator transaction binding the contract method 0xa34123a7. +// +// Solidity: function burn(int24 tickLower, int24 tickUpper, uint128 amount) returns(uint256 amount0, uint256 amount1) +func (_Uniswap *UniswapTransactorSession) Burn(tickLower *big.Int, tickUpper *big.Int, amount *big.Int) (*types.Transaction, error) { + return _Uniswap.Contract.Burn(&_Uniswap.TransactOpts, tickLower, tickUpper, amount) +} + +// Collect is a paid mutator transaction binding the contract method 0x4f1eb3d8. +// +// Solidity: function collect(address recipient, int24 tickLower, int24 tickUpper, uint128 amount0Requested, uint128 amount1Requested) returns(uint128 amount0, uint128 amount1) +func (_Uniswap *UniswapTransactor) Collect(opts *bind.TransactOpts, recipient common.Address, tickLower *big.Int, tickUpper *big.Int, amount0Requested *big.Int, amount1Requested *big.Int) (*types.Transaction, error) { + return _Uniswap.contract.Transact(opts, "collect", recipient, tickLower, tickUpper, amount0Requested, amount1Requested) +} + +// Collect is a paid mutator transaction binding the contract method 0x4f1eb3d8. +// +// Solidity: function collect(address recipient, int24 tickLower, int24 tickUpper, uint128 amount0Requested, uint128 amount1Requested) returns(uint128 amount0, uint128 amount1) +func (_Uniswap *UniswapSession) Collect(recipient common.Address, tickLower *big.Int, tickUpper *big.Int, amount0Requested *big.Int, amount1Requested *big.Int) (*types.Transaction, error) { + return _Uniswap.Contract.Collect(&_Uniswap.TransactOpts, recipient, tickLower, tickUpper, amount0Requested, amount1Requested) +} + +// Collect is a paid mutator transaction binding the contract method 0x4f1eb3d8. +// +// Solidity: function collect(address recipient, int24 tickLower, int24 tickUpper, uint128 amount0Requested, uint128 amount1Requested) returns(uint128 amount0, uint128 amount1) +func (_Uniswap *UniswapTransactorSession) Collect(recipient common.Address, tickLower *big.Int, tickUpper *big.Int, amount0Requested *big.Int, amount1Requested *big.Int) (*types.Transaction, error) { + return _Uniswap.Contract.Collect(&_Uniswap.TransactOpts, recipient, tickLower, tickUpper, amount0Requested, amount1Requested) +} + +// CollectProtocol is a paid mutator transaction binding the contract method 0x85b66729. +// +// Solidity: function collectProtocol(address recipient, uint128 amount0Requested, uint128 amount1Requested) returns(uint128 amount0, uint128 amount1) +func (_Uniswap *UniswapTransactor) CollectProtocol(opts *bind.TransactOpts, recipient common.Address, amount0Requested *big.Int, amount1Requested *big.Int) (*types.Transaction, error) { + return _Uniswap.contract.Transact(opts, "collectProtocol", recipient, amount0Requested, amount1Requested) +} + +// CollectProtocol is a paid mutator transaction binding the contract method 0x85b66729. +// +// Solidity: function collectProtocol(address recipient, uint128 amount0Requested, uint128 amount1Requested) returns(uint128 amount0, uint128 amount1) +func (_Uniswap *UniswapSession) CollectProtocol(recipient common.Address, amount0Requested *big.Int, amount1Requested *big.Int) (*types.Transaction, error) { + return _Uniswap.Contract.CollectProtocol(&_Uniswap.TransactOpts, recipient, amount0Requested, amount1Requested) +} + +// CollectProtocol is a paid mutator transaction binding the contract method 0x85b66729. +// +// Solidity: function collectProtocol(address recipient, uint128 amount0Requested, uint128 amount1Requested) returns(uint128 amount0, uint128 amount1) +func (_Uniswap *UniswapTransactorSession) CollectProtocol(recipient common.Address, amount0Requested *big.Int, amount1Requested *big.Int) (*types.Transaction, error) { + return _Uniswap.Contract.CollectProtocol(&_Uniswap.TransactOpts, recipient, amount0Requested, amount1Requested) +} + +// Flash is a paid mutator transaction binding the contract method 0x490e6cbc. +// +// Solidity: function flash(address recipient, uint256 amount0, uint256 amount1, bytes data) returns() +func (_Uniswap *UniswapTransactor) Flash(opts *bind.TransactOpts, recipient common.Address, amount0 *big.Int, amount1 *big.Int, data []byte) (*types.Transaction, error) { + return _Uniswap.contract.Transact(opts, "flash", recipient, amount0, amount1, data) +} + +// Flash is a paid mutator transaction binding the contract method 0x490e6cbc. +// +// Solidity: function flash(address recipient, uint256 amount0, uint256 amount1, bytes data) returns() +func (_Uniswap *UniswapSession) Flash(recipient common.Address, amount0 *big.Int, amount1 *big.Int, data []byte) (*types.Transaction, error) { + return _Uniswap.Contract.Flash(&_Uniswap.TransactOpts, recipient, amount0, amount1, data) +} + +// Flash is a paid mutator transaction binding the contract method 0x490e6cbc. +// +// Solidity: function flash(address recipient, uint256 amount0, uint256 amount1, bytes data) returns() +func (_Uniswap *UniswapTransactorSession) Flash(recipient common.Address, amount0 *big.Int, amount1 *big.Int, data []byte) (*types.Transaction, error) { + return _Uniswap.Contract.Flash(&_Uniswap.TransactOpts, recipient, amount0, amount1, data) +} + +// IncreaseObservationCardinalityNext is a paid mutator transaction binding the contract method 0x32148f67. +// +// Solidity: function increaseObservationCardinalityNext(uint16 observationCardinalityNext) returns() +func (_Uniswap *UniswapTransactor) IncreaseObservationCardinalityNext(opts *bind.TransactOpts, observationCardinalityNext uint16) (*types.Transaction, error) { + return _Uniswap.contract.Transact(opts, "increaseObservationCardinalityNext", observationCardinalityNext) +} + +// IncreaseObservationCardinalityNext is a paid mutator transaction binding the contract method 0x32148f67. +// +// Solidity: function increaseObservationCardinalityNext(uint16 observationCardinalityNext) returns() +func (_Uniswap *UniswapSession) IncreaseObservationCardinalityNext(observationCardinalityNext uint16) (*types.Transaction, error) { + return _Uniswap.Contract.IncreaseObservationCardinalityNext(&_Uniswap.TransactOpts, observationCardinalityNext) +} + +// IncreaseObservationCardinalityNext is a paid mutator transaction binding the contract method 0x32148f67. +// +// Solidity: function increaseObservationCardinalityNext(uint16 observationCardinalityNext) returns() +func (_Uniswap *UniswapTransactorSession) IncreaseObservationCardinalityNext(observationCardinalityNext uint16) (*types.Transaction, error) { + return _Uniswap.Contract.IncreaseObservationCardinalityNext(&_Uniswap.TransactOpts, observationCardinalityNext) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf637731d. +// +// Solidity: function initialize(uint160 sqrtPriceX96) returns() +func (_Uniswap *UniswapTransactor) Initialize(opts *bind.TransactOpts, sqrtPriceX96 *big.Int) (*types.Transaction, error) { + return _Uniswap.contract.Transact(opts, "initialize", sqrtPriceX96) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf637731d. +// +// Solidity: function initialize(uint160 sqrtPriceX96) returns() +func (_Uniswap *UniswapSession) Initialize(sqrtPriceX96 *big.Int) (*types.Transaction, error) { + return _Uniswap.Contract.Initialize(&_Uniswap.TransactOpts, sqrtPriceX96) +} + +// Initialize is a paid mutator transaction binding the contract method 0xf637731d. +// +// Solidity: function initialize(uint160 sqrtPriceX96) returns() +func (_Uniswap *UniswapTransactorSession) Initialize(sqrtPriceX96 *big.Int) (*types.Transaction, error) { + return _Uniswap.Contract.Initialize(&_Uniswap.TransactOpts, sqrtPriceX96) +} + +// Mint is a paid mutator transaction binding the contract method 0x3c8a7d8d. +// +// Solidity: function mint(address recipient, int24 tickLower, int24 tickUpper, uint128 amount, bytes data) returns(uint256 amount0, uint256 amount1) +func (_Uniswap *UniswapTransactor) Mint(opts *bind.TransactOpts, recipient common.Address, tickLower *big.Int, tickUpper *big.Int, amount *big.Int, data []byte) (*types.Transaction, error) { + return _Uniswap.contract.Transact(opts, "mint", recipient, tickLower, tickUpper, amount, data) +} + +// Mint is a paid mutator transaction binding the contract method 0x3c8a7d8d. +// +// Solidity: function mint(address recipient, int24 tickLower, int24 tickUpper, uint128 amount, bytes data) returns(uint256 amount0, uint256 amount1) +func (_Uniswap *UniswapSession) Mint(recipient common.Address, tickLower *big.Int, tickUpper *big.Int, amount *big.Int, data []byte) (*types.Transaction, error) { + return _Uniswap.Contract.Mint(&_Uniswap.TransactOpts, recipient, tickLower, tickUpper, amount, data) +} + +// Mint is a paid mutator transaction binding the contract method 0x3c8a7d8d. +// +// Solidity: function mint(address recipient, int24 tickLower, int24 tickUpper, uint128 amount, bytes data) returns(uint256 amount0, uint256 amount1) +func (_Uniswap *UniswapTransactorSession) Mint(recipient common.Address, tickLower *big.Int, tickUpper *big.Int, amount *big.Int, data []byte) (*types.Transaction, error) { + return _Uniswap.Contract.Mint(&_Uniswap.TransactOpts, recipient, tickLower, tickUpper, amount, data) +} + +// SetFeeProtocol is a paid mutator transaction binding the contract method 0x8206a4d1. +// +// Solidity: function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) returns() +func (_Uniswap *UniswapTransactor) SetFeeProtocol(opts *bind.TransactOpts, feeProtocol0 uint8, feeProtocol1 uint8) (*types.Transaction, error) { + return _Uniswap.contract.Transact(opts, "setFeeProtocol", feeProtocol0, feeProtocol1) +} + +// SetFeeProtocol is a paid mutator transaction binding the contract method 0x8206a4d1. +// +// Solidity: function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) returns() +func (_Uniswap *UniswapSession) SetFeeProtocol(feeProtocol0 uint8, feeProtocol1 uint8) (*types.Transaction, error) { + return _Uniswap.Contract.SetFeeProtocol(&_Uniswap.TransactOpts, feeProtocol0, feeProtocol1) +} + +// SetFeeProtocol is a paid mutator transaction binding the contract method 0x8206a4d1. +// +// Solidity: function setFeeProtocol(uint8 feeProtocol0, uint8 feeProtocol1) returns() +func (_Uniswap *UniswapTransactorSession) SetFeeProtocol(feeProtocol0 uint8, feeProtocol1 uint8) (*types.Transaction, error) { + return _Uniswap.Contract.SetFeeProtocol(&_Uniswap.TransactOpts, feeProtocol0, feeProtocol1) +} + +// Swap is a paid mutator transaction binding the contract method 0x128acb08. +// +// Solidity: function swap(address recipient, bool zeroForOne, int256 amountSpecified, uint160 sqrtPriceLimitX96, bytes data) returns(int256 amount0, int256 amount1) +func (_Uniswap *UniswapTransactor) Swap(opts *bind.TransactOpts, recipient common.Address, zeroForOne bool, amountSpecified *big.Int, sqrtPriceLimitX96 *big.Int, data []byte) (*types.Transaction, error) { + return _Uniswap.contract.Transact(opts, "swap", recipient, zeroForOne, amountSpecified, sqrtPriceLimitX96, data) +} + +// Swap is a paid mutator transaction binding the contract method 0x128acb08. +// +// Solidity: function swap(address recipient, bool zeroForOne, int256 amountSpecified, uint160 sqrtPriceLimitX96, bytes data) returns(int256 amount0, int256 amount1) +func (_Uniswap *UniswapSession) Swap(recipient common.Address, zeroForOne bool, amountSpecified *big.Int, sqrtPriceLimitX96 *big.Int, data []byte) (*types.Transaction, error) { + return _Uniswap.Contract.Swap(&_Uniswap.TransactOpts, recipient, zeroForOne, amountSpecified, sqrtPriceLimitX96, data) +} + +// Swap is a paid mutator transaction binding the contract method 0x128acb08. +// +// Solidity: function swap(address recipient, bool zeroForOne, int256 amountSpecified, uint160 sqrtPriceLimitX96, bytes data) returns(int256 amount0, int256 amount1) +func (_Uniswap *UniswapTransactorSession) Swap(recipient common.Address, zeroForOne bool, amountSpecified *big.Int, sqrtPriceLimitX96 *big.Int, data []byte) (*types.Transaction, error) { + return _Uniswap.Contract.Swap(&_Uniswap.TransactOpts, recipient, zeroForOne, amountSpecified, sqrtPriceLimitX96, data) +} + +// UniswapBurnIterator is returned from FilterBurn and is used to iterate over the raw logs and unpacked data for Burn events raised by the Uniswap contract. +type UniswapBurnIterator struct { + Event *UniswapBurn // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UniswapBurnIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(UniswapBurn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(UniswapBurn) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *UniswapBurnIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UniswapBurnIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UniswapBurn represents a Burn event raised by the Uniswap contract. +type UniswapBurn struct { + Owner common.Address + TickLower *big.Int + TickUpper *big.Int + Amount *big.Int + Amount0 *big.Int + Amount1 *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterBurn is a free log retrieval operation binding the contract event 0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c. +// +// Solidity: event Burn(address indexed owner, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount, uint256 amount0, uint256 amount1) +func (_Uniswap *UniswapFilterer) FilterBurn(opts *bind.FilterOpts, owner []common.Address, tickLower []*big.Int, tickUpper []*big.Int) (*UniswapBurnIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var tickLowerRule []interface{} + for _, tickLowerItem := range tickLower { + tickLowerRule = append(tickLowerRule, tickLowerItem) + } + var tickUpperRule []interface{} + for _, tickUpperItem := range tickUpper { + tickUpperRule = append(tickUpperRule, tickUpperItem) + } + + logs, sub, err := _Uniswap.contract.FilterLogs(opts, "Burn", ownerRule, tickLowerRule, tickUpperRule) + if err != nil { + return nil, err + } + return &UniswapBurnIterator{contract: _Uniswap.contract, event: "Burn", logs: logs, sub: sub}, nil +} + +// WatchBurn is a free log subscription operation binding the contract event 0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c. +// +// Solidity: event Burn(address indexed owner, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount, uint256 amount0, uint256 amount1) +func (_Uniswap *UniswapFilterer) WatchBurn(opts *bind.WatchOpts, sink chan<- *UniswapBurn, owner []common.Address, tickLower []*big.Int, tickUpper []*big.Int) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var tickLowerRule []interface{} + for _, tickLowerItem := range tickLower { + tickLowerRule = append(tickLowerRule, tickLowerItem) + } + var tickUpperRule []interface{} + for _, tickUpperItem := range tickUpper { + tickUpperRule = append(tickUpperRule, tickUpperItem) + } + + logs, sub, err := _Uniswap.contract.WatchLogs(opts, "Burn", ownerRule, tickLowerRule, tickUpperRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(UniswapBurn) + if err := _Uniswap.contract.UnpackLog(event, "Burn", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseBurn is a log parse operation binding the contract event 0x0c396cd989a39f4459b5fa1aed6a9a8dcdbc45908acfd67e028cd568da98982c. +// +// Solidity: event Burn(address indexed owner, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount, uint256 amount0, uint256 amount1) +func (_Uniswap *UniswapFilterer) ParseBurn(log types.Log) (*UniswapBurn, error) { + event := new(UniswapBurn) + if err := _Uniswap.contract.UnpackLog(event, "Burn", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UniswapCollectIterator is returned from FilterCollect and is used to iterate over the raw logs and unpacked data for Collect events raised by the Uniswap contract. +type UniswapCollectIterator struct { + Event *UniswapCollect // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UniswapCollectIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(UniswapCollect) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(UniswapCollect) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *UniswapCollectIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UniswapCollectIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UniswapCollect represents a Collect event raised by the Uniswap contract. +type UniswapCollect struct { + Owner common.Address + Recipient common.Address + TickLower *big.Int + TickUpper *big.Int + Amount0 *big.Int + Amount1 *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCollect is a free log retrieval operation binding the contract event 0x70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0. +// +// Solidity: event Collect(address indexed owner, address recipient, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount0, uint128 amount1) +func (_Uniswap *UniswapFilterer) FilterCollect(opts *bind.FilterOpts, owner []common.Address, tickLower []*big.Int, tickUpper []*big.Int) (*UniswapCollectIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + var tickLowerRule []interface{} + for _, tickLowerItem := range tickLower { + tickLowerRule = append(tickLowerRule, tickLowerItem) + } + var tickUpperRule []interface{} + for _, tickUpperItem := range tickUpper { + tickUpperRule = append(tickUpperRule, tickUpperItem) + } + + logs, sub, err := _Uniswap.contract.FilterLogs(opts, "Collect", ownerRule, tickLowerRule, tickUpperRule) + if err != nil { + return nil, err + } + return &UniswapCollectIterator{contract: _Uniswap.contract, event: "Collect", logs: logs, sub: sub}, nil +} + +// WatchCollect is a free log subscription operation binding the contract event 0x70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0. +// +// Solidity: event Collect(address indexed owner, address recipient, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount0, uint128 amount1) +func (_Uniswap *UniswapFilterer) WatchCollect(opts *bind.WatchOpts, sink chan<- *UniswapCollect, owner []common.Address, tickLower []*big.Int, tickUpper []*big.Int) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + + var tickLowerRule []interface{} + for _, tickLowerItem := range tickLower { + tickLowerRule = append(tickLowerRule, tickLowerItem) + } + var tickUpperRule []interface{} + for _, tickUpperItem := range tickUpper { + tickUpperRule = append(tickUpperRule, tickUpperItem) + } + + logs, sub, err := _Uniswap.contract.WatchLogs(opts, "Collect", ownerRule, tickLowerRule, tickUpperRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(UniswapCollect) + if err := _Uniswap.contract.UnpackLog(event, "Collect", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseCollect is a log parse operation binding the contract event 0x70935338e69775456a85ddef226c395fb668b63fa0115f5f20610b388e6ca9c0. +// +// Solidity: event Collect(address indexed owner, address recipient, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount0, uint128 amount1) +func (_Uniswap *UniswapFilterer) ParseCollect(log types.Log) (*UniswapCollect, error) { + event := new(UniswapCollect) + if err := _Uniswap.contract.UnpackLog(event, "Collect", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UniswapCollectProtocolIterator is returned from FilterCollectProtocol and is used to iterate over the raw logs and unpacked data for CollectProtocol events raised by the Uniswap contract. +type UniswapCollectProtocolIterator struct { + Event *UniswapCollectProtocol // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UniswapCollectProtocolIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(UniswapCollectProtocol) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(UniswapCollectProtocol) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *UniswapCollectProtocolIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UniswapCollectProtocolIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UniswapCollectProtocol represents a CollectProtocol event raised by the Uniswap contract. +type UniswapCollectProtocol struct { + Sender common.Address + Recipient common.Address + Amount0 *big.Int + Amount1 *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterCollectProtocol is a free log retrieval operation binding the contract event 0x596b573906218d3411850b26a6b437d6c4522fdb43d2d2386263f86d50b8b151. +// +// Solidity: event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1) +func (_Uniswap *UniswapFilterer) FilterCollectProtocol(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*UniswapCollectProtocolIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _Uniswap.contract.FilterLogs(opts, "CollectProtocol", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &UniswapCollectProtocolIterator{contract: _Uniswap.contract, event: "CollectProtocol", logs: logs, sub: sub}, nil +} + +// WatchCollectProtocol is a free log subscription operation binding the contract event 0x596b573906218d3411850b26a6b437d6c4522fdb43d2d2386263f86d50b8b151. +// +// Solidity: event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1) +func (_Uniswap *UniswapFilterer) WatchCollectProtocol(opts *bind.WatchOpts, sink chan<- *UniswapCollectProtocol, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _Uniswap.contract.WatchLogs(opts, "CollectProtocol", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(UniswapCollectProtocol) + if err := _Uniswap.contract.UnpackLog(event, "CollectProtocol", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseCollectProtocol is a log parse operation binding the contract event 0x596b573906218d3411850b26a6b437d6c4522fdb43d2d2386263f86d50b8b151. +// +// Solidity: event CollectProtocol(address indexed sender, address indexed recipient, uint128 amount0, uint128 amount1) +func (_Uniswap *UniswapFilterer) ParseCollectProtocol(log types.Log) (*UniswapCollectProtocol, error) { + event := new(UniswapCollectProtocol) + if err := _Uniswap.contract.UnpackLog(event, "CollectProtocol", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UniswapFlashIterator is returned from FilterFlash and is used to iterate over the raw logs and unpacked data for Flash events raised by the Uniswap contract. +type UniswapFlashIterator struct { + Event *UniswapFlash // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UniswapFlashIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(UniswapFlash) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(UniswapFlash) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *UniswapFlashIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UniswapFlashIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UniswapFlash represents a Flash event raised by the Uniswap contract. +type UniswapFlash struct { + Sender common.Address + Recipient common.Address + Amount0 *big.Int + Amount1 *big.Int + Paid0 *big.Int + Paid1 *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterFlash is a free log retrieval operation binding the contract event 0xbdbdb71d7860376ba52b25a5028beea23581364a40522f6bcfb86bb1f2dca633. +// +// Solidity: event Flash(address indexed sender, address indexed recipient, uint256 amount0, uint256 amount1, uint256 paid0, uint256 paid1) +func (_Uniswap *UniswapFilterer) FilterFlash(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*UniswapFlashIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _Uniswap.contract.FilterLogs(opts, "Flash", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &UniswapFlashIterator{contract: _Uniswap.contract, event: "Flash", logs: logs, sub: sub}, nil +} + +// WatchFlash is a free log subscription operation binding the contract event 0xbdbdb71d7860376ba52b25a5028beea23581364a40522f6bcfb86bb1f2dca633. +// +// Solidity: event Flash(address indexed sender, address indexed recipient, uint256 amount0, uint256 amount1, uint256 paid0, uint256 paid1) +func (_Uniswap *UniswapFilterer) WatchFlash(opts *bind.WatchOpts, sink chan<- *UniswapFlash, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _Uniswap.contract.WatchLogs(opts, "Flash", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(UniswapFlash) + if err := _Uniswap.contract.UnpackLog(event, "Flash", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseFlash is a log parse operation binding the contract event 0xbdbdb71d7860376ba52b25a5028beea23581364a40522f6bcfb86bb1f2dca633. +// +// Solidity: event Flash(address indexed sender, address indexed recipient, uint256 amount0, uint256 amount1, uint256 paid0, uint256 paid1) +func (_Uniswap *UniswapFilterer) ParseFlash(log types.Log) (*UniswapFlash, error) { + event := new(UniswapFlash) + if err := _Uniswap.contract.UnpackLog(event, "Flash", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UniswapIncreaseObservationCardinalityNextIterator is returned from FilterIncreaseObservationCardinalityNext and is used to iterate over the raw logs and unpacked data for IncreaseObservationCardinalityNext events raised by the Uniswap contract. +type UniswapIncreaseObservationCardinalityNextIterator struct { + Event *UniswapIncreaseObservationCardinalityNext // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UniswapIncreaseObservationCardinalityNextIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(UniswapIncreaseObservationCardinalityNext) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(UniswapIncreaseObservationCardinalityNext) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *UniswapIncreaseObservationCardinalityNextIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UniswapIncreaseObservationCardinalityNextIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UniswapIncreaseObservationCardinalityNext represents a IncreaseObservationCardinalityNext event raised by the Uniswap contract. +type UniswapIncreaseObservationCardinalityNext struct { + ObservationCardinalityNextOld uint16 + ObservationCardinalityNextNew uint16 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterIncreaseObservationCardinalityNext is a free log retrieval operation binding the contract event 0xac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a. +// +// Solidity: event IncreaseObservationCardinalityNext(uint16 observationCardinalityNextOld, uint16 observationCardinalityNextNew) +func (_Uniswap *UniswapFilterer) FilterIncreaseObservationCardinalityNext(opts *bind.FilterOpts) (*UniswapIncreaseObservationCardinalityNextIterator, error) { + + logs, sub, err := _Uniswap.contract.FilterLogs(opts, "IncreaseObservationCardinalityNext") + if err != nil { + return nil, err + } + return &UniswapIncreaseObservationCardinalityNextIterator{contract: _Uniswap.contract, event: "IncreaseObservationCardinalityNext", logs: logs, sub: sub}, nil +} + +// WatchIncreaseObservationCardinalityNext is a free log subscription operation binding the contract event 0xac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a. +// +// Solidity: event IncreaseObservationCardinalityNext(uint16 observationCardinalityNextOld, uint16 observationCardinalityNextNew) +func (_Uniswap *UniswapFilterer) WatchIncreaseObservationCardinalityNext(opts *bind.WatchOpts, sink chan<- *UniswapIncreaseObservationCardinalityNext) (event.Subscription, error) { + + logs, sub, err := _Uniswap.contract.WatchLogs(opts, "IncreaseObservationCardinalityNext") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(UniswapIncreaseObservationCardinalityNext) + if err := _Uniswap.contract.UnpackLog(event, "IncreaseObservationCardinalityNext", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseIncreaseObservationCardinalityNext is a log parse operation binding the contract event 0xac49e518f90a358f652e4400164f05a5d8f7e35e7747279bc3a93dbf584e125a. +// +// Solidity: event IncreaseObservationCardinalityNext(uint16 observationCardinalityNextOld, uint16 observationCardinalityNextNew) +func (_Uniswap *UniswapFilterer) ParseIncreaseObservationCardinalityNext(log types.Log) (*UniswapIncreaseObservationCardinalityNext, error) { + event := new(UniswapIncreaseObservationCardinalityNext) + if err := _Uniswap.contract.UnpackLog(event, "IncreaseObservationCardinalityNext", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UniswapInitializeIterator is returned from FilterInitialize and is used to iterate over the raw logs and unpacked data for Initialize events raised by the Uniswap contract. +type UniswapInitializeIterator struct { + Event *UniswapInitialize // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UniswapInitializeIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(UniswapInitialize) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(UniswapInitialize) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *UniswapInitializeIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UniswapInitializeIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UniswapInitialize represents a Initialize event raised by the Uniswap contract. +type UniswapInitialize struct { + SqrtPriceX96 *big.Int + Tick *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialize is a free log retrieval operation binding the contract event 0x98636036cb66a9c19a37435efc1e90142190214e8abeb821bdba3f2990dd4c95. +// +// Solidity: event Initialize(uint160 sqrtPriceX96, int24 tick) +func (_Uniswap *UniswapFilterer) FilterInitialize(opts *bind.FilterOpts) (*UniswapInitializeIterator, error) { + + logs, sub, err := _Uniswap.contract.FilterLogs(opts, "Initialize") + if err != nil { + return nil, err + } + return &UniswapInitializeIterator{contract: _Uniswap.contract, event: "Initialize", logs: logs, sub: sub}, nil +} + +// WatchInitialize is a free log subscription operation binding the contract event 0x98636036cb66a9c19a37435efc1e90142190214e8abeb821bdba3f2990dd4c95. +// +// Solidity: event Initialize(uint160 sqrtPriceX96, int24 tick) +func (_Uniswap *UniswapFilterer) WatchInitialize(opts *bind.WatchOpts, sink chan<- *UniswapInitialize) (event.Subscription, error) { + + logs, sub, err := _Uniswap.contract.WatchLogs(opts, "Initialize") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(UniswapInitialize) + if err := _Uniswap.contract.UnpackLog(event, "Initialize", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialize is a log parse operation binding the contract event 0x98636036cb66a9c19a37435efc1e90142190214e8abeb821bdba3f2990dd4c95. +// +// Solidity: event Initialize(uint160 sqrtPriceX96, int24 tick) +func (_Uniswap *UniswapFilterer) ParseInitialize(log types.Log) (*UniswapInitialize, error) { + event := new(UniswapInitialize) + if err := _Uniswap.contract.UnpackLog(event, "Initialize", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UniswapMintIterator is returned from FilterMint and is used to iterate over the raw logs and unpacked data for Mint events raised by the Uniswap contract. +type UniswapMintIterator struct { + Event *UniswapMint // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UniswapMintIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(UniswapMint) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(UniswapMint) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *UniswapMintIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UniswapMintIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UniswapMint represents a Mint event raised by the Uniswap contract. +type UniswapMint struct { + Sender common.Address + Owner common.Address + TickLower *big.Int + TickUpper *big.Int + Amount *big.Int + Amount0 *big.Int + Amount1 *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterMint is a free log retrieval operation binding the contract event 0x7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde. +// +// Solidity: event Mint(address sender, address indexed owner, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount, uint256 amount0, uint256 amount1) +func (_Uniswap *UniswapFilterer) FilterMint(opts *bind.FilterOpts, owner []common.Address, tickLower []*big.Int, tickUpper []*big.Int) (*UniswapMintIterator, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var tickLowerRule []interface{} + for _, tickLowerItem := range tickLower { + tickLowerRule = append(tickLowerRule, tickLowerItem) + } + var tickUpperRule []interface{} + for _, tickUpperItem := range tickUpper { + tickUpperRule = append(tickUpperRule, tickUpperItem) + } + + logs, sub, err := _Uniswap.contract.FilterLogs(opts, "Mint", ownerRule, tickLowerRule, tickUpperRule) + if err != nil { + return nil, err + } + return &UniswapMintIterator{contract: _Uniswap.contract, event: "Mint", logs: logs, sub: sub}, nil +} + +// WatchMint is a free log subscription operation binding the contract event 0x7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde. +// +// Solidity: event Mint(address sender, address indexed owner, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount, uint256 amount0, uint256 amount1) +func (_Uniswap *UniswapFilterer) WatchMint(opts *bind.WatchOpts, sink chan<- *UniswapMint, owner []common.Address, tickLower []*big.Int, tickUpper []*big.Int) (event.Subscription, error) { + + var ownerRule []interface{} + for _, ownerItem := range owner { + ownerRule = append(ownerRule, ownerItem) + } + var tickLowerRule []interface{} + for _, tickLowerItem := range tickLower { + tickLowerRule = append(tickLowerRule, tickLowerItem) + } + var tickUpperRule []interface{} + for _, tickUpperItem := range tickUpper { + tickUpperRule = append(tickUpperRule, tickUpperItem) + } + + logs, sub, err := _Uniswap.contract.WatchLogs(opts, "Mint", ownerRule, tickLowerRule, tickUpperRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(UniswapMint) + if err := _Uniswap.contract.UnpackLog(event, "Mint", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseMint is a log parse operation binding the contract event 0x7a53080ba414158be7ec69b987b5fb7d07dee101fe85488f0853ae16239d0bde. +// +// Solidity: event Mint(address sender, address indexed owner, int24 indexed tickLower, int24 indexed tickUpper, uint128 amount, uint256 amount0, uint256 amount1) +func (_Uniswap *UniswapFilterer) ParseMint(log types.Log) (*UniswapMint, error) { + event := new(UniswapMint) + if err := _Uniswap.contract.UnpackLog(event, "Mint", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UniswapSetFeeProtocolIterator is returned from FilterSetFeeProtocol and is used to iterate over the raw logs and unpacked data for SetFeeProtocol events raised by the Uniswap contract. +type UniswapSetFeeProtocolIterator struct { + Event *UniswapSetFeeProtocol // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UniswapSetFeeProtocolIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(UniswapSetFeeProtocol) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(UniswapSetFeeProtocol) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *UniswapSetFeeProtocolIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UniswapSetFeeProtocolIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UniswapSetFeeProtocol represents a SetFeeProtocol event raised by the Uniswap contract. +type UniswapSetFeeProtocol struct { + FeeProtocol0Old uint8 + FeeProtocol1Old uint8 + FeeProtocol0New uint8 + FeeProtocol1New uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSetFeeProtocol is a free log retrieval operation binding the contract event 0x973d8d92bb299f4af6ce49b52a8adb85ae46b9f214c4c4fc06ac77401237b133. +// +// Solidity: event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New) +func (_Uniswap *UniswapFilterer) FilterSetFeeProtocol(opts *bind.FilterOpts) (*UniswapSetFeeProtocolIterator, error) { + + logs, sub, err := _Uniswap.contract.FilterLogs(opts, "SetFeeProtocol") + if err != nil { + return nil, err + } + return &UniswapSetFeeProtocolIterator{contract: _Uniswap.contract, event: "SetFeeProtocol", logs: logs, sub: sub}, nil +} + +// WatchSetFeeProtocol is a free log subscription operation binding the contract event 0x973d8d92bb299f4af6ce49b52a8adb85ae46b9f214c4c4fc06ac77401237b133. +// +// Solidity: event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New) +func (_Uniswap *UniswapFilterer) WatchSetFeeProtocol(opts *bind.WatchOpts, sink chan<- *UniswapSetFeeProtocol) (event.Subscription, error) { + + logs, sub, err := _Uniswap.contract.WatchLogs(opts, "SetFeeProtocol") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(UniswapSetFeeProtocol) + if err := _Uniswap.contract.UnpackLog(event, "SetFeeProtocol", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSetFeeProtocol is a log parse operation binding the contract event 0x973d8d92bb299f4af6ce49b52a8adb85ae46b9f214c4c4fc06ac77401237b133. +// +// Solidity: event SetFeeProtocol(uint8 feeProtocol0Old, uint8 feeProtocol1Old, uint8 feeProtocol0New, uint8 feeProtocol1New) +func (_Uniswap *UniswapFilterer) ParseSetFeeProtocol(log types.Log) (*UniswapSetFeeProtocol, error) { + event := new(UniswapSetFeeProtocol) + if err := _Uniswap.contract.UnpackLog(event, "SetFeeProtocol", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// UniswapSwapIterator is returned from FilterSwap and is used to iterate over the raw logs and unpacked data for Swap events raised by the Uniswap contract. +type UniswapSwapIterator struct { + Event *UniswapSwap // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *UniswapSwapIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(UniswapSwap) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(UniswapSwap) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *UniswapSwapIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *UniswapSwapIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// UniswapSwap represents a Swap event raised by the Uniswap contract. +type UniswapSwap struct { + Sender common.Address + Recipient common.Address + Amount0 *big.Int + Amount1 *big.Int + SqrtPriceX96 *big.Int + Liquidity *big.Int + Tick *big.Int + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSwap is a free log retrieval operation binding the contract event 0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67. +// +// Solidity: event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick) +func (_Uniswap *UniswapFilterer) FilterSwap(opts *bind.FilterOpts, sender []common.Address, recipient []common.Address) (*UniswapSwapIterator, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _Uniswap.contract.FilterLogs(opts, "Swap", senderRule, recipientRule) + if err != nil { + return nil, err + } + return &UniswapSwapIterator{contract: _Uniswap.contract, event: "Swap", logs: logs, sub: sub}, nil +} + +// WatchSwap is a free log subscription operation binding the contract event 0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67. +// +// Solidity: event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick) +func (_Uniswap *UniswapFilterer) WatchSwap(opts *bind.WatchOpts, sink chan<- *UniswapSwap, sender []common.Address, recipient []common.Address) (event.Subscription, error) { + + var senderRule []interface{} + for _, senderItem := range sender { + senderRule = append(senderRule, senderItem) + } + var recipientRule []interface{} + for _, recipientItem := range recipient { + recipientRule = append(recipientRule, recipientItem) + } + + logs, sub, err := _Uniswap.contract.WatchLogs(opts, "Swap", senderRule, recipientRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(UniswapSwap) + if err := _Uniswap.contract.UnpackLog(event, "Swap", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSwap is a log parse operation binding the contract event 0xc42079f94a6350d7e6235f29174924f928cc2ac818eb64fed8004e115fbcca67. +// +// Solidity: event Swap(address indexed sender, address indexed recipient, int256 amount0, int256 amount1, uint160 sqrtPriceX96, uint128 liquidity, int24 tick) +func (_Uniswap *UniswapFilterer) ParseSwap(log types.Log) (*UniswapSwap, error) { + event := new(UniswapSwap) + if err := _Uniswap.contract.UnpackLog(event, "Swap", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/providers/apis/defi/uniswapv3/utils.go b/providers/apis/defi/uniswapv3/utils.go new file mode 100644 index 000000000..f150698bc --- /dev/null +++ b/providers/apis/defi/uniswapv3/utils.go @@ -0,0 +1,72 @@ +package uniswapv3 + +import ( + "encoding/json" + "fmt" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/skip-mev/slinky/oracle/config" +) + +const ( + // Name is the name of the Uniswap V3 API. + Name = "uniswapv3_api" + + // ContractMethod is the contract method to call for the Uniswap V3 API. + ContractMethod = "slot0" +) + +// PoolConfig is the configuration for a Uniswap V3 pool. This is specific to each pair of tokens. +type PoolConfig struct { + // Address is the Uniswap V3 pool address. + Address string `json:"address"` + // BaseDecimals is the number of decimals for the base token. This should be derived from the + // token contract. + BaseDecimals int64 `json:"base_decimals"` + // QuoteDecimals is the number of decimals for the quote token. This should be derived from the + // token contract. + QuoteDecimals int64 `json:"quote_decimals"` + // Invert is utilized to invert the price of a pool's reserves. This may be required for certain + // pools as the price is derived based on the sorted order of the ERC20 addresses of the tokens + // in the pool. + Invert bool `json:"invert"` +} + +// ValidateBasic validates the pool configuration. +func (pc *PoolConfig) ValidateBasic() error { + if !common.IsHexAddress(pc.Address) { + return fmt.Errorf("pool address is not a valid ethereum address") + } + + if pc.BaseDecimals <= 0 { + return fmt.Errorf("base decimals must be positive") + } + + if pc.QuoteDecimals <= 0 { + return fmt.Errorf("quote decimals must be positive") + } + + return nil +} + +// MustToJSON converts the pool configuration to JSON. +func (pc *PoolConfig) MustToJSON() string { + b, err := json.Marshal(pc) + if err != nil { + panic(err) + } + return string(b) +} + +// DefaultAPIConfig is the default configuration for the Uniswap API. +var DefaultAPIConfig = config.APIConfig{ + Name: Name, + Atomic: true, + Enabled: true, + Timeout: 1000 * time.Millisecond, + Interval: 2000 * time.Millisecond, + ReconnectTimeout: 2000 * time.Millisecond, + MaxQueries: 1, + URL: "https://eth.public-rpc.com/", +} diff --git a/providers/apis/defi/uniswapv3/utils_test.go b/providers/apis/defi/uniswapv3/utils_test.go new file mode 100644 index 000000000..677507f73 --- /dev/null +++ b/providers/apis/defi/uniswapv3/utils_test.go @@ -0,0 +1,48 @@ +package uniswapv3_test + +import ( + "testing" + + "github.com/skip-mev/slinky/providers/apis/defi/uniswapv3" + "github.com/stretchr/testify/require" +) + +func TestPoolConfig(t *testing.T) { + t.Run("empty config", func(t *testing.T) { + cfg := uniswapv3.PoolConfig{} + require.Error(t, cfg.ValidateBasic()) + }) + + t.Run("invalid address", func(t *testing.T) { + cfg := uniswapv3.PoolConfig{ + Address: "invalid", + } + require.Error(t, cfg.ValidateBasic()) + }) + + t.Run("invalid base decimals", func(t *testing.T) { + cfg := uniswapv3.PoolConfig{ + Address: "0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8", + BaseDecimals: 0, + } + require.Error(t, cfg.ValidateBasic()) + }) + + t.Run("invalid quote decimals", func(t *testing.T) { + cfg := uniswapv3.PoolConfig{ + Address: "0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8", + BaseDecimals: 18, + QuoteDecimals: 0, + } + require.Error(t, cfg.ValidateBasic()) + }) + + t.Run("valid config", func(t *testing.T) { + cfg := uniswapv3.PoolConfig{ + Address: "0x8ad599c3A0ff1De082011EFDDc58f1908eb6e6D8", + BaseDecimals: 18, + QuoteDecimals: 18, + } + require.NoError(t, cfg.ValidateBasic()) + }) +} diff --git a/providers/base/api/handlers/api_query_handler.go b/providers/base/api/handlers/api_query_handler.go index 4352b84e9..0c5f2981f 100644 --- a/providers/base/api/handlers/api_query_handler.go +++ b/providers/base/api/handlers/api_query_handler.go @@ -65,6 +65,26 @@ func NewAPIQueryHandler[K providertypes.ResponseKey, V providertypes.ResponseVal requestHandler RequestHandler, apiHandler APIDataHandler[K, V], metrics metrics.APIMetrics, +) (APIQueryHandler[K, V], error) { + fetcher, err := NewRestAPIFetcher(requestHandler, apiHandler, metrics, cfg, logger) + if err != nil { + return nil, fmt.Errorf("failed to create api fetcher: %w", err) + } + + return &APIQueryHandlerImpl[K, V]{ + logger: logger.With(zap.String("api_query_handler", cfg.Name)), + config: cfg, + metrics: metrics, + fetcher: fetcher, + }, nil +} + +// NewAPIQueryHandlerWithFetcher creates a new APIQueryHandler with a custom api fetcher. +func NewAPIQueryHandlerWithFetcher[K providertypes.ResponseKey, V providertypes.ResponseValue]( + logger *zap.Logger, + cfg config.APIConfig, + fetcher APIFetcher[K, V], + metrics metrics.APIMetrics, ) (APIQueryHandler[K, V], error) { if err := cfg.ValidateBasic(); err != nil { return nil, fmt.Errorf("invalid provider config: %w", err) @@ -82,9 +102,8 @@ func NewAPIQueryHandler[K providertypes.ResponseKey, V providertypes.ResponseVal return nil, fmt.Errorf("no metrics specified for api query handler") } - fetcher, err := NewRestAPIFetcher(requestHandler, apiHandler, metrics, cfg, logger) - if err != nil { - return nil, fmt.Errorf("failed to create api fetcher: %w", err) + if fetcher == nil { + return nil, fmt.Errorf("no fetcher specified for api query handler") } return &APIQueryHandlerImpl[K, V]{ @@ -213,9 +232,9 @@ func (h *APIQueryHandlerImpl[K, V]) writeResponse( // Update the metrics. for id := range response.Resolved { - h.metrics.AddProviderResponse(h.config.Name, strings.ToLower(id.String()), metrics.Success) + h.metrics.AddProviderResponse(h.config.Name, strings.ToLower(id.String()), providertypes.OK) } - for id, err := range response.UnResolved { - h.metrics.AddProviderResponse(h.config.Name, strings.ToLower(id.String()), metrics.StatusFromError(err)) + for id, unresolvedResult := range response.UnResolved { + h.metrics.AddProviderResponse(h.config.Name, strings.ToLower(id.String()), unresolvedResult.Code()) } } diff --git a/providers/base/api/handlers/api_query_handler_test.go b/providers/base/api/handlers/api_query_handler_test.go index c01dc4ad3..fb686a62d 100644 --- a/providers/base/api/handlers/api_query_handler_test.go +++ b/providers/base/api/handlers/api_query_handler_test.go @@ -121,7 +121,7 @@ func TestAPIQueryHandler(t *testing.T) { m.On("ObserveProviderResponseLatency", "handler1", mock.Anything).Maybe() m.On("AddHTTPStatusCode", "handler1", mock.Anything).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), metrics.Success).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), providertypes.OK).Maybe() return m }, @@ -171,7 +171,7 @@ func TestAPIQueryHandler(t *testing.T) { m.On("ObserveProviderResponseLatency", "handler1", mock.Anything).Maybe() m.On("AddHTTPStatusCode", "handler1", mock.Anything).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), metrics.Success).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), providertypes.OK).Maybe() return m }, @@ -207,7 +207,7 @@ func TestAPIQueryHandler(t *testing.T) { m.On("ObserveProviderResponseLatency", "handler1", mock.Anything).Maybe() m.On("AddHTTPStatusCode", "handler1", mock.Anything).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), mock.Anything).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), providertypes.ErrorRateLimitExceeded).Maybe() return m }, ids: []slinkytypes.CurrencyPair{btcusd}, @@ -278,7 +278,7 @@ func TestAPIQueryHandler(t *testing.T) { m.On("ObserveProviderResponseLatency", "handler1", mock.Anything).Maybe() m.On("AddHTTPStatusCode", "handler1", mock.Anything).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), mock.Anything).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), providertypes.ErrorUnknown).Maybe() return m }, @@ -334,9 +334,9 @@ func TestAPIQueryHandler(t *testing.T) { m.On("ObserveProviderResponseLatency", "handler1", mock.Anything).Maybe() m.On("AddHTTPStatusCode", "handler1", mock.Anything).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), metrics.Success).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(ethusd)), metrics.Success).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(atomusd)), metrics.Success).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), providertypes.OK).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(ethusd)), providertypes.OK).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(atomusd)), providertypes.OK).Maybe() return m }, @@ -414,9 +414,9 @@ func TestAPIQueryHandler(t *testing.T) { m.On("ObserveProviderResponseLatency", "handler1", mock.Anything).Maybe() m.On("AddHTTPStatusCode", "handler1", mock.Anything).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), metrics.Success).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(ethusd)), metrics.Success).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(atomusd)), metrics.Success).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), providertypes.OK).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(ethusd)), providertypes.OK).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(atomusd)), providertypes.OK).Maybe() return m }, @@ -484,9 +484,9 @@ func TestAPIQueryHandler(t *testing.T) { m.On("ObserveProviderResponseLatency", "handler1", mock.Anything).Maybe() m.On("AddHTTPStatusCode", "handler1", mock.Anything).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), metrics.Success).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(ethusd)), metrics.Unknown).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(atomusd)), metrics.Success).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), providertypes.OK).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(ethusd)), providertypes.ErrorRateLimitExceeded).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(atomusd)), providertypes.OK).Maybe() return m }, @@ -566,9 +566,9 @@ func TestAPIQueryHandler(t *testing.T) { m.On("ObserveProviderResponseLatency", "handler1", mock.Anything).Maybe() m.On("AddHTTPStatusCode", "handler1", mock.Anything).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), metrics.Success).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(ethusd)), metrics.Success).Maybe() - m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(atomusd)), metrics.Success).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(btcusd)), providertypes.OK).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(ethusd)), providertypes.OK).Maybe() + m.On("AddProviderResponse", "handler1", strings.ToLower(fmt.Sprint(atomusd)), providertypes.OK).Maybe() return m }, diff --git a/providers/base/api/handlers/mocks/api_data_handler.go b/providers/base/api/handlers/mocks/api_data_handler.go index ad9d1f973..316a6cc91 100644 --- a/providers/base/api/handlers/mocks/api_data_handler.go +++ b/providers/base/api/handlers/mocks/api_data_handler.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.30.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks @@ -19,6 +19,10 @@ type APIDataHandler[K types.ResponseKey, V types.ResponseValue] struct { func (_m *APIDataHandler[K, V]) CreateURL(ids []K) (string, error) { ret := _m.Called(ids) + if len(ret) == 0 { + panic("no return value specified for CreateURL") + } + var r0 string var r1 error if rf, ok := ret.Get(0).(func([]K) (string, error)); ok { @@ -43,6 +47,10 @@ func (_m *APIDataHandler[K, V]) CreateURL(ids []K) (string, error) { func (_m *APIDataHandler[K, V]) ParseResponse(ids []K, response *http.Response) types.GetResponse[K, V] { ret := _m.Called(ids, response) + if len(ret) == 0 { + panic("no return value specified for ParseResponse") + } + var r0 types.GetResponse[K, V] if rf, ok := ret.Get(0).(func([]K, *http.Response) types.GetResponse[K, V]); ok { r0 = rf(ids, response) diff --git a/providers/base/api/handlers/mocks/api_query_handler.go b/providers/base/api/handlers/mocks/api_query_handler.go index 6262c5936..5a053960c 100644 --- a/providers/base/api/handlers/mocks/api_query_handler.go +++ b/providers/base/api/handlers/mocks/api_query_handler.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.30.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/providers/base/api/handlers/mocks/request_handler.go b/providers/base/api/handlers/mocks/request_handler.go index ae80c2bb6..1a2e08217 100644 --- a/providers/base/api/handlers/mocks/request_handler.go +++ b/providers/base/api/handlers/mocks/request_handler.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.30.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks @@ -19,6 +19,10 @@ type RequestHandler struct { func (_m *RequestHandler) Do(ctx context.Context, url string) (*http.Response, error) { ret := _m.Called(ctx, url) + if len(ret) == 0 { + panic("no return value specified for Do") + } + var r0 *http.Response var r1 error if rf, ok := ret.Get(0).(func(context.Context, string) (*http.Response, error)); ok { @@ -45,6 +49,10 @@ func (_m *RequestHandler) Do(ctx context.Context, url string) (*http.Response, e func (_m *RequestHandler) Type() string { ret := _m.Called() + if len(ret) == 0 { + panic("no return value specified for Type") + } + var r0 string if rf, ok := ret.Get(0).(func() string); ok { r0 = rf() diff --git a/providers/base/api/metrics/api_query_handler.go b/providers/base/api/metrics/api_query_handler.go index e805e6102..88d19892a 100644 --- a/providers/base/api/metrics/api_query_handler.go +++ b/providers/base/api/metrics/api_query_handler.go @@ -9,6 +9,7 @@ import ( "github.com/skip-mev/slinky/oracle/config" oraclemetrics "github.com/skip-mev/slinky/oracle/metrics" providermetrics "github.com/skip-mev/slinky/providers/base/metrics" + providertypes "github.com/skip-mev/slinky/providers/types" ) const ( @@ -26,7 +27,7 @@ const ( type APIMetrics interface { // AddProviderResponse increments the number of ticks with a fully successful provider update. // This increments the number of responses by provider, id (i.e. currency pair), and status. - AddProviderResponse(providerName, id string, status Status) + AddProviderResponse(providerName, id string, errorCode providertypes.ErrorCode) // AddHTTPStatusCode increments the number of responses by provider and status. // This is used to track the number of responses by provider and status. @@ -94,16 +95,23 @@ func NewNopAPIMetrics() APIMetrics { return &noOpAPIMetricsImpl{} } -func (m *noOpAPIMetricsImpl) AddProviderResponse(_ string, _ string, _ Status) {} -func (m *noOpAPIMetricsImpl) AddHTTPStatusCode(_ string, _ *http.Response) {} -func (m *noOpAPIMetricsImpl) ObserveProviderResponseLatency(_ string, _ time.Duration) {} +func (m *noOpAPIMetricsImpl) AddProviderResponse(_ string, _ string, _ providertypes.ErrorCode) {} +func (m *noOpAPIMetricsImpl) AddHTTPStatusCode(_ string, _ *http.Response) {} +func (m *noOpAPIMetricsImpl) ObserveProviderResponseLatency(_ string, _ time.Duration) {} // AddProviderResponse increments the number of requests by provider and status. -func (m *APIMetricsImpl) AddProviderResponse(providerName string, id string, status Status) { +func (m *APIMetricsImpl) AddProviderResponse(providerName string, id string, err providertypes.ErrorCode) { + var status string + if err.Error() == nil { + status = "success" + } else { + status = err.Error().Error() + } + m.apiResponseStatusPerProvider.With(prometheus.Labels{ providermetrics.ProviderLabel: providerName, providermetrics.IDLabel: id, - StatusLabel: status.String(), + StatusLabel: status, }, ).Add(1) } diff --git a/providers/base/api/metrics/api_utils.go b/providers/base/api/metrics/api_utils.go deleted file mode 100644 index 3e624ad0a..000000000 --- a/providers/base/api/metrics/api_utils.go +++ /dev/null @@ -1,68 +0,0 @@ -package metrics - -import ( - "errors" - - providererrors "github.com/skip-mev/slinky/providers/base/api/errors" -) - -const ( - // CreateURL indicates that the provider could not construct a valid url to query. - CreateURL Status = iota - // DoRequest indicates that the request handler could not make the request. - DoRequest - // ParseResponse indicates that the provider could not parse the response. - ParseResponse - // RateLimit indicates that the request handler encountered a rate limit. - RateLimit - // UnexpectedStatusCode indicates that the request handler encountered an unexpected - // status code. - UnexpectedStatusCode - // Success indicates that the provider successfully queried the data. - Success - // Unknown indicates that the provider encountered an unknown error. - Unknown -) - -// Status is a type that represents the status of a provider response. -type Status int - -// String returns a string representation of the status. -func (s Status) String() string { - switch s { - case CreateURL: - return "create_url_err" - case DoRequest: - return "request_err" - case ParseResponse: - return "parse_response_err" - case RateLimit: - return "rate_limit_err" - case UnexpectedStatusCode: - return "unexpected_status_code_err" - case Success: - return "success" - default: - return "unknown_err" - } -} - -// StatusFromError returns a Status based on the error. If the error is nil, StatusSuccess is returned. -func StatusFromError(err error) Status { - switch { - case err == nil: - return Success - case errors.Is(err, providererrors.ErrCreateURL): - return CreateURL - case errors.Is(err, providererrors.ErrDoRequest): - return DoRequest - case errors.Is(err, providererrors.ErrParseResponse): - return ParseResponse - case errors.Is(err, providererrors.ErrRateLimit): - return RateLimit - case errors.Is(err, providererrors.ErrUnexpectedStatusCode): - return UnexpectedStatusCode - default: - return Unknown - } -} diff --git a/providers/base/api/metrics/mocks/mock_metrics.go b/providers/base/api/metrics/mocks/mock_metrics.go index 028016a50..2d71d4ad2 100644 --- a/providers/base/api/metrics/mocks/mock_metrics.go +++ b/providers/base/api/metrics/mocks/mock_metrics.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.30.1. DO NOT EDIT. +// Code generated by mockery v2.40.1. DO NOT EDIT. package mocks @@ -7,9 +7,9 @@ import ( mock "github.com/stretchr/testify/mock" - metrics "github.com/skip-mev/slinky/providers/base/api/metrics" - time "time" + + types "github.com/skip-mev/slinky/providers/types" ) // APIMetrics is an autogenerated mock type for the APIMetrics type @@ -23,7 +23,7 @@ func (_m *APIMetrics) AddHTTPStatusCode(providerName string, resp *http.Response } // AddProviderResponse provides a mock function with given fields: providerName, id, status -func (_m *APIMetrics) AddProviderResponse(providerName string, id string, status metrics.Status) { +func (_m *APIMetrics) AddProviderResponse(providerName string, id string, status types.ErrorCode) { _m.Called(providerName, id, status) } diff --git a/providers/base/metrics/mocks/mock_metrics.go b/providers/base/metrics/mocks/mock_metrics.go index 5f9aaf66e..896966004 100644 --- a/providers/base/metrics/mocks/mock_metrics.go +++ b/providers/base/metrics/mocks/mock_metrics.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/providers/base/websocket/handlers/mocks/web_socket_conn_handler.go b/providers/base/websocket/handlers/mocks/web_socket_conn_handler.go index b4acc0921..01073656f 100644 --- a/providers/base/websocket/handlers/mocks/web_socket_conn_handler.go +++ b/providers/base/websocket/handlers/mocks/web_socket_conn_handler.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/providers/base/websocket/handlers/mocks/web_socket_data_handler.go b/providers/base/websocket/handlers/mocks/web_socket_data_handler.go index fc78cc8b7..c7fadf5d8 100644 --- a/providers/base/websocket/handlers/mocks/web_socket_data_handler.go +++ b/providers/base/websocket/handlers/mocks/web_socket_data_handler.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/providers/base/websocket/handlers/mocks/web_socket_query_handler.go b/providers/base/websocket/handlers/mocks/web_socket_query_handler.go index 7cc019043..65b6759ef 100644 --- a/providers/base/websocket/handlers/mocks/web_socket_query_handler.go +++ b/providers/base/websocket/handlers/mocks/web_socket_query_handler.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/providers/base/websocket/metrics/mocks/mock_metrics.go b/providers/base/websocket/metrics/mocks/mock_metrics.go index be1b62c41..c6e1167b0 100644 --- a/providers/base/websocket/metrics/mocks/mock_metrics.go +++ b/providers/base/websocket/metrics/mocks/mock_metrics.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/providers/factories/oracle/api.go b/providers/factories/oracle/api.go index 119d95b73..7debc10b6 100644 --- a/providers/factories/oracle/api.go +++ b/providers/factories/oracle/api.go @@ -4,6 +4,8 @@ import ( "fmt" "net/http" + "github.com/skip-mev/slinky/providers/apis/defi/raydium" + "go.uber.org/zap" "github.com/skip-mev/slinky/oracle/config" @@ -12,6 +14,7 @@ import ( "github.com/skip-mev/slinky/providers/apis/binance" coinbaseapi "github.com/skip-mev/slinky/providers/apis/coinbase" "github.com/skip-mev/slinky/providers/apis/coingecko" + "github.com/skip-mev/slinky/providers/apis/defi/uniswapv3" "github.com/skip-mev/slinky/providers/apis/geckoterminal" "github.com/skip-mev/slinky/providers/apis/kraken" apihandlers "github.com/skip-mev/slinky/providers/base/api/handlers" @@ -46,10 +49,15 @@ func APIQueryHandlerFactory( } var ( - apiDataHandler types.PriceAPIDataHandler - requestHandler apihandlers.RequestHandler + apiPriceFetcher types.PriceAPIFetcher + apiDataHandler types.PriceAPIDataHandler ) + requestHandler, err := apihandlers.NewRequestHandlerImpl(client) + if err != nil { + return nil, err + } + switch cfg.Name { case binance.Name: apiDataHandler, err = binance.NewAPIHandler(marketMap, cfg.API) @@ -61,6 +69,14 @@ func APIQueryHandlerFactory( apiDataHandler, err = geckoterminal.NewAPIHandler(marketMap, cfg.API) case kraken.Name: apiDataHandler, err = kraken.NewAPIHandler(marketMap, cfg.API) + case uniswapv3.Name: + var ethClient uniswapv3.EVMClient + ethClient, err = uniswapv3.NewGoEthereumClientImpl(cfg.API.URL) + if err != nil { + return nil, err + } + + apiPriceFetcher, err = uniswapv3.NewPriceFetcher(logger, metrics, cfg.API, ethClient) case static.Name: apiDataHandler, err = static.NewAPIHandler(marketMap) if err != nil { @@ -75,6 +91,15 @@ func APIQueryHandlerFactory( } requestHandler = static.NewStaticMockClient() + case raydium.Name: + apiPriceFetcher, err = raydium.NewAPIPriceFetcher( + marketMap, + cfg.API, + logger, + ) + if err != nil { + return nil, err + } default: return nil, fmt.Errorf("unknown provider: %s", cfg.Name) } @@ -82,20 +107,25 @@ func APIQueryHandlerFactory( return nil, err } - // If a custom request handler is not provided, create a new default one. - if requestHandler == nil { - requestHandler, err = apihandlers.NewRequestHandlerImpl(client) + // if no apiPriceFetcher has been created yet, create a default REST API price fetcher. + if apiPriceFetcher == nil { + apiPriceFetcher, err = apihandlers.NewRestAPIFetcher( + requestHandler, + apiDataHandler, + metrics, + cfg.API, + logger, + ) if err != nil { return nil, err } } // Create the API query handler which encapsulates all of the fetching and parsing logic. - return types.NewPriceAPIQueryHandler( + return types.NewPriceAPIQueryHandlerWithFetcher( logger, cfg.API, - requestHandler, - apiDataHandler, + apiPriceFetcher, metrics, ) } diff --git a/providers/types/mocks/mock_provider.go b/providers/types/mocks/mock_provider.go index e62ab58bc..5d1bf67c8 100644 --- a/providers/types/mocks/mock_provider.go +++ b/providers/types/mocks/mock_provider.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/service/clients/oracle/client.go b/service/clients/oracle/client.go index 855d67a47..46cbfba84 100644 --- a/service/clients/oracle/client.go +++ b/service/clients/oracle/client.go @@ -8,6 +8,7 @@ import ( "cosmossdk.io/log" "google.golang.org/grpc" + "google.golang.org/grpc/connectivity" "google.golang.org/grpc/credentials/insecure" "github.com/skip-mev/slinky/oracle/config" @@ -111,10 +112,6 @@ func (c *GRPCClient) Start(ctx context.Context) error { grpc.WithTransportCredentials(insecure.NewCredentials()), } - if c.blockingDial { - opts = append(opts, grpc.WithBlock()) - } - // dial the client, but defer to context closure, if necessary var ( conn *grpc.ClientConn @@ -123,7 +120,17 @@ func (c *GRPCClient) Start(ctx context.Context) error { ) go func() { defer close(done) - conn, err = grpc.DialContext(ctx, c.addr, opts...) + conn, err = grpc.NewClient(c.addr, opts...) + + // attempt to connect + wait for change in connection state + if c.blockingDial { + // connect + conn.Connect() + + if err == nil { + conn.WaitForStateChange(ctx, connectivity.Ready) + } + } }() // wait for either the context to close or the dial to complete diff --git a/service/clients/oracle/mocks/mock_oracle_client.go b/service/clients/oracle/mocks/mock_oracle_client.go index 08f3dc3ea..1a209f464 100644 --- a/service/clients/oracle/mocks/mock_oracle_client.go +++ b/service/clients/oracle/mocks/mock_oracle_client.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/service/metrics/mocks/mock_metrics.go b/service/metrics/mocks/mock_metrics.go index b0d82ae65..bb05ec837 100644 --- a/service/metrics/mocks/mock_metrics.go +++ b/service/metrics/mocks/mock_metrics.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/service/servers/oracle/mocks/mock_oracle_service.go b/service/servers/oracle/mocks/mock_oracle_service.go index b26440ff5..9f4649701 100644 --- a/service/servers/oracle/mocks/mock_oracle_service.go +++ b/service/servers/oracle/mocks/mock_oracle_service.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/tests/integration/go.mod b/tests/integration/go.mod index cccc2928b..16766f9a0 100644 --- a/tests/integration/go.mod +++ b/tests/integration/go.mod @@ -102,7 +102,7 @@ require ( github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.4 // indirect + github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/orderedcode v0.0.1 // indirect diff --git a/tests/integration/go.sum b/tests/integration/go.sum index acaf04376..adaec2d23 100644 --- a/tests/integration/go.sum +++ b/tests/integration/go.sum @@ -550,8 +550,9 @@ 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/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= +github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= diff --git a/tests/integration/slinky_setup.go b/tests/integration/slinky_setup.go index 8cd5463ed..876372334 100644 --- a/tests/integration/slinky_setup.go +++ b/tests/integration/slinky_setup.go @@ -362,7 +362,7 @@ func (s *SlinkyIntegrationSuite) AddCurrencyPairs(chain *cosmos.CosmosChain, aut }, }, Paths: mmtypes.Paths{Paths: []mmtypes.Path{ - mmtypes.Path{Operations: []mmtypes.Operation{ + {Operations: []mmtypes.Operation{ { CurrencyPair: cp, Invert: false, diff --git a/tests/integration/slinky_slashing_setup.go b/tests/integration/slinky_slashing_setup.go index 391f3fe2b..e061f10c3 100644 --- a/tests/integration/slinky_slashing_setup.go +++ b/tests/integration/slinky_slashing_setup.go @@ -198,15 +198,18 @@ func UpdateNodePrices(node *cosmos.ChainNode, ticker mmtypes.Ticker, price int64 }, }, Paths: map[string]mmtypes.Paths{ - ticker.String(): {Paths: []mmtypes.Path{ - {Operations: []mmtypes.Operation{ - { - CurrencyPair: ticker.CurrencyPair, - Invert: false, - Provider: static.Name, - }, - }}}, - }}, + ticker.String(): { + Paths: []mmtypes.Path{ + {Operations: []mmtypes.Operation{ + { + CurrencyPair: ticker.CurrencyPair, + Invert: false, + Provider: static.Name, + }, + }}, + }, + }, + }, } oracle := GetOracleSideCar(node) diff --git a/tests/petri/go.mod b/tests/petri/go.mod index d77fc68fb..ee5fe0894 100644 --- a/tests/petri/go.mod +++ b/tests/petri/go.mod @@ -1,34 +1,35 @@ module github.com/skip-mev/slinky/tests/petri go 1.21.6 +toolchain go1.22.1 require ( - github.com/cosmos/cosmos-sdk v0.50.3 + github.com/cosmos/cosmos-sdk v0.50.5 github.com/skip-mev/petri/chain/v2 v2.0.1 github.com/skip-mev/petri/node/v2 v2.0.1 github.com/skip-mev/petri/provider/v2 v2.0.0 github.com/skip-mev/petri/types/v2 v2.0.1 - github.com/skip-mev/slinky v0.1.0 - github.com/stretchr/testify v1.8.4 - go.uber.org/zap v1.26.0 + github.com/skip-mev/slinky v0.3.1 + github.com/stretchr/testify v1.9.0 + go.uber.org/zap v1.27.0 ) require ( - cloud.google.com/go v0.110.10 // indirect - cloud.google.com/go/compute v1.23.3 // indirect + cloud.google.com/go v0.112.0 // indirect + cloud.google.com/go/compute v1.24.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect - cloud.google.com/go/iam v1.1.5 // indirect - cloud.google.com/go/storage v1.35.1 // indirect - cosmossdk.io/api v0.7.2 // indirect + cloud.google.com/go/iam v1.1.6 // indirect + cloud.google.com/go/storage v1.36.0 // indirect + cosmossdk.io/api v0.7.3 // indirect cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/core v0.11.0 // indirect cosmossdk.io/depinject v1.0.0-alpha.4 // indirect cosmossdk.io/errors v1.0.1 // indirect - cosmossdk.io/log v1.3.0 // indirect - cosmossdk.io/math v1.2.0 // indirect + cosmossdk.io/log v1.3.1 // indirect + cosmossdk.io/math v1.3.0 // indirect cosmossdk.io/store v1.0.2 // indirect - cosmossdk.io/x/circuit v0.0.0-20230726190121-58855c685902 // indirect - cosmossdk.io/x/tx v0.13.0 // indirect + cosmossdk.io/x/circuit v0.1.0 // indirect + cosmossdk.io/x/tx v0.13.1 // indirect cosmossdk.io/x/upgrade v0.1.1 // indirect filippo.io/edwards25519 v1.0.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -49,18 +50,18 @@ require ( github.com/cockroachdb/apd/v2 v2.0.2 // indirect github.com/cockroachdb/errors v1.11.1 // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v0.0.0-20231101195458-481da04154d6 // indirect + github.com/cockroachdb/pebble v1.1.0 // indirect github.com/cockroachdb/redact v1.1.5 // indirect github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect - github.com/cometbft/cometbft v0.38.5 // indirect + github.com/cometbft/cometbft v0.38.6 // indirect github.com/cometbft/cometbft-db v0.9.1 // indirect github.com/cosmos/btcutil v1.0.5 // indirect - github.com/cosmos/cosmos-db v1.0.0 // indirect - github.com/cosmos/cosmos-proto v1.0.0-beta.3 // indirect + github.com/cosmos/cosmos-db v1.0.2 // indirect + github.com/cosmos/cosmos-proto v1.0.0-beta.4 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect github.com/cosmos/gogogateway v1.2.0 // indirect - github.com/cosmos/gogoproto v1.4.11 // indirect - github.com/cosmos/iavl v1.0.0 // indirect + github.com/cosmos/gogoproto v1.4.12 // indirect + github.com/cosmos/iavl v1.0.1 // indirect github.com/cosmos/ics23/go v0.10.0 // indirect github.com/cosmos/ledger-cosmos-go v0.13.3 // indirect github.com/danieljoos/wincred v1.1.2 // indirect @@ -72,32 +73,34 @@ require ( github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13 // indirect github.com/distribution/reference v0.5.0 // indirect github.com/docker/distribution v2.8.3+incompatible // indirect - github.com/docker/docker v24.0.7+incompatible // indirect + github.com/docker/docker v24.0.9+incompatible // indirect github.com/docker/go-connections v0.4.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/dvsekhvalnov/jose2go v1.6.0 // indirect - github.com/emicklei/dot v1.6.0 // indirect - github.com/fatih/color v1.15.0 // indirect - github.com/felixge/httpsnoop v1.0.2 // indirect + github.com/emicklei/dot v1.6.1 // indirect + github.com/fatih/color v1.16.0 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/getsentry/sentry-go v0.25.0 // indirect + github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-kit/kit v0.13.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/stdr v1.2.2 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/mock v1.6.0 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/google/s2a-go v0.1.7 // indirect - github.com/google/uuid v1.4.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect github.com/gorilla/handlers v1.5.1 // indirect @@ -125,17 +128,16 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmhodges/levigo v1.0.0 // indirect - github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/compress v1.17.7 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/lib/pq v1.10.9 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect - github.com/linxGnu/grocksdb v1.8.6 // indirect + github.com/linxGnu/grocksdb v1.8.12 // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/manifoldco/promptui v0.9.0 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect github.com/minio/highwayhash v1.0.2 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect @@ -145,18 +147,18 @@ require ( github.com/oklog/run v1.1.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.0-rc2 // indirect - github.com/pelletier/go-toml/v2 v2.1.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.0 // indirect github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.18.0 // indirect - github.com/prometheus/client_model v0.5.0 // indirect - github.com/prometheus/common v0.45.0 // indirect + github.com/prometheus/client_model v0.6.0 // indirect + github.com/prometheus/common v0.47.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/rs/cors v1.8.3 // indirect - github.com/rs/zerolog v1.31.0 // indirect + github.com/rs/zerolog v1.32.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sasha-s/go-deadlock v0.3.1 // indirect @@ -177,31 +179,34 @@ require ( github.com/zondax/ledger-go v0.14.3 // indirect go.etcd.io/bbolt v1.3.8 // indirect go.opencensus.io v0.24.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 // indirect + go.opentelemetry.io/otel v1.22.0 // indirect + go.opentelemetry.io/otel/metric v1.22.0 // indirect + go.opentelemetry.io/otel/trace v1.22.0 // indirect go.uber.org/multierr v1.10.0 // indirect - golang.org/x/crypto v0.18.0 // indirect - golang.org/x/exp v0.0.0-20231006140011-7918f672742d // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.20.0 // indirect - golang.org/x/oauth2 v0.15.0 // indirect - golang.org/x/sync v0.5.0 // indirect - golang.org/x/sys v0.16.0 // indirect - golang.org/x/term v0.16.0 // indirect + golang.org/x/crypto v0.21.0 // indirect + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect + golang.org/x/mod v0.16.0 // indirect + golang.org/x/net v0.22.0 // indirect + golang.org/x/oauth2 v0.16.0 // indirect + golang.org/x/sync v0.6.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.16.1 // indirect - golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect - google.golang.org/api v0.153.0 // indirect + golang.org/x/tools v0.19.0 // indirect + google.golang.org/api v0.162.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 // indirect - google.golang.org/grpc v1.60.1 // indirect - google.golang.org/protobuf v1.32.0 // indirect + google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641 // indirect + google.golang.org/grpc v1.62.1 // indirect + google.golang.org/protobuf v1.33.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect nhooyr.io/websocket v1.8.6 // indirect pgregory.net/rapid v1.1.0 // indirect - sigs.k8s.io/yaml v1.3.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect ) diff --git a/tests/petri/go.sum b/tests/petri/go.sum index a2b6aa3bd..a0254626f 100644 --- a/tests/petri/go.sum +++ b/tests/petri/go.sum @@ -30,8 +30,8 @@ cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w9 cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= -cloud.google.com/go v0.110.10 h1:LXy9GEO+timppncPIAZoOj3l58LIU9k+kn48AN7IO3Y= -cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic= +cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= +cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= cloud.google.com/go/aiplatform v1.22.0/go.mod h1:ig5Nct50bZlzV6NvKaTwmplLLddFx0YReh9WfTO5jKw= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= cloud.google.com/go/analytics v0.11.0/go.mod h1:DjEWCu41bVbYcKyvlws9Er60YE4a//bK6mnhWvQeFNI= @@ -68,8 +68,8 @@ cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= -cloud.google.com/go/compute v1.23.3 h1:6sVlXXBmbd7jNX0Ipq0trII3e4n1/MsADLK6a+aiVlk= -cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/containeranalysis v0.5.1/go.mod h1:1D92jd8gRR/c0fGMlymRgxWD3Qw9C1ff6/T7mLgVL8I= @@ -109,8 +109,8 @@ cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y97 cloud.google.com/go/grafeas v0.2.0/go.mod h1:KhxgtF2hb0P191HlY5besjYm6MqTSTj3LSI+M+ByZHc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/iam v1.1.5 h1:1jTsCu4bcsNsE4iiqNT5SHwrDRCfRmIaaaVFhRveTJI= -cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8= +cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= +cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= cloud.google.com/go/lifesciences v0.5.0/go.mod h1:3oIKy8ycWGPUyZDR/8RNnTOYevhaMLqh5vLUXs9zvT8= @@ -171,8 +171,8 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= -cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w= -cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= +cloud.google.com/go/storage v1.36.0 h1:P0mOkAcaJxhCTvAkMhxMfrTKiNcub4YmmPBtlhAyTr8= +cloud.google.com/go/storage v1.36.0/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= cloud.google.com/go/talent v1.1.0/go.mod h1:Vl4pt9jiHKvOgF9KoZo6Kob9oV4lwd/ZD5Cto54zDRw= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= cloud.google.com/go/videointelligence v1.6.0/go.mod h1:w0DIDlVRKtwPCn/C4iwZIJdvC69yInhW0cfi+p546uU= @@ -184,8 +184,8 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cosmossdk.io/api v0.7.2 h1:BO3i5fvKMKvfaUiMkCznxViuBEfyWA/k6w2eAF6q1C4= -cosmossdk.io/api v0.7.2/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= +cosmossdk.io/api v0.7.3 h1:V815i8YOwOAQa1rLCsSMjVG5Gnzs02JLq+l7ks8s1jk= +cosmossdk.io/api v0.7.3/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo= @@ -194,16 +194,16 @@ cosmossdk.io/depinject v1.0.0-alpha.4 h1:PLNp8ZYAMPTUKyG9IK2hsbciDWqna2z1Wsl98ok cosmossdk.io/depinject v1.0.0-alpha.4/go.mod h1:HeDk7IkR5ckZ3lMGs/o91AVUc7E596vMaOmslGFM3yU= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= cosmossdk.io/errors v1.0.1/go.mod h1:MeelVSZThMi4bEakzhhhE/CKqVv3nOJDA25bIqRDu/U= -cosmossdk.io/log v1.3.0 h1:L0Z0XstClo2kOU4h3V1iDoE5Ji64sg5HLOogzGg67Oo= -cosmossdk.io/log v1.3.0/go.mod h1:HIDyvWLqZe2ovlWabsDN4aPMpY/nUEquAhgfTf2ZzB8= -cosmossdk.io/math v1.2.0 h1:8gudhTkkD3NxOP2YyyJIYYmt6dQ55ZfJkDOaxXpy7Ig= -cosmossdk.io/math v1.2.0/go.mod h1:l2Gnda87F0su8a/7FEKJfFdJrM0JZRXQaohlgJeyQh0= +cosmossdk.io/log v1.3.1 h1:UZx8nWIkfbbNEWusZqzAx3ZGvu54TZacWib3EzUYmGI= +cosmossdk.io/log v1.3.1/go.mod h1:2/dIomt8mKdk6vl3OWJcPk2be3pGOS8OQaLUM/3/tCM= +cosmossdk.io/math v1.3.0 h1:RC+jryuKeytIiictDslBP9i1fhkVm6ZDmZEoNP316zE= +cosmossdk.io/math v1.3.0/go.mod h1:vnRTxewy+M7BtXBNFybkuhSH4WfedVAAnERHgVFhp3k= cosmossdk.io/store v1.0.2 h1:lSg5BTvJBHUDwswNNyeh4K/CbqiHER73VU4nDNb8uk0= cosmossdk.io/store v1.0.2/go.mod h1:EFtENTqVTuWwitGW1VwaBct+yDagk7oG/axBMPH+FXs= -cosmossdk.io/x/circuit v0.0.0-20230726190121-58855c685902 h1:vYHGkdQrkFHXJXNwYKLvt7PtgAt6by7gAzUtlwQ//os= -cosmossdk.io/x/circuit v0.0.0-20230726190121-58855c685902/go.mod h1:9j92Murx9xkeeQZl+nkI6iVT+h9/GHg/MqMzHqHLKhc= -cosmossdk.io/x/tx v0.13.0 h1:8lzyOh3zONPpZv2uTcUmsv0WTXy6T1/aCVDCqShmpzU= -cosmossdk.io/x/tx v0.13.0/go.mod h1:CpNQtmoqbXa33/DVxWQNx5Dcnbkv2xGUhL7tYQ5wUsY= +cosmossdk.io/x/circuit v0.1.0 h1:IAej8aRYeuOMritczqTlljbUVHq1E85CpBqaCTwYgXs= +cosmossdk.io/x/circuit v0.1.0/go.mod h1:YDzblVE8+E+urPYQq5kq5foRY/IzhXovSYXb4nwd39w= +cosmossdk.io/x/tx v0.13.1 h1:Mg+EMp67Pz+NukbJqYxuo8uRp7N/a9uR+oVS9pONtj8= +cosmossdk.io/x/tx v0.13.1/go.mod h1:CBCU6fsRVz23QGFIQBb1DNX2DztJCf3jWyEkHY2nJQ0= cosmossdk.io/x/upgrade v0.1.1 h1:aoPe2gNvH+Gwt/Pgq3dOxxQVU3j5P6Xf+DaUJTDZATc= cosmossdk.io/x/upgrade v0.1.1/go.mod h1:MNLptLPcIFK9CWt7Ra//8WUZAxweyRDNcbs5nkOcQy0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -235,10 +235,6 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/ github.com/adlio/schema v1.3.3 h1:oBJn8I02PyTB466pZO1UZEn1TV5XLlifBSyMrmHl/1I= github.com/adlio/schema v1.3.3/go.mod h1:1EsRssiv9/Ce2CMzq5DoL7RiMshhuigQxrR4DMV9fHg= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/alecthomas/assert/v2 v2.4.1 h1:mwPZod/d35nlaCppr6sFP0rbCL05WH9fIo7lvsf47zo= -github.com/alecthomas/assert/v2 v2.4.1/go.mod h1:fw5suVxB+wfYJ3291t0hRTqtGzFYdSwstnRQdaQx2DM= -github.com/alecthomas/repr v0.3.0 h1:NeYzUPfjjlqHY4KtzgKJiWd6sVq2eNUPTi34PiFGjY8= -github.com/alecthomas/repr v0.3.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= 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= @@ -313,6 +309,8 @@ github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa h1:jQCWAUqqlij9Pgj2i/PB79y4KOPYVyFYdROxgaCwdTQ= +github.com/cncf/xds/go v0.0.0-20231128003011-0fa0005c9caa/go.mod h1:x/1Gn8zydmfq8dk6e9PdstVsDgu9RuyIIJqAaF//0IM= github.com/cockroachdb/apd/v2 v2.0.2 h1:weh8u7Cneje73dDh+2tEVLUvyBc89iwepWCD8b8034E= github.com/cockroachdb/apd/v2 v2.0.2/go.mod h1:DDxRlzC2lo3/vSlmSoS7JkqbbrARPuFOGr0B9pvN3Gw= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -322,15 +320,15 @@ github.com/cockroachdb/errors v1.11.1 h1:xSEW75zKaKCWzR3OfxXUxgrk/NtT4G1MiOv5lWZ github.com/cockroachdb/errors v1.11.1/go.mod h1:8MUxA3Gi6b25tYlFEBGLf+D8aISL+M4MIpiWMSNRfxw= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= -github.com/cockroachdb/pebble v0.0.0-20231101195458-481da04154d6 h1:g+Y6IAf28JinY3zNdXwpw71SBGhLEb72kGQgiR5XKZM= -github.com/cockroachdb/pebble v0.0.0-20231101195458-481da04154d6/go.mod h1:acMRUGd/BK8AUmQNK3spUCCGzFLZU2bSST3NMXSq2Kc= +github.com/cockroachdb/pebble v1.1.0 h1:pcFh8CdCIt2kmEpK0OIatq67Ln9uGDYY3d5XnE0LJG4= +github.com/cockroachdb/pebble v1.1.0/go.mod h1:sEHm5NOXxyiAoKWhoFxT8xMgd/f3RA6qUqQ1BXKrh2E= github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/cometbft/cometbft v0.38.5 h1:4lOcK5VTPrfbLOhNHmPYe6c7eDXHtBdMCQuKbAfFJdU= -github.com/cometbft/cometbft v0.38.5/go.mod h1:0tqKin+KQs8zDwzYD8rPHzSBIDNPuB4NrwwGDNb/hUg= +github.com/cometbft/cometbft v0.38.6 h1:QSgpCzrGWJ2KUq1qpw+FCfASRpE27T6LQbfEHscdyOk= +github.com/cometbft/cometbft v0.38.6/go.mod h1:8rSPxzUJYquCN8uuBgbUHOMg2KAwvr7CyUw+6ukO4nw= github.com/cometbft/cometbft-db v0.9.1 h1:MIhVX5ja5bXNHF8EYrThkG9F7r9kSfv8BX4LWaxWJ4M= github.com/cometbft/cometbft-db v0.9.1/go.mod h1:iliyWaoV0mRwBJoizElCwwRA9Tf7jZJOURcRZF9m60U= github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg= @@ -343,21 +341,21 @@ github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSV github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cosmos/btcutil v1.0.5 h1:t+ZFcX77LpKtDBhjucvnOH8C2l2ioGsBNEQ3jef8xFk= github.com/cosmos/btcutil v1.0.5/go.mod h1:IyB7iuqZMJlthe2tkIFL33xPyzbFYP0XVdS8P5lUPis= -github.com/cosmos/cosmos-db v1.0.0 h1:EVcQZ+qYag7W6uorBKFPvX6gRjw6Uq2hIh4hCWjuQ0E= -github.com/cosmos/cosmos-db v1.0.0/go.mod h1:iBvi1TtqaedwLdcrZVYRSSCb6eSy61NLj4UNmdIgs0U= -github.com/cosmos/cosmos-proto v1.0.0-beta.3 h1:VitvZ1lPORTVxkmF2fAp3IiA61xVwArQYKXTdEcpW6o= -github.com/cosmos/cosmos-proto v1.0.0-beta.3/go.mod h1:t8IASdLaAq+bbHbjq4p960BvcTqtwuAxid3b/2rOD6I= -github.com/cosmos/cosmos-sdk v0.50.3 h1:zP0AXm54ws2t2qVWvcQhEYVafhOAREU2QL0gnbwjvXw= -github.com/cosmos/cosmos-sdk v0.50.3/go.mod h1:tlrkY1sntOt1q0OX/rqF0zRJtmXNoffAS6VFTcky+w8= +github.com/cosmos/cosmos-db v1.0.2 h1:hwMjozuY1OlJs/uh6vddqnk9j7VamLv+0DBlbEXbAKs= +github.com/cosmos/cosmos-db v1.0.2/go.mod h1:Z8IXcFJ9PqKK6BIsVOB3QXtkKoqUOp1vRvPT39kOXEA= +github.com/cosmos/cosmos-proto v1.0.0-beta.4 h1:aEL7tU/rLOmxZQ9z4i7mzxcLbSCY48OdY7lIWTLG7oU= +github.com/cosmos/cosmos-proto v1.0.0-beta.4/go.mod h1:oeB+FyVzG3XrQJbJng0EnV8Vljfk9XvTIpGILNU/9Co= +github.com/cosmos/cosmos-sdk v0.50.5 h1:MOEi+DKYgW67YaPgB+Pf+nHbD3V9S/ayitRKJYLfGIA= +github.com/cosmos/cosmos-sdk v0.50.5/go.mod h1:oV/k6GJgXV9QPoM2fsYDPPsyPBgQbdotv532O6Mz1OQ= github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gogogateway v1.2.0 h1:Ae/OivNhp8DqBi/sh2A8a1D0y638GpL3tkmLQAiKxTE= github.com/cosmos/gogogateway v1.2.0/go.mod h1:iQpLkGWxYcnCdz5iAdLcRBSw3h7NXeOkZ4GUkT+tbFI= github.com/cosmos/gogoproto v1.4.2/go.mod h1:cLxOsn1ljAHSV527CHOtaIP91kK6cCrZETRBrkzItWU= -github.com/cosmos/gogoproto v1.4.11 h1:LZcMHrx4FjUgrqQSWeaGC1v/TeuVFqSLa43CC6aWR2g= -github.com/cosmos/gogoproto v1.4.11/go.mod h1:/g39Mh8m17X8Q/GDEs5zYTSNaNnInBSohtaxzQnYq1Y= -github.com/cosmos/iavl v1.0.0 h1:bw6t0Mv/mVCJvlMTOPHWLs5uUE3BRBfVWCRelOzl+so= -github.com/cosmos/iavl v1.0.0/go.mod h1:CmTGqMnRnucjxbjduneZXT+0vPgNElYvdefjX2q9tYc= +github.com/cosmos/gogoproto v1.4.12 h1:vB6Lbe/rtnYGjQuFxkPiPYiCybqFT8QvLipDZP8JpFE= +github.com/cosmos/gogoproto v1.4.12/go.mod h1:LnZob1bXRdUoqMMtwYlcR3wjiElmlC+FkjaZRv1/eLY= +github.com/cosmos/iavl v1.0.1 h1:D+mYbcRO2wptYzOM1Hxl9cpmmHU1ZEt9T2Wv5nZTeUw= +github.com/cosmos/iavl v1.0.1/go.mod h1:8xIUkgVvwvVrBu81scdPty+/Dx9GqwHnAvXz4cwF7RY= github.com/cosmos/ics23/go v0.10.0 h1:iXqLLgp2Lp+EdpIuwXTYIQU+AiHj9mOC2X9ab++bZDM= github.com/cosmos/ics23/go v0.10.0/go.mod h1:ZfJSmng/TBNTBkFemHHHj5YY7VAU/MBU980F4VU1NG0= github.com/cosmos/ledger-cosmos-go v0.13.3 h1:7ehuBGuyIytsXbd4MP43mLeoN2LTOEnk5nvue4rK+yM= @@ -392,8 +390,8 @@ github.com/distribution/reference v0.5.0 h1:/FUIFXtfc/x2gpa5/VGfiGLuOIdYa1t65IKK 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.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig1seQen0cKYlM= -github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +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/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.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -408,8 +406,8 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m 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/emicklei/dot v1.6.0 h1:vUzuoVE8ipzS7QkES4UfxdpCwdU2U97m2Pb2tQCoYRY= -github.com/emicklei/dot v1.6.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= +github.com/emicklei/dot v1.6.1 h1:ujpDlBkkwgWUY+qPId5IwapRW/xEoligRSYjioR6DFI= +github.com/emicklei/dot v1.6.1/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= 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= @@ -421,13 +419,15 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.m github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU4zdyUgIUNhlgg0A= +github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs= -github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o= -github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= @@ -439,8 +439,8 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= -github.com/getsentry/sentry-go v0.25.0 h1:q6Eo+hS+yoJlTO3uu/azhQadsD8V+jQn2D8VvX1eOyI= -github.com/getsentry/sentry-go v0.25.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= @@ -465,6 +465,11 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= @@ -487,8 +492,8 @@ github.com/gobwas/pool v0.2.1/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6Wezm github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/gobwas/ws v1.1.0 h1:7RFti/xnNkMJnrK7D1yQ/iCIB5OrrY/54/H930kIbHA= github.com/gobwas/ws v1.1.0/go.mod h1:nzvNcVha5eUziGrbxFCo6qFIojQHjJV5cLYIbezhfL0= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= +github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -539,8 +544,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/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -601,8 +606,8 @@ github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8 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/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.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/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= @@ -690,8 +695,6 @@ github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= github.com/hdevalence/ed25519consensus v0.1.0 h1:jtBwzzcHuTmFrQN6xQZn6CQEO/V9f7HsjsjeEZ6auqU= github.com/hdevalence/ed25519consensus v0.1.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= -github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= -github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/go-assert v1.1.5 h1:fjemmA7sSfYHJD7CUqs9qTwwfdNAx7/j2/ZlHXzNB3c= github.com/huandu/go-assert v1.1.5/go.mod h1:yOLvuqZwmcHIC5rIzrBhT7D3Q9c3GFnd0JrPVhn/06U= @@ -741,8 +744,8 @@ github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYs github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.15.11/go.mod h1:QPwzmACJjUTFsnSHH934V6woptycfrDDJnH7hvFVbGM= -github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.7 h1:ehO88t2UGzQK66LMdE8tibEd1ErmzZjNEqWkjLAKQQg= +github.com/klauspost/compress v1.17.7/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= 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.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= @@ -762,8 +765,8 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6 github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= 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/linxGnu/grocksdb v1.8.6 h1:O7I6SIGPrypf3f/gmrrLUBQDKfO8uOoYdWf4gLS06tc= -github.com/linxGnu/grocksdb v1.8.6/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= +github.com/linxGnu/grocksdb v1.8.12 h1:1/pCztQUOa3BX/1gR3jSZDoaKFpeHFvQ1XrqZpSvZVo= +github.com/linxGnu/grocksdb v1.8.12/go.mod h1:xZCIb5Muw+nhbDK4Y5UJuOrin5MceOuiXkVUR7vp4WY= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= @@ -786,8 +789,6 @@ github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= @@ -858,8 +859,8 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= github.com/opencontainers/image-spec v1.1.0-rc2/go.mod h1:3OVijpioIKYWTqjiG0zfF6wvoJ4fAXGbjdZuI2NgsRQ= -github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs= -github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= +github.com/opencontainers/runc v1.1.3 h1:vIXrkId+0/J2Ymu2m7VjGvbSlAId9XNRPhn2p4b+d8w= +github.com/opencontainers/runc v1.1.3/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg= 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= @@ -876,8 +877,8 @@ github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0Mw 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.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI= -github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc= +github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo= +github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230904192822-1876fd5063bc h1:8bQZVK1X6BJR/6nYUPxQEP+ReTsceJTKizeuwjWOPUA= @@ -910,16 +911,16 @@ github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1: 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/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.0 h1:k1v3CzpSRUTrKMppY35TLwPvxHqBu0bYgxZzqGIgaos= +github.com/prometheus/client_model v0.6.0/go.mod h1:NTQHnmxFpouOD0DpvP4XujX3CdOAGQPoaGhyTchlyt8= github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 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.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.47.0 h1:p5Cz0FNHo7SnWOmWmoRozVcjEp0bIVU8cV7OShpjL1k= +github.com/prometheus/common v0.47.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= 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= @@ -935,14 +936,14 @@ github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6So 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.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= -github.com/rs/zerolog v1.31.0 h1:FcTR3NnLWW+NnTwwhFWiJSZr4ECLpqCm6QsEnyvbV4A= -github.com/rs/zerolog v1.31.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= +github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0= +github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -962,6 +963,8 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf 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/skip-mev/chaintestutil v0.0.0-20240116134208-3e49bf514803 h1:VRRVYN3wsOIOqVT3e3nDh3vyUl6RvF9QwdK4BvgPP9c= +github.com/skip-mev/chaintestutil v0.0.0-20240116134208-3e49bf514803/go.mod h1:LF2koCTmygQnz11yjSfHvNP8axdyZ2lTEw0EwI+dnno= github.com/skip-mev/petri/chain/v2 v2.0.1 h1:THeyxsMqYpBpebjZIcZBC4kOjgS0e8yg1kw+UcTCYDY= github.com/skip-mev/petri/chain/v2 v2.0.1/go.mod h1:72cP8EWwNHpImg0pXa2Oxll+lRDcpFt917CfwrpE7rI= github.com/skip-mev/petri/node/v2 v2.0.1 h1:QHU3ppEFcLRi3LCSY59U4HAK1OHUXj1bCKW9rStdZ54= @@ -974,8 +977,8 @@ github.com/skip-mev/petri/util/v2 v2.0.1 h1:SKjnrK/ZjoA5V0uyHjVf4Cyw+JU1Jy0El1qy github.com/skip-mev/petri/util/v2 v2.0.1/go.mod h1:sPq+CiL0ytYfOk11j7PAIq5ZcvGhwoV8/z64LOXbeNs= github.com/skip-mev/petri/wallet/v2 v2.0.1 h1:83rvHAzy+Ci86kISZB44LuayiF00q0vbOjApDRIFQpk= github.com/skip-mev/petri/wallet/v2 v2.0.1/go.mod h1:clapxceQoHQqqZXPP6MlciTShRw5xVA5w9bWXpywcvY= -github.com/skip-mev/slinky v0.1.0 h1:74TBxjstr2AwjZWb1q3zV5wj3zSKgPzooTs/8K5EYG0= -github.com/skip-mev/slinky v0.1.0/go.mod h1:rdm36fRoCEM8x+vhyuU4hWMdLn/MHe55M8AZsIpXkqY= +github.com/skip-mev/slinky v0.3.1 h1:K/Bq8vvqSXqoSq3chaLFdIiwy9qNR3n4XakT9ur+8AM= +github.com/skip-mev/slinky v0.3.1/go.mod h1:mCicT46xX3S5JtlvxjCH2ChYL0vojKb1oc8ZXH1IcAM= 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= @@ -1010,8 +1013,8 @@ 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.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.1 h1:4VhoImhV/Bm0ToFkXFi8hXNXwpDRZ/ynw3amt82mzq0= -github.com/stretchr/objx v0.5.1/go.mod h1:/iHQpkQwBD6DLUmQ4pE+s1TXdob1mORJ4/UFdrifcy0= +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= @@ -1022,8 +1025,9 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= 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.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +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.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= @@ -1072,14 +1076,26 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0 h1:UNQQKPfTDe1J81ViolILjTKPr9WetKW6uei2hFgJmFs= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.47.0/go.mod h1:r9vWsPS/3AQItv3OSlEJ/E4mbrhUbbw18meOjArPtKQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0 h1:sv9kVfal0MK0wBMCOGr+HeJm9v803BkJxGrk2au7j08= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.47.0/go.mod h1:SK2UL73Zy1quvRPonmOmRDiWk1KBV3LyIeeIxcEApWw= +go.opentelemetry.io/otel v1.22.0 h1:xS7Ku+7yTFvDfDraDIJVpw7XPyuHlB9MCiqqX5mcJ6Y= +go.opentelemetry.io/otel v1.22.0/go.mod h1:eoV4iAi3Ea8LkAEI9+GFT44O6T/D0GWAVFyZVCC6pMI= +go.opentelemetry.io/otel/metric v1.22.0 h1:lypMQnGyJYeuYPhOM/bgjbFM6WE44W1/T45er4d8Hhg= +go.opentelemetry.io/otel/metric v1.22.0/go.mod h1:evJGjVpZv0mQ5QBRJoBF64yMuOf4xCWdXjK8pzFvliY= +go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/trace v1.22.0 h1:Hg6pPujv0XG9QaVbGOBVHunyuLcCC3jN7WEhPx83XD0= +go.opentelemetry.io/otel/trace v1.22.0/go.mod h1:RbbHXVqKES9QhzZq/fE5UnOSILqRt40a21sPw2He1xo= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= 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= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +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.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -1089,8 +1105,8 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E 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.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1102,8 +1118,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= -golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= +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/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1115,8 +1131,8 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d h1:jtJma62tbqLibJ5sFQz8bKtEM8rJBtfilJ2qTU199MI= -golang.org/x/exp v0.0.0-20231006140011-7918f672742d/go.mod h1:ldy0pHrwJyGW56pPQzzkH36rKxoZW1tw7ZJpeKx+hdo= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= 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= @@ -1143,8 +1159,8 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= 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= @@ -1204,8 +1220,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= -golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= -golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= +golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= 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= @@ -1231,8 +1247,8 @@ golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= -golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= -golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= +golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= +golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1247,8 +1263,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.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= @@ -1345,13 +1361,13 @@ golang.org/x/sys v0.0.0-20221010170243-090e33056c14/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= -golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +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/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.16.0 h1:m+B6fahuftsE9qjo0VWp2FW0mB3MTJvR0BaMQrq0pmE= -golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1434,8 +1450,8 @@ golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= -golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= +golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1494,8 +1510,8 @@ google.golang.org/api v0.96.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= -google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4= -google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= +google.golang.org/api v0.162.0 h1:Vhs54HkaEpkMBdgGdOT2P6F0csGG/vxDS0hWHJzmmps= +google.golang.org/api v0.162.0/go.mod h1:6SulDkfoBIg4NFmCuZ39XeeAgSHCPecfSUuDyYlAHs0= 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= @@ -1612,12 +1628,12 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221014213838-99cd37c6964a/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/genproto v0.0.0-20221025140454-527a21cfbd71/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3 h1:1hfbdAfFbkmpg41000wDVqr7jUpK/Yo+LPnIxxGzmkg= -google.golang.org/genproto v0.0.0-20231211222908-989df2bf70f3/go.mod h1:5RBcpGRxr25RbDzY5w+dmaqpSEvl8Gwl1x2CICf60ic= -google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0 h1:s1w3X6gQxwrLEpxnLd/qXTVLgQE2yXwaOaoa6IlY/+o= -google.golang.org/genproto/googleapis/api v0.0.0-20231212172506-995d672761c0/go.mod h1:CAny0tYF+0/9rmDB9fahA9YLzX3+AEVl1qXbv5hhj6c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0 h1:/jFB8jK5R3Sq3i/lmeZO0cATSzFfZaJq1J2Euan3XKU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231212172506-995d672761c0/go.mod h1:FUoWkonphQm3RhTS+kOEhF8h0iDpm4tdXolVCeZ9KKA= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= +google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= +google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8 h1:8eadJkXbwDEMNwcB5O0s5Y5eCfyuCLdvaiOIaGTrWmQ= +google.golang.org/genproto/googleapis/api v0.0.0-20240304212257-790db918fca8/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641 h1:DKU1r6Tj5s1vlU/moGhuGz7E3xRfwjdAfDzbsaQJtEY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240228224816-df926f6c8641/go.mod h1:UCOku4NytXMJuLQE5VuqA5lX3PcHCBo8pxNyvkf4xBs= 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= @@ -1659,8 +1675,8 @@ google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACu google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= -google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= -google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= +google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= +google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= 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= @@ -1677,8 +1693,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= -google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= 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= @@ -1729,6 +1745,6 @@ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/x/alerts/types/mocks/bank_keeper.go b/x/alerts/types/mocks/bank_keeper.go index 281aaa152..0f4a58ad4 100644 --- a/x/alerts/types/mocks/bank_keeper.go +++ b/x/alerts/types/mocks/bank_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/x/alerts/types/mocks/incentive_keeper.go b/x/alerts/types/mocks/incentive_keeper.go index eef9e50c4..5f485ad90 100644 --- a/x/alerts/types/mocks/incentive_keeper.go +++ b/x/alerts/types/mocks/incentive_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/x/alerts/types/mocks/oracle_keeper.go b/x/alerts/types/mocks/oracle_keeper.go index 859723eee..f2fdf1580 100644 --- a/x/alerts/types/mocks/oracle_keeper.go +++ b/x/alerts/types/mocks/oracle_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/x/alerts/types/mocks/staking_keeper.go b/x/alerts/types/mocks/staking_keeper.go index eeaa1946b..97dce6bfe 100644 --- a/x/alerts/types/mocks/staking_keeper.go +++ b/x/alerts/types/mocks/staking_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/x/incentives/types/examples/mocks/bank_keeper.go b/x/incentives/types/examples/mocks/bank_keeper.go index 41ff03e6d..e52a20076 100644 --- a/x/incentives/types/examples/mocks/bank_keeper.go +++ b/x/incentives/types/examples/mocks/bank_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/x/incentives/types/examples/mocks/staking_keeper.go b/x/incentives/types/examples/mocks/staking_keeper.go index ee3d40288..82a5d73e9 100644 --- a/x/incentives/types/examples/mocks/staking_keeper.go +++ b/x/incentives/types/examples/mocks/staking_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/x/marketmap/types/ticker.go b/x/marketmap/types/ticker.go index b8321606d..7c3be4c8a 100644 --- a/x/marketmap/types/ticker.go +++ b/x/marketmap/types/ticker.go @@ -57,7 +57,11 @@ func (t *Ticker) ValidateBasic() error { return fmt.Errorf("metadata json field is longer than maximum length of %d", MaxMetadataJSONFieldLength) } - return json.IsValid([]byte(t.Metadata_JSON)) + if err := json.IsValid([]byte(t.Metadata_JSON)); err != nil { + return fmt.Errorf("invalid JSON metadata; %w", err) + } + + return nil } // Equal returns true iff the Ticker is equal to the given Ticker. diff --git a/x/oracle/types/mocks/market_map_keeper.go b/x/oracle/types/mocks/market_map_keeper.go index d6e43090b..4741c64c3 100644 --- a/x/oracle/types/mocks/market_map_keeper.go +++ b/x/oracle/types/mocks/market_map_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/x/sla/types/mocks/mock_slashing_keeper.go b/x/sla/types/mocks/mock_slashing_keeper.go index cfabd3b38..7f05d974d 100644 --- a/x/sla/types/mocks/mock_slashing_keeper.go +++ b/x/sla/types/mocks/mock_slashing_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks diff --git a/x/sla/types/mocks/mock_staking_keeper.go b/x/sla/types/mocks/mock_staking_keeper.go index 1feb038be..934f0bae6 100644 --- a/x/sla/types/mocks/mock_staking_keeper.go +++ b/x/sla/types/mocks/mock_staking_keeper.go @@ -1,4 +1,4 @@ -// Code generated by mockery v2.42.1. DO NOT EDIT. +// Code generated by mockery v2.42.2. DO NOT EDIT. package mocks